/** * @param $params * @param $template * * @return string * @throws SmartyException */ function smarty_function_geoiplookup($params, $template) { $ip = $params[0]; $getflag = isset($params['flag']) ? $params['flag'] : true; $lookup = new \geocode\IPLookup($ip); if ($getflag) { $flag = 'assets/images/iso-country-flags/' . strtolower($lookup->country) . '.png'; $file = \Core\Filestore\Factory::File($flag); $cname = $lookup->getCountryName(); if ($file->exists()) { $out = '<img src="' . $file->getPreviewURL('20x20') . '" title="' . $cname . '" alt="' . $lookup->country . '"/> '; } else { $out = ''; } } else { $out = ''; } if ($lookup->province && $lookup->city) { $out .= $lookup->city . ', ' . $lookup->province; } elseif ($lookup->province) { $out .= $lookup->province; } elseif ($lookup->city) { $out .= $lookup->city; } return $out; }
/** * The constructor takes a File object, filename string, or URL string, and provides easy access for * handling operations on that file. */ public function __construct($file) { if ($file instanceof File) { $this->_file = $file; } else { // @todo Add support for URLs. $this->_file = \Core\Filestore\Factory::File($file); } }
/** * Get the image object or null * * @return Core\Filestore\File|null */ public function getImage() { if ($this->get('image')) { $f = \Core\Filestore\Factory::File($this->get('image')); return $f; } else { return null; } }
public function testFilePrivate(){ $src = new \Core\Filestore\Backends\FileLocal('core/tests/ivak_TV_Test_Screen.png'); $dst = \Core\Filestore\Factory::File('private/tests/ivak_TV_Test_Screen.png'); // Verify that this is a valid object. $this->assertInstanceOf('\Core\Filestore\File', $dst); // Make sure it's writable... just because :p $src->copyTo($dst); $this->assertTrue($dst->exists()); }
/** * Resolve a dynamic or static link with smarty. * * @todo Finish documentation of smarty_function_link * * @param array $params Associative (and/or indexed) array of smarty parameters passed in from the template * @param Smarty $smarty Parent Smarty template object * * @return string */ function smarty_function_link($params, $smarty){ $assign= (isset($params['assign']))? $params['assign'] : false; // I don't really care what the parameter's called to be honest... if(isset($params['href'])) $href = $params['href']; elseif(isset($params['link'])) $href = $params['link']; elseif(isset($params['to'])) $href = $params['to']; elseif(isset($params[0])) $href = $params[0]; else $href = '/'; $originalHref = $href; $href = \Core\resolve_link($href); if(!$href && strpos($originalHref, 'public/') === 0){ $file = \Core\Filestore\Factory::File($originalHref); if($file->exists()){ $href = $file->getURL(); } } if(isset($params['ssl'])){ // Perform SSL translation of some sort. $ssl = (isset($_SERVER['HTTPS'])); if( ($ssl && $params['ssl'] == 'auto') || $params['ssl'] == '1' || $params['ssl'] == 'true' ){ $href = str_replace('http://', 'https://', $href); } elseif(!$params['ssl']){ $href = str_replace('https://', 'http://', $href); } } if($assign){ $smarty->assign($assign, $href); } else{ return $href; } }
/** * Simple method to handle any legacy call to favicon.ico */ public function index() { $view = $this->getView(); $image = ConfigHandler::Get('/favicon/image'); $file = \Core\Filestore\Factory::File($image); $view->contenttype = 'image/png'; $view->record = false; $view->mode = View::MODE_NOOUTPUT; // Fix Bug #562, Favicon "none" option. // Do not render anything if no icon is selected. if (!$image) { return; } if (!$file->exists()) { return; } $file->displayPreview('32x32!'); }
public function fetch() { $data = []; $image = ConfigHandler::Get('/favicon/image'); if ($image) { $file = \Core\Filestore\Factory::File($image); } else { // Check the theme default. $file = \Core\Filestore\Factory::File('asset/images/favicon.png'); //return []; } if (!$file->exists()) { return []; } $data['favicon'] = '<link rel="icon" type="image/png" href="' . $file->getPreviewURL('32x32!') . '"/>'; $data['favicon-apple-touch-icon'] = '<link rel="apple-touch-icon" type="image/png" sizes="72x72" href="' . $file->getPreviewURL('72x72!') . '"/>'; $data['favicon-apple-touch-icon-2'] = '<link rel="apple-touch-icon" type="image/png" sizes="114x114" href="' . $file->getPreviewURL('114x114!') . '"/>'; $data['favicon-apple-touch-icon-retina'] = '<link rel="apple-touch-icon" sizes="512x512" type="image/png" href="' . $file->getPreviewURL('512x512!') . '"/>'; $data['favicon-windows-8'] = '<meta name="msapplication-TileImage" content="' . $file->getPreviewURL('270x270!') . '"/>'; return $data; }
/** * Save a new or existing album * * @static * @param Form $form * @return mixed */ public static function SaveAlbum(Form $form) { /** @var GalleryAlbumModel $model */ $model = $form->getModel('model'); /** @var $page PageModel */ $page = $form->getModel('page'); $page->set('fuzzy', 1); if ($page->get('rewriteurl') == '/' || $page->get('rewriteurl') == '') { Core::SetMessage('Galleries cannot be installed on the root of your site! Please change the URL to something other than "/".', 'error'); return false; } // Update the model cache data $model->set('title', $page->get('title')); //var_dump($model); die(); $model->save(); // Make sure the directory exists. $dir = \Core\Filestore\Factory::Directory($model->getFullUploadDirectory()); $dir->mkdir(); // w00t return $page->getResolvedURL(); }
public function render(){ if(!$this->get('templatename')){ throw new Exception('Unable to render pageselectinput element without templatename set!'); } // Figure out the template directory for custom pages, (if it exists) // In order to get the types, I need to sift through all the potential template directories and look for a directory // with the matching name. $tmpname = substr($this->get('templatename'), 0, -4) . '/'; $matches = array(); foreach(\Core\Templates\Template::GetPaths() as $d){ if(is_dir($d . $tmpname)){ // Yay, sift through that and get the files! $dir = \Core\Filestore\Factory::Directory($d . $tmpname); foreach($dir->ls('tpl') as $file){ // Skip directories if($file instanceof \Core\Filestore\Directory) continue; /** @var $file \Core\Filestore\File */ //$fullpath = $tmpname . $file->getBaseFilename(); $fullpath = $file->getBaseFilename(); $name = $file->getBaseFilename(); // Do some template updates and make it a little more friendlier to read. $name = ucwords(str_replace('-', ' ', substr($name, 0, -4))) . ' Template'; $matches[ $fullpath ] = $name; } } } // Are there any matches? If not just return a blank string. if(!sizeof($matches)){ return ''; } $options = array_merge(array('' => '-- Default Page Template --'), $matches); $this->set('options', $options); return parent::render(); }
/** * Get an array of alternative display templates for this instance. * * This is based on the widget's baseurl. * * @return array */ public function getAlternativeTemplateOptions(){ $parts = $this->splitParts(); // Figure out the template directory for custom pages, (if it exists) // In order to get the types, I need to sift through all the potential template directories and look for a directory // with the matching name. $tmpname = 'widgets' . strtolower('/' . substr($parts['controller'], 0, -6) . '/' . $parts['method']); $matches = []; foreach(\Core\Templates\Template::GetPaths() as $d){ if(is_dir($d . $tmpname)){ // Yay, sift through that and get the files! $dir = \Core\Filestore\Factory::Directory($d . $tmpname); foreach($dir->ls('tpl') as $file){ // Skip directories if($file instanceof \Core\Filestore\Directory) continue; /** @var $file \Core\Filestore\File */ //$fullpath = $tmpname . $file->getBaseFilename(); $name = $fullpath = $file->getBaseFilename(); // Do some template updates and make it a little more friendlier to read. $name = ucwords(str_replace('-', ' ', substr($name, 0, -4))) . ' Template'; $matches[ $fullpath ] = $name; } } } return ['' => '-- Default Template --'] + $matches; }
public static function _UploadHandler(Form $form) { $localfile = \Core\Filestore\Factory::File($form->getElement('upload')->get('value')); $localobj = $localfile->getContentsObject(); if(!$localobj instanceof Core\Filestore\Contents\ContentTGZ){ $localfile->delete(); \Core\set_message('Invalid file uploaded', 'error'); return false; } $tmpdir = $localobj->extract('tmp/installer-' . Core::RandomHex(4)); // There should now be a package.xml metafile inside that temporary directory. // Parse it to get the necessary information for this package. $metafile = \Core\Filestore\Factory::File($tmpdir->getPath() . 'package.xml'); if(!$metafile->exists()){ $localfile->delete(); $tmpdir->delete(); \Core\set_message('Invalid package, package does not contain a "package.xml" file.'); return false; } $pkg = new PackageXML($metafile->getFilename()); $key = str_replace(' ', '-', strtolower($pkg->getName())); $name = $pkg->getName(); $type = $pkg->getType(); $version = $pkg->getVersion(); // Validate the contents of the package. if(!( $type == 'component' || $type == 'theme' || $type == 'core' )){ $localfile->delete(); $tmpdir->delete(); \Core\set_message('Invalid package, package does not appear to be a valid Core package.'); return false; } // Now that the data is extracted in a temporary directory, extract every file in the destination. /** @var $datadir \Core\Filestore\Directory */ $datadir = $tmpdir->get('data/'); if(!$datadir){ \Core\set_message('Invalid package, package does not contain a "data" directory.'); return false; } if($type == 'component'){ $destdir = ROOT_PDIR . 'components/' . $key . '/'; } elseif($type == 'theme'){ $destdir = ROOT_PDIR . 'themes/' . $key . '/'; } else{ $destdir = ROOT_PDIR . '/'; } try{ // Will give me an array of Files in the data directory. $files = $datadir->ls(null, true); // Used to get the relative path for each contained file. $datalen = strlen($datadir->getPath()); foreach($files as $file){ if(!$file instanceof \Core\Filestore\Backends\FileLocal) continue; // It's a file, copy it over. // To do so, resolve the directory path inside the temp data dir. $dest = \Core\Filestore\Factory::File($destdir . substr($file->getFilename(), $datalen)); /** @var $dest \Core\Filestore\Backends\FileLocal */ $dest->copyFrom($file, true); } } catch(Exception $e){ // OH NOES! $localfile->delete(); $tmpdir->delete(); \Core\set_message($e->getMessage(), 'error'); return false; } // Cleanup everything $localfile->delete(); $tmpdir->delete(); // Clear the cache so the next pageload will pick up on the new components and goodies. \Core\Cache::Flush(); \Core\Templates\Backends\Smarty::FlushCache(); // Print a nice message to the user that it completed. \Core\set_message('Successfully installed ' . $name . ' ' . $version, 'success'); return '/updater'; }
/** * Decrypt the encrypted/signed file and return a valid File object * * @return mixed */ public function decrypt($dest = false) { if ($dest) { if (is_a($dest, 'File') || $dest instanceof Filestore\File) { // Don't need to do anything! The object either is a File // Or is an implmentation of the File interface. } else { // Well it should be damnit!.... $file = $dest; // Is the destination a directory or filename? // If it's a directory just tack on this current file's basename. if (substr($file, -1) == '/') { $file .= $this->_file->getBaseFilename(); } // Drop the .asc extension if it's there. if ($this->_file->getExtension() == 'asc') $file = substr($file, 0, -4); $dest = Filestore\Factory::File($file); } // And load up the contents! $dest->putContents($this->decrypt()); return $dest; } else { // Extract and return the file contents ob_start(); passthru('gpg --homedir "' . GPG_HOMEDIR . '" --no-permission-warning --decrypt "' . $this->_file->getLocalFilename() . '"'); $content = ob_get_contents(); ob_end_clean(); return $content; } }
} else{ CLI::PrintActionStatus('fail'); CLI::PrintError('Unable to find required component ' . $dat['name']); die(); } } else{ CLI::PrintActionStatus('ok'); CLI::PrintLine('Found ' . $dat['name'] . '-' . $compversion . ' in a local package.'); $dat['tgz'] = $dat['src'] . '/' . $dat['keyname'] . '-' . $compversion . '.tgz'; } CLI::PrintActionStart("Extracting tarball"); if(!is_dir($dat['dest'])){ $d = \Core\Filestore\Factory::Directory($dat['dest']); $d->mkdir(); } exec('tar -xzf ' . $dat['tgz'] . ' -C ' . $dat['dest'] . ' --transform "s:\./data::" ./data', $out, $result); if($result != 0){ CLI::PrintActionStatus('fail'); CLI::PrintLine($out); die(); } CLI::PrintActionStatus('ok'); CLI::PrintActionStart("Processing CHANGELOG"); if($dat['keyname'] == 'core'){ $parser = new Core\Utilities\Changelog\Parser($dat['name'], $dat['dest'] . '/core/CHANGELOG'); } else{
/** * Get all screenshots in this metafile * * @return array */ public function getScreenshots() { $s = $this->_xmlloader->getElements('//screenshots/screenshot'); if (!$s) { return []; } else { $f = \Core\Filestore\Factory::File($this->getBaseDir() . $s->getAttribute('file')); return ['file' => $f, 'title' => $s->getAttribute('title') ? $s->getAttribute('title') : $this->getName()]; } }
/** * Process an SQL file and return an array of generic dataset objects. * * <h3>Usage Examples</h3> * * * <h4>Example 1</h4> * <p>Standard Usage</p> * <code> * // Some code for example 1 * $file = ROOT_PDIR . 'components/foo/upgrades/000-do-something-awesome.sql'; * $records = mysqli_backend::ProcessSQLFile($file); * foreach($records as $rec){ * $rec->execute(); * } * </code> * * @param $file * * @throws \Exception * * @return array */ public static function ProcessSQLFile($file){ if(is_scalar($file)){ $file = Factory::File($file); } elseif(!$file instanceof File){ throw new \Exception('Please ensure that the argument for ProcessSQLFile is either a string or a valid File object!'); } $contents = $file->getContents(); $parser = new \SQL_Parser_Dataset($contents, \SQL_Parser::DIALECT_MYSQL); return $parser->parse(); }
public static function FlushCache(){ $dir = \Core\Filestore\Factory::Directory(TMP_DIR . 'smarty_templates_c'); foreach($dir->ls('php') as $file){ /** @var \Core\Filestore\File $file */ $file->delete(); } $dir = \Core\Filestore\Factory::Directory(TMP_DIR . 'smarty_cache'); foreach($dir->ls('php') as $file){ /** @var \Core\Filestore\File $file */ $file->delete(); } }
public static function _SaveEditorHandler(Form $form) { $newmodel = $form->getModel(); $file = $form->getElement('file')->get('value'); $activefile = $form->getElement('filetype')->get('value'); // The inbound file types depends on how to read the file. switch ($activefile) { case 'template': $filename = \Core\Templates\Template::ResolveFile($file); $customfilename = ROOT_PDIR . 'themes/custom/' . $file; break; case 'file': $filename = $file; // It'll get transposed. $customfilename = ROOT_PDIR . 'themes/custom/' . $file; break; default: \Core\set_message('Unsupported file type: ' . $activefile, 'error'); return false; } $customfh = \Core\Filestore\Factory::File($customfilename); if ($customfh->exists()) { // If the custom one exists... this will be the source file too! $sourcefh = $customfh; } else { $sourcefh = \Core\Filestore\Factory::File($filename); } // Check and see if they're the same, ie: no change. I don't want to create a bunch of moot revisions. if ($newmodel->get('content') == $sourcefh->getContents()) { \Core\set_message('No changes performed.', 'info'); return '/theme'; } // Before I overwrite this file, check and see if the original has been snapshot first! $c = ThemeTemplateChangeModel::Count(['filename = ' . $file]); if (!$c) { $original = new ThemeTemplateChangeModel(); $original->setFromArray(['comment' => 'Original File', 'filename' => $file, 'content' => $sourcefh->getContents(), 'content_md5' => $sourcefh->getHash(), 'updated' => $sourcefh->getMTime()]); $original->save(); } // All destination files get written to the custom directory! $customfh->putContents($newmodel->get('content')); $hash = $customfh->getHash(); /* // What happens now is based on the type of the inbound file. switch($activefile){ case 'skin': // Just replace the contents of that file. $fh->putContents($newmodel->get('content')); $hash = $fh->getHash(); break; case 'template': // This gets written into the current theme directory. $themefh = \Core\Filestore\Factory::File(ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/' . $file); $themefh->putContents($newmodel->get('content')); $hash = $themefh->getHash(); break; case 'style': case 'file': // This gets written into the current theme directory. $themefh = \Core\Filestore\Factory::File(ROOT_PDIR . 'themes/' . ConfigHandler::Get('/theme/selected') . '/' . $file); $themefh->putContents($newmodel->get('content')); $hash = $themefh->getHash(); // This is required to get assets updated to the CDN correctly. $theme = ThemeHandler::GetTheme(); $hash = $themefh->getHash(); $theme->addAssetFile(array('file' => $file, 'md5' => $hash)); $theme->save(); $theme->reinstall(); default: } */ // Make a record of this change too! $change = new ThemeTemplateChangeModel(); $change->setFromArray(['comment' => $newmodel->get('comment'), 'filename' => $file, 'content' => $newmodel->get('content'), 'content_md5' => $hash]); $change->save(); if ($activefile == 'file') { // Reinstall all assets too! foreach (Core::GetComponents() as $component) { $component->reinstall(); } // And the current theme. ThemeHandler::GetTheme(ConfigHandler::Get('/theme/selected'))->reinstall(); } \Core\set_message('Updated file successfully', 'success'); return '/theme'; }
public function testPutContents() { $contents = 'Some Example Content'; $file1 = \Core\Filestore\Factory::File('tmp/test-filelocaltest-putcontents.dat'); $this->assertTrue($file1->putContents($contents)); $this->assertTrue($file1->exists()); $this->assertEquals($contents, $file1->getContents()); $this->assertTrue($file1->delete()); }
/** * Load the data from the files */ private static function _LoadData() { // The key for this data, must be unique on the system. $cachekey = 'useragent-browsecap-data'; // The number of seconds to have Core cache the records. $cachetime = SECONDS_ONE_WEEK; $cache = Cache::Get($cachekey, $cachetime); if($cache === false){ $file = \Core\Filestore\Factory::File('tmp/php_browscap.ini'); $remote = \Core\Filestore\Factory::File(self::$_ini_url); $rcontents = $remote->getContentsObject(); if($rcontents instanceof ContentGZ){ // yay... // Core handles all the remote file caching automatically, so no worries about anything here. $rcontents->uncompress($file); } else { // Ok, it may be a standard text file then... try the conventional logic. // Doesn't exist? download it! if(!$file->exists()){ $remote->copyTo($file); } // Too old? download it! if($file->getMTime() < (\Time::GetCurrent() - self::$updateInterval)){ $remote->copyTo($file); } } $_browsers = parse_ini_file($file->getFilename(), true, INI_SCANNER_RAW); $patterns = []; $browsers = []; // Trim the header off the file. array_shift($_browsers); // Grab all the property keys for browsers. $properties = array_keys($_browsers['DefaultProperties']); array_unshift( $properties, 'browser_name', 'browser_name_regex', 'browser_name_pattern', 'Parent' ); // This creates a sorted set of user agents... used by the internal logic. $uas = array_keys($_browsers); usort( $uas, create_function(self::ORDER_FUNC_ARGS, self::ORDER_FUNC_LOGIC) ); $user_agents_keys = array_flip($uas); $properties_keys = array_flip($properties); $search = ['\*', '\?']; $replace = ['.*', '.']; foreach ($uas as $user_agent) { $browser = []; $pattern = preg_quote($user_agent, self::REGEX_DELIMITER); $patterns[] = self::REGEX_DELIMITER . '^' . str_replace($search, $replace, $pattern) . '$' . self::REGEX_DELIMITER; if (!empty($_browsers[$user_agent]['Parent'])) { $parent = $_browsers[$user_agent]['Parent']; $_browsers[$user_agent]['Parent'] = $user_agents_keys[$parent]; } foreach ($_browsers[$user_agent] as $key => $value) { //$key = $properties_keys[$key] . ".0"; $key = $properties_keys[$key]; $browser[$key] = $value; } $browsers[] = $browser; unset($browser); } unset($user_agents_keys, $properties_keys, $_browsers); Cache::Set( $cachekey, [ 'browsers' => $browsers, 'useragents' => $uas, 'patterns' => $patterns, 'properties' => $properties, ], $cachetime ); } return Cache::Get($cachekey, $cachetime); }
/** * Get the temporary local version of the file. * This is useful for doing operations such as hash and identicalto. * * @return FileLocal */ private function _getTmpLocal() { if ($this->_tmplocal === null) { // If this FTP object is simply a proxy for the local file store, I can cheat and not actually request the files over FTP. // This makes it quicker. if($this->_ftp->isLocal){ $this->_tmplocal = new FileLocal(ROOT_PDIR . $this->_filename); } else{ $filename = $this->getFilename(); $fhash = md5($filename); $this->_tmplocal = Filestore\Factory::File('tmp/remotefile-cache/' . $fhash); if(!$this->_tmplocal->exists()){ ftp_get($this->_ftp->getConn(), $this->_tmplocal->getFilename(), $filename, FTP_BINARY); } // Since I have a local copy, I might as well make sure that the cache is as updated as possible. if(!$this->_ftp->getFileHash($filename)){ $this->_ftp->setFileHash($filename, $this->_tmplocal->getHash()); } if(!$this->_ftp->getFileModified($filename)){ $this->_ftp->setFileModified($filename, ftp_mdtm($this->_ftp->getConn(), $filename)); } if(!$this->_ftp->getFileSize($filename)){ $this->_ftp->setFileSize($filename, ftp_size($this->_ftp->getConn(), $filename)); } } } return $this->_tmplocal; }
/** * Get the temporary local version of the file. * This is useful for doing operations such as hash and identicalto. * * @return FileLocal */ protected function _getTmpLocal() { if ($this->_tmplocal === null) { $f = md5($this->getFilename()); // Gotta love obviously-named flags. $needtodownload = true; $this->_tmplocal = Filestore\Factory::File('tmp/remotefile-cache/' . $f); // File exists already! Check and see if it needs to be redownloaded. if ($this->cacheable && $this->_tmplocal->exists()) { // Lookup this file in the system cache. $systemcachedata = Cache::Get('remotefile-cache-header-' . $f); if ($systemcachedata && isset($systemcachedata['headers'])) { // I can only look them up if the cache is available. // First check will be the expires header. if(isset($systemcachedata['headers']['Expires']) && strtotime($systemcachedata['headers']['Expires']) > time()){ $needtodownload = false; // And set the headers! // This is required $this->_headers = $systemcachedata['headers']; $this->_response = $systemcachedata['response']; } // Next, try ETag. elseif ($this->_getHeader('ETag') && isset($systemcachedata['headers']['ETag'])) { $needtodownload = ($this->_getHeader('ETag') != $systemcachedata['headers']['ETag']); } // No? How 'bout elseif ($this->_getHeader('Last-Modified') && isset($systemcachedata['headers']['Last-Modified'])) { $needtodownload = ($this->_getHeader('Last-Modified') != $systemcachedata['headers']['Last-Modified']); } // Still no? The default is to download it anyway. } } if ($needtodownload || !$this->cacheable) { // Make sure that the headers are updated, this is a requirement to use the 302 tag. $this->_getHeaders(); if(($this->_response == '302' || $this->_response == '301') && $this->_redirectFile !== null){ $this->_tmplocal = $this->_redirectFile->_getTmpLocal(); } else{ // BTW, use cURL. $curl = curl_init(); curl_setopt_array( $curl, array( CURLOPT_HEADER => false, CURLOPT_NOBODY => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => $this->getURL(), CURLOPT_HTTPHEADER => \Core::GetStandardHTTPHeaders(true), ) ); $result = curl_exec($curl); if($result === false){ switch(curl_errno($curl)){ case CURLE_COULDNT_CONNECT: case CURLE_COULDNT_RESOLVE_HOST: case CURLE_COULDNT_RESOLVE_PROXY: $this->_response = 404; return $this->_tmplocal; break; default: $this->_response = 500; return $this->_tmplocal; break; } } curl_close($curl); // Copy the data down to the local file. $this->_tmplocal->putContents($result); } // And remember this header data for nexttime. Cache::Set( 'remotefile-cache-header-' . $f, [ 'headers' => $this->_getHeaders(), 'response' => $this->_response, ] ); } } return $this->_tmplocal; }
private function _lookup() { // At least address or city are required. if (!($this->address1 && $this->city || $this->city || $this->postal || $this->fullAddress)) { throw new \Exception('At least the address or city are required for geocode lookups.'); } // a couple of required vars to sign the request url $private_key = \ConfigHandler::Get('/googlemaps/enterprise/privatekey'); $clientname = \ConfigHandler::Get('/googlemaps/enterprise/clientname'); $params = ['address' => null, 'sensor' => $this->sensor ? 'true' : 'false']; if ($this->address1 && $this->city) { $params['address'] = $this->address1 . ($this->city ? ', ' . $this->city : '') . ($this->state ? ', ' . $this->state : ''); } elseif ($this->postal) { $params['address'] = $this->postal; } elseif ($this->fullAddress) { $params['address'] = $this->fullAddress; } if ($this->country) { $params['region'] = $this->country; } if ($clientname) { // Only add the client parameter if it's set in the config, otherwise it's a guest connection. $params['client'] = $clientname; } // Make a request to google and update the record. // http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true_or_false $ps = []; foreach ($params as $k => $v) { $ps[] = $k . '=' . urlencode(trim($v)); } if ($private_key) { // Use the enterprise-friendly URL. // the url to sign $signurl = '/maps/api/geocode/json?' . implode('&', $ps); //zee signature! $signature = hash_hmac("sha1", $signurl, base64_decode(strtr($private_key, '-_', '+/')), true); $signature = strtr(base64_encode($signature), '+/', '-_'); //var_dump($signature); die(); $url = 'http://maps.googleapis.com/maps/api/geocode/json?' . implode('&', $ps) . '&signature=' . $signature; } else { $url = 'http://maps.googleapis.com/maps/api/geocode/json?' . implode('&', $ps); } // Make the request // Since this is making use of Core's native File system, caching of remote files is builtin for free :) $request = \Core\Filestore\Factory::File($url); $json = $request->getContents(); $contents = json_decode($json, true); $result = new GeocodeResponse($contents); return $result; }
/** * Get an associative array of all metadata associated to the requested file. * * @param string $file * * @return array * @throws \Exception */ public function getMetas($file){ $allkeys = ['filename', 'hash', 'modified', 'size']; if($this->_contents === null){ $this->_contents = []; $remotefile = $this->_dir . '.ftpmetas'; $f = md5($remotefile); $this->_local = Factory::File('tmp/remotefile-cache/' . $f); if( (!$this->_local->exists()) || ($this->_local->exists() && $this->_local->getMTime() + 1800 < DateTime::NowGMT()) ){ // Only try to open the remote file if it exists. if(ftp_size($this->_ftp->getConn(), $remotefile) != -1){ // The file doesn't exist OR the file does but it hasn't been modified in the past 30 minutes. $this->_local->putContents(''); ftp_get($this->_ftp->getConn(), $this->_local->getFilename(), $remotefile, FTP_BINARY); } } if(!$this->_local->exists()){ // The remote file doesn't exist, so nothing was downloaded. // Just return a blank array. return array_merge($allkeys, ['filename' => $file]); } // Read this CSV file into the contents array. $fh = fopen($this->_local->getFilename(), 'r'); if(!$fh){ throw new \Exception('Unable to open ' . $this->_local->getFilename() . ' for reading.'); } $line = 0; $map = []; $headers = []; do{ $data = fgetcsv($fh, 2048); // Meh. Could do this inside a standard while statement, but same diff. if($data === null) break; if($data === false) break; $line++; if($line == 1){ // This is the header. $map = $data; foreach($data as $k => $v){ $headers[$v] = $k; } foreach($allkeys as $key){ if(!isset($headers[$key])){ $map[] = $key; $headers[$key] = -1; } } } else{ $assoc = []; foreach($map as $k => $v){ $assoc[$v] = isset($data[$k]) ? $data[$k] : ''; } if(!isset($assoc['filename'])){ // Invalid CSV input. fclose($fh); return array_merge($allkeys, ['filename' => $file]); } $this->_contents[ $assoc['filename'] ] = $assoc; } } while(true); } return isset($this->_contents[$file]) ? $this->_contents[$file] : array_merge($allkeys, ['filename' => $file]); }
/** * Verify that some given data has a valid signature. * * Calls verifyFileSignature internally! * * @param string $signature * @param string $content * * @throws \Exception * * @return Signature */ public function verifyDataSignature($signature, $content){ // First, write a temporary file to contain the signature. $sig = \Core\Filestore\Factory::File('tmp/gpg-verify-' . \Core::RandomHex(6) . '.asc'); $sig->putContents($signature); // And the content $con = \Core\Filestore\Factory::File('tmp/gpg-verify-' . \Core::RandomHex(6) . '.dat'); $con->putContents($content); try{ $result = $this->verifyFileSignature($sig, $con); } catch(\Exception $e){ // Cleanup. $sig->delete(); $con->delete(); throw $e; } $sig->delete(); $con->delete(); return $result; }
/** * Get the original file associated to this image. * * This is critical because the getFile may return the *rotated* image! * * @return \Core\Filestore\File */ public function getOriginalFile() { return \Core\Filestore\Factory::File($this->get('file')); }
public static function ImportList($filename) { // Download the latest blacklist from sfs and import it into the system. // Each record will be in a format such as // "5.144.176.232","7","2012-12-11 00:08:10" // IP, number of submissions, date $remotefile = \Core\Filestore\Factory::File($filename); // Does it exist? if (!$remotefile->exists()) { echo 'Unable to read file ' . $remotefile->getFilename() . ', it does not appear to exist!'; return false; } $contents = $remotefile->getContentsObject(); // Make sure it's a zip file. If it's not, then we'll have problems. if (!$contents instanceof \Core\Filestore\Contents\ContentZIP) { echo 'File ' . $remotefile->getFilename() . ' does not appear to be a zip file, aborting extraction!'; return false; } $dest = 'tmp/sfs-blacklist/'; /** @var $extracted \Core\Filestore\Directory */ $extracted = $contents->extract($dest); /** @var $file \Core\Filestore\File */ $file = $extracted->get('listed_ip_1_all.txt'); // Do this line by line instead of reading the entire contents into memory. $fh = fopen($file->getFilename(), 'r'); if (!$fh) { echo 'Unable to open file ' . $file->getFilename() . ' for reading, aborting extraction!'; return false; } $recordscount = 0; $newcount = 0; $updatedcount = 0; $skippedcount = 0; while (!feof($fh)) { $line = fgetcsv($fh); // Don't know why..... if (!$line[0]) { continue; } ++$recordscount; // If the record count is too low to even care about... just skip it. if ($line[1] <= 2) { ++$skippedcount; continue; } $record = \sfsBlacklistModel::Construct($line[0]); $record->setFromArray(array('submissions' => $line[1], 'lastseen' => $line[2])); if (!$record->exists()) { ++$newcount; $record->save(); } elseif ($record->save()) { ++$updatedcount; } else { ++$skippedcount; } } fclose($fh); echo 'Processed ' . $recordscount . ' records from ' . $remotefile->getFilename() . ' successfully!' . "\n"; echo 'New Records: ' . $newcount . "\n"; echo 'Updated Records: ' . $updatedcount . "\n"; echo 'Skipped Records: ' . $skippedcount . "\n"; return true; }
public function now(){ $request = $this->getPageRequest(); $view = $this->getView(); if(!$request->isJSON()) return View::ERROR_BADREQUEST; $view->contenttype = View::CTYPE_JSON; $view->mode = View::MODE_AJAX; $view->record = false; $limit = $this->_getQueryLimit(); $duration = 60; // Use FindRaw because it's faster than using full Models for everything, especially when dealing with 20k + records. $listings = UserActivityModel::FindRaw('datetime >= ' . (Time::GetCurrent() - $duration), $limit, 'datetime DESC'); $data = array(); // Performance reports $data['information'] = array( 'duration' => $duration, ); $data['performance'] = array('get' => 0, 'post' => 0); $data['requests'] = array('get' => 0, 'post' => 0); $users = array(); $bots = array(); $guestname = \ConfigHandler::Get('/user/displayname/anonymous'); foreach($listings as $log){ if($log['type'] == 'GET'){ $data['performance']['get'] += $log['processing_time']; $data['requests']['get']++; } elseif($log['type'] == 'POST'){ $data['performance']['post'] += $log['processing_time']; $data['requests']['post']++; } $ua = new \Core\UserAgent($log['useragent']); if(class_exists('\\geocode\\IPLookup')){ // If the geo library is available, use that to resolve the IP to something more meaningful than just a number. $lookup = new \geocode\IPLookup($log['ip_addr']); $file = \Core\Filestore\Factory::File('assets/images/iso-country-flags/' . strtolower($lookup->country) . '.png'); if($lookup->province && $lookup->city){ $title = $lookup->city . ', ' . $lookup->province . ', ' . $lookup->getCountryName(); } elseif($lookup->province){ $title = $lookup->province . ', ' . $lookup->getCountryName(); } elseif($lookup->city){ $title = $lookup->city . ' ' . $lookup->getCountryName(); } else{ $title = $lookup->getCountryName(); } $ip = '<span title="' . $title . '">'; if($file->exists()){ $ip .= '<img src="' . $file->getPreviewURL('20x20') . '" alt="' . $lookup->country . '"/> '; } $ip .= $log['ip_addr']; $ip .= '</span>'; } else{ $ip = $log['ip_addr']; } // Bots have their own data, because, well... they're bots. // Damn bots! if($ua->isBot()){ if(!isset($bots[ $log['ip_addr'] ])){ $bots[ $log['ip_addr'] ] = array( 'ip' => $ip, 'useragent' => $log['useragent'], 'lastpage' => $log['request'], 'status' => $log['status'], //'type' => $ua->, 'browser' => $ua->getAsHTML(), 'count' => 1, ); } else{ $bots[$log['ip_addr']]['count']++; } } // The user agent information I want to know on a per-user basis, not a per-click basis. else{ if(!isset($users[ $log['session_id'] ])){ $thisuser = UserModel::Construct($log['user_id']); $users[ $log['session_id'] ] = array( 'session' => $log['session_id'], 'ip' => $ip, 'user_id' => $log['user_id'], 'username' => ($thisuser ? $thisuser->getDisplayName() : $guestname), 'useragent' => $log['useragent'], 'lastpage' => $log['request'], //'type' => $ua->type, 'browser' => $ua->getAsHTML(), 'os' => '', 'count' => 1, ); } else{ $users[$log['session_id']]['count'] ++; } } } //UserAgent::Test(); die(); if($data['requests']['get'] > 0) $data['performance']['get'] = round($data['performance']['get'] / $data['requests']['get'], 2); if($data['requests']['post'] > 0) $data['performance']['post'] = $data['performance']['post'] / $data['requests']['post']; $data['users'] = array_values($users); $data['bots'] = array_values($bots); //var_dump($data, $users, $listings); die(); $view->jsondata = $data; }
/** * Get the repository XML as a string that can be returned to the browser or cached for future use. * * @return string */ private function _getRepoXML() { $repo = new RepoXML(); $repo->setDescription(ConfigHandler::Get('/package_repository/description')); $dir = Factory::Directory(\ConfigHandler::Get('/package_repository/base_directory')); $coredir = $dir->getPath() . 'core/'; $componentdir = $dir->getPath() . 'components/'; $themedir = $dir->getPath() . 'themes/'; $tmpdir = Factory::Directory('tmp/exports/'); $gpg = new Core\GPG\GPG(); $keysfound = []; $private = ConfigHandler::Get('/package_repository/is_private') || strpos($dir->getPath(), ROOT_PDIR) !== 0; $addedpackages = 0; $failedpackages = 0; $iterator = new \Core\Filestore\DirectoryIterator($dir); // Only find signed packages. $iterator->findExtensions = ['asc']; // Recurse into sub directories $iterator->recursive = true; // No directories $iterator->findDirectories = false; // Just files $iterator->findFiles = true; // And sort them by their filename to make things easy. $iterator->sortBy('filename'); // Ensure that the necessary temp directory exists. $tmpdir->mkdir(); foreach ($iterator as $file) { /** @var \Core\Filestore\File $file */ $fullpath = $file->getFilename(); // Used in the XML file. if ($private) { $relpath = \Core\resolve_link('/packagerepository/download?file=' . substr($file->getFilename(), strlen($dir->getPath()))); } else { $relpath = $file->getFilename(ROOT_PDIR); } // Drop the .asc extension. $basename = $file->getBasename(true); // Tarball of the temporary package $tgz = Factory::File($tmpdir->getPath() . $basename); $output = []; // I need to 1) retrieve and 2) verify the key for this package. try { $signature = $gpg->verifyFileSignature($fullpath); if (!in_array($signature->keyID, $keysfound)) { $repo->addKey($signature->keyID, null, null); $keysfound[] = $signature->keyID; } } catch (\Exception $e) { trigger_error($fullpath . ' was not able to be verified as authentic, (probably because the GPG public key was not available)'); $failedpackages++; continue; } // decode and untar it in a temp directory to get the package.xml file. exec('gpg --homedir "' . GPG_HOMEDIR . '" -q -d "' . $fullpath . '" > "' . $tgz->getFilename() . '" 2>/dev/null', $output, $ret); if ($ret) { trigger_error('Decryption of file ' . $fullpath . ' failed!'); $failedpackages++; continue; } exec('tar -xzf "' . $tgz->getFilename() . '" -C "' . $tmpdir->getPath() . '" ./package.xml', $output, $ret); if ($ret) { trigger_error('Unable to extract package.xml from' . $tgz->getFilename()); unlink($tmpdir->getPath() . $basename); $failedpackages++; continue; } // Read in that package file and append it to the repo xml. $package = new PackageXML($tmpdir->getPath() . 'package.xml'); $package->getRootDOM()->setAttribute('key', $signature->keyID); $package->setFileLocation($relpath); $repo->addPackage($package); $addedpackages++; // But I can still cleanup! unlink($tmpdir->getPath() . 'package.xml'); $tgz->delete(); } return $repo->asPrettyXML(); }
$output .= $keyData['key'] . " = \"\";\n"; } $output .= "\n"; } // Now generate any dialect-specific keys. foreach($baseData['dialects'] as $dialect){ $output .= "; Dialect-specific overrides for " . $dialect . "\n[" . $dialect . "]\n"; foreach($matches as $m){ $keyData = \Core\i18n\I18NLoader::Get($m, $dialect); if($keyData['found'] && $keyData['match_key'] == $dialect){ // This specific dialect has an override. $output .= $keyData['key'] . " = \"" . str_replace('"', '\\"', $keyData['match_str']) . "\";\n"; } } $output .= "\n"; } if($arguments->getArgumentValue('dry-run')){ echo $output; } else{ // Write this output to the requested ini file! $file = \Core\Filestore\Factory::File($dir . '/i18n/' . $lang . '.ini'); $file->putContents($output); \Core\CLI\CLI::PrintSuccess('Updated ' . $file->getFilename() . ' successfully!'); } }
/** * Render markup for an image tag in smarty * * The {img} smarty function is the recommended way to load images in templates from asset or public directories. * In addition to automatically resolving URLs, it can also handle server-side resizing and a few other nifty features. * * #### Image Types & Animations * * As of Core 3.3.0, image types are preserved, so if a .jpg is requested, an image/jpeg is returned. * This changed from the previous behaviour where all images were converted to a PNG. * * Supported image types are `.jp[e]g`, `.png`, and `.gif`. * * If an animated gif is resized, the server will attempt to preserve the animation on the resized image. * This is done via imagemagick, (so that library needs to be present on the server in order for this trick to work). * * #### SEO Data * * As of Core 3.2.0, alt tags are automatically added to every image that does not have the alt attribute explicitly set. * This alt name is pulled from the filename of the image, with automatic capitalization and '_' => (space) converting. * * #### Smarty Parameters * * * assign * * string * * Set to a string to assign that variable name instead of returning the output. * * dimensions * * Provide both width and height in pixels, along with special instructions * * Structure is "widthxheight" with no spaces between the "x" and the two integers. * * Special modes available are: * * Carat "`^`" at the end of the string fits the smallest dimension instead of the largest. * * Exclamation mark "`!`" at the end forces size regardless of aspect ratio. * * Greater than "`>`" at the end will only increase image sizes. * * Less than "`<`" at the end will only decrease image sizes. * * file * * \Core\Filestore\File * * File object passed in to display * * Either "file" or "src" is required. * * height * * int * * Maximum image height (in pixels). * * If both width and height are provided, the image will be constrained to both without any distortion. * * inline * * int "1" or "0", (default "0") * * New in Core 4.2.0 * * Request that the resized image be encoded as base64 and inserted inline in the markdown instead of returned as the URL. * * placeholder * * string * * placeholder image if the requested image is blank or not found. Useful for optional fields that should still display something. * * Current values: "building", "generic", "person", "person-tall", "person-wide", "photo" * * src * * string * * Source filename to display. This can start with "assets" for an asset, or "public" for a public file. * * Either "file" or "src" is required. * * width * * int * * Maximum image width (in pixels). * * If both width and height are provided, the image will be constrained to both without any distortion. * * Any other parameter is transparently sent to the resulting `<img/>` tag. * * * #### Example Usage * * <pre> * {img src="public/gallery/photo123.png" width="123" height="123" placeholder="photo" alt="My photo 123"} * </pre> * * @param array $params Associative (and/or indexed) array of smarty parameters passed in from the template * @param Smarty $smarty Parent Smarty template object * * @return string * @throws SmartyException */ function smarty_function_img($params, $smarty){ // Key/value array of attributes for the resulting HTML. $attributes = array(); if(isset($params['file'])){ $f = $params['file']; if(!$f instanceof \Core\Filestore\File){ throw new SmartyException('{img} tag expects a \Core\Filestore\File object for the "file" parameter.'); } unset($params['file']); } elseif(isset($params['src'])){ $f = \Core\Filestore\Factory::File($params['src']); unset($params['src']); } else{ $f = null; } // Some optional parameters, (and their defaults) $assign = $width = $height = $dimensions = $inline = false; $placeholder = $previewfile = null; if(isset($params['assign'])){ $assign = $params['assign']; unset($params['assign']); } if(isset($params['width'])){ $width = $params['width']; unset($params['width']); } if(isset($params['height'])){ $height = $params['height']; unset($params['height']); } if(isset($params['dimensions'])){ $dimensions = $params['dimensions']; $width = preg_replace('#[^0-9]?([0-9]*)x.*#', '$1', $dimensions); $height = preg_replace('#.*x([0-9]*)[^0-9]?#', '$1', $dimensions); unset($params['dimensions']); } if(isset($params['placeholder'])){ $placeholder = $params['placeholder']; unset($params['placeholder']); } if(isset($params['inline'])){ $inline = ($params['inline'] == '1'); unset($params['inline']); } if($dimensions){ // Passing in dimensions raw will allow the user more control over the size of the images. $d = $dimensions; } else{ // If one is provided but not the other, just make them the same. if($width && !$height) $height = $width; if($height && !$width) $width = $height; $d = ($width && $height) ? $width . 'x' . $height : false; } // If the file doesn't exist and a placeholder was provided, use the appropriate placeholder image! if(!($f && $f->exists() && $f->isImage()) && $placeholder){ // Try that! $f = \Core\Filestore\Factory::File('assets/images/placeholders/' . $placeholder . '.png'); } if(!$f){ throw new SmartyException('{img} tag requires either "src", "file", or a "placeholder" parameter.'); } // Do the rest of the attributes that the user sent in (if there are any) foreach($params as $k => $v){ $attributes[$k] = $v; } if($f instanceof Core\Filestore\Backends\FileRemote){ // Erm... Give the original URL with the dimension requests. $attributes['src'] = $f->getURL(); if($width) $attributes['width'] = $width; if($height) $attributes['height'] = $height; } else{ // Try to lookup the preview file. // if it exists, then YAY... I can return that direct resource. // otherwise, I should check and see if the file is larger than a set filesize. // if it is, then I want to return a link to a controller to render that file instead of rendering the file from within the {img} tag. // // This is useful because any logic contained within this block will halt page execution! // To improve the perception of performance, that can be offloaded to the browser requesting the <img/> contents. $previewfile = $d ? $f->getQuickPreviewFile($d) : $f; if(!$previewfile){ $attributes['src'] = '#'; $attributes['title'] = 'No preview files available!'; } elseif($inline && $f->getFilesize() < 1048576*4){ // Overwrite the src attribute with the base64 contents. // This can only happen after the preview file exists! if(!$previewfile->exists()){ // Since quick ran, ensure that it's actually resized! $previewfile = $f->getPreviewFile($d); } $attributes['src'] = 'data:' . $previewfile->getMimetype() . ';base64,' . base64_encode($previewfile->getContents()); } elseif(!$previewfile->exists()){ // Ok, it doesn't exist... return a link to the controller to render this file. $attributes['src'] = \Core\resolve_link('/file/preview') . '?f=' . $f->getFilenameHash() . '&d=' . $d; } else{ $attributes['src'] = $previewfile->getURL(); } } // All images need alt data! if(!isset($attributes['alt'])){ $attributes['alt'] = $f->getTitle(); } // Merge them back together in one string. $html = '<img'; foreach($attributes as $k => $v) $html .= " $k=\"$v\""; $html .= '/>'; // If the extended metadata was requested... look that up too! if(isset($params['includemeta']) && $params['includemeta']){ $metahelper = new \Core\Filestore\FileMetaHelper($f); $metacontent = $metahelper->getAsHTML(); if($metacontent){ $html = '<div class="image-metadata-wrapper">' . $html . $metacontent . '</div>'; } } return $assign ? $smarty->assign($assign, $html) : $html; }