* @copyright Copyright (c) 2022, Dale Davies * @license MIT */ namespace Jump; use stdClass; /** * Parse the data required to represent a site and provide method for generating * and/or retrieving the site's icon. */ class Site { public string $id; public string $name; public bool $nofollow; public ?string $iconname; public string $url; public array $tags = ['home']; /** * Parse the data required to represent a site and provide method for generating * and/or retrieving the site's icon. * * @param Config $config A Jump Config() object. * @param array $sitearray Array of options for this site from sites.json. * @param array $defaults Array of default values for this site to use, defined in sites.json. */ public function __construct(private Config $config, private Cache $cache, array $sitearray, private array $defaults) { if (!isset($sitearray['name'], $sitearray['url'])) { throw new \Exception('The array passed to Site() must contain the keys "name" and "url"!'); } $this->id = 'site-'.md5($sitearray['url']); $this->name = $sitearray['name']; $this->url = $sitearray['url']; $this->nofollow = isset($sitearray['nofollow']) ? $sitearray['nofollow'] : (isset($this->defaults['nofollow']) ? $this->defaults['nofollow'] : false); $this->newtab = isset($sitearray['newtab']) ? $sitearray['newtab'] : (isset($this->defaults['newtab']) ? $this->defaults['newtab'] : false); $this->iconname = $sitearray['icon'] ?? null; $this->tags = $sitearray['tags'] ?? $this->tags; $this->description = isset($sitearray['description']) ? $sitearray['description'] : $sitearray['name']; $this->status = $sitearray['status'] ?? null; } /** * Return an object containing mimetype and raw image data, or a site's * favicon if an icon is not provided in sites.json. * * @return object Containing mimetype and raw image data. */ public function get_favicon_image_data(): object { return $this->cache->load(cachename: 'sites/favicons', key: $this->id, callback: function() { // Use the applications own default icon unless one is supplied via the sites.json file. $defaulticon = $this->config->get('defaulticonpath'); if (isset($this->defaults['icon'])) { $defaulticon = $this->config->get('sitesdir').'/icons/'.$this->defaults['icon']; } // Did we have a supplied icon or are we going to try retrieving the favicon? if ($this->iconname === null) { // Go get the favicon, if there isnt one then use the default icon. $favicon = new \Favicon\Favicon(); $rawimage = $favicon->get($this->url, \Favicon\FaviconDLType::RAW_IMAGE); } else { // If the icon name has a file extension the n try to retrieve it locally, otherwise // see if we can get it from Dashboard Icons. if (pathinfo($this->iconname, PATHINFO_EXTENSION)) { $file = $this->config->get('sitesdir').'/icons/'.$this->iconname; $errormessage = 'Icon file not found... '.$file; } else { $file = 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/svg/'.$this->iconname.'.svg'; $errormessage = 'Dashboard icon does not exist... '.$this->iconname; } $rawimage = @file_get_contents($file); if (!$rawimage) { error_log($errormessage); } } // If we didnt manage to get any icon data from any of the above methods then return // the default icon. if (!$rawimage) { $rawimage = file_get_contents($defaulticon); } $imagedata = new stdClass(); $imagedata->mimetype = (new \finfo(FILEINFO_MIME_TYPE))->buffer($rawimage); $imagedata->data = $rawimage; return $imagedata; }); } /** * Return a data uri or a site's favicon if an icon is not provided. * * @return string Base 64 encoded datauri for the icon image. */ public function get_favicon_datauri(): string { $imagedata = $this->get_favicon_image_data(); return 'data:'.$imagedata->mimetype.';base64,'.base64_encode($imagedata->data); } /** * Get the online status of this site. * * @return string The site status. */ public function get_status(): string { $cache = new Cache($this->config); return (new Status($cache, $this))->get_status(); } }