示例#1
0
		'file'  => '',
		'name'  => SITENAME,
		'sname' =>  preg_replace('/[^a-z0-9-\.\+]*/i', '', str_replace(' ', '-', SITENAME)),
		'xml'   => null,
	];
}
else{
	echo "Found the following bundles:" . NL;
	foreach($bundles as $b){
		echo $b['name'] . ' (' . $b['file'] . ')' . NL;
	}
}
sleep(1);

// Prompt the user with what version the new bundles will be.
$version = Core::GetComponent('core')->getVersion();
$version = CLI::PromptUser('Please set the bundled version or', 'text', $version);



foreach($bundles as $b){
	/** @var XMLLoader|null $xml */
	$xml = $b['xml'];
	$destdir = $dir . '/' . $b['sname'];

	// Check the dest directory for current versions.
	if(!is_dir($destdir)) mkdir($destdir);
	$desttgz = $b['sname'] . '-' . $version;
	if(!is_dir($destdir . '/' . $desttgz)) mkdir($destdir . '/' . $desttgz);

	// Get a list of packages to export.
 public function analytics()
 {
     $request = $this->getPageRequest();
     $view = $this->getView();
     $manager = \Core\user()->checkAccess('p:/package_repository/view_analytics');
     if (!$manager) {
         return View::ERROR_ACCESSDENIED;
     }
     // Retrieve a list of connections to this repo for both downloading and checks!
     $where = new \Core\Datamodel\DatasetWhereClause();
     $where->addWhereSub('OR', ['baseurl = /packagerepository', 'baseurl = /packagerepository/download']);
     // Default to a 3-month window for now just to have a relatively useful sample of data.
     // This will be expanded to include a filter at some point in time.
     $window = new \Core\Date\DateTime();
     $window->modify('-3 months');
     $window = $window->format('U');
     // Generate a boilerplate dataset for the all-history view.
     // This is required because the graphing software expects all data to be in the same columns,
     // and these columns are simply indexed arrays.
     // As we're pulling the data potentially out-of-order and across different versions,
     // this array will provide a consistent scaffold for unset versions.
     $allboilerplate = [];
     // Series Boilerplate
     $allmonths = [];
     // Labels
     // This goes back 12 months.
     $date = new \Core\Date\DateTime();
     $date->modify('-11 months');
     for ($i = 1; $i <= 12; $i++) {
         $allboilerplate[$date->format('Ym')] = null;
         $allmonths[] = $date->format('M');
         $date->nextMonth();
     }
     $raw = UserActivityModel::FindRaw($where);
     // Will contain a list of useragents along with the count of how many access.
     $useragents = [];
     // Will contain how many times a given IP has requested the site.
     // This is for a metric that currently is not enabled.
     $ipaddresses = [];
     // A rich list of hosts along with the latest version, the IP connecting from, and the date of the last check.
     $hosts = [];
     // All series for the bar graph at the top of the page, Keyed by version and contains the total number of hits.
     $allseries = [];
     $allseries['Total'] = ['class' => 'series-other', 'name' => 'Total', 'title' => 'Total', 'useragent' => '', 'values' => $allboilerplate];
     // Used so I can compare the version of the connecting useragent against the current version of Core.
     // This of course does noothing to ensure that this site is updated, but it at least should give some perspective.
     $currentVersion = Core::VersionSplit(Core::GetComponent('core')->getVersion());
     foreach ($raw as $dat) {
         if (strpos($dat['useragent'], '(http://corepl.us)') !== false) {
             /** @var string $ua ex: "Core Plus 1.2.3" */
             $ua = str_replace(' (http://corepl.us)', '', $dat['useragent']);
             /** @var string $version Just the version, ex: "1.2.3" */
             $version = str_replace('Core Plus ', '', $ua);
             /** @var string $referrer Original Site/Server, ex: "http://corepl.us" */
             $referrer = $dat['referrer'] ? $dat['referrer'] : $dat['ip_addr'];
             // The set of logic to compare the current version of Core against the version connecting.
             // This is used primarily to set a class name onto the graphs so that they can be coloured specifically.
             $v = Core::VersionSplit($version);
             // These two values are used in the historical map, (as revision may be a bit useless at this scale).
             $briefVersion = $v['major'] . '.' . $v['minor'] . '.x';
             $briefUA = 'Core Plus ' . $briefVersion;
             if ($v['major'] == $currentVersion['major'] && $v['minor'] == $currentVersion['minor']) {
                 // Check is same version as current (or newer), blue!
                 $class = 'series-current';
             } elseif ($v['major'] + 2 <= $currentVersion['major']) {
                 // Check is at least 2 major versions out of date, red.
                 $class = 'series-outdated-2';
             } elseif ($v['major'] + 1 <= $currentVersion['major']) {
                 // Check is at least 1 major version out of date, green.
                 $class = 'series-outdated-1';
             } else {
                 // Same major version, close enough.
                 $class = 'series-outdated-0';
             }
             $month = date('Ym', $dat['datetime']);
         } else {
             $ua = 'Other';
             $briefUA = 'Other';
             $version = null;
             $briefVersion = null;
             $referrer = null;
             $class = 'series-other';
             $month = null;
         }
         // All Data!
         if ($month && array_key_exists($month, $allboilerplate)) {
             if (!isset($allseries[$briefUA])) {
                 $allseries[$briefUA] = ['class' => $class, 'name' => $briefVersion, 'title' => $briefUA, 'useragent' => $briefUA, 'values' => $allboilerplate];
             }
             $allseries[$briefUA]['values'][$month]++;
             //$allseries['Total']['values'][$month]++;
         }
         // Is this data new enough to display on the graph?
         // This is required because the "all" graph at the top needs all-time, (or at least the past 12 months).
         if ($dat['datetime'] >= $window) {
             // USER AGENT DATA
             if (!isset($useragents[$ua])) {
                 $useragents[$ua] = ['value' => 0, 'class' => $class, 'name' => $version, 'title' => $ua, 'useragent' => $ua];
             }
             $useragents[$ua]['value']++;
             // IP ADDRESS DATA
             if (!isset($ipaddresses[$dat['ip_addr']])) {
                 $ipaddresses[$dat['ip_addr']] = ['ip_addr' => $dat['ip_addr'], 'count' => 0];
             }
             $ipaddresses[$dat['ip_addr']]['count']++;
             // HOSTS DATA
             if ($version && $referrer) {
                 $k = $referrer . '-' . $dat['ip_addr'];
                 if (!isset($hosts[$k])) {
                     $hosts[$k] = ['servername' => $referrer, 'ip_addr' => $dat['ip_addr'], 'version' => '0.0', 'datetime' => 1];
                 }
                 if (Core::VersionCompare($hosts[$k]['version'], $version, 'lt')) {
                     $hosts[$k]['version'] = $version;
                 }
                 if ($hosts[$k]['datetime'] < $dat['datetime']) {
                     $hosts[$k]['datetime'] = $dat['datetime'];
                 }
             }
         }
     }
     ksort($useragents);
     ksort($hosts, SORT_NATURAL);
     ksort($allseries, SORT_NATURAL);
     ksort($ipaddresses, SORT_NATURAL);
     // Update the title of the values now that the totals have been created.
     // Also, take this opportunity to set the chart data as necessary, (as its format will be slightly different).
     $chart = ['versions' => ['labels' => [], 'series' => []], 'all' => ['labels' => array_values($allmonths), 'series' => []], 'ips' => []];
     foreach ($useragents as &$dat) {
         $dat['title'] .= ' (' . $dat['value'] . ' Total Hits)';
         $chart['versions']['labels'][] = $dat['name'];
         $chart['versions']['series'][] = ['value' => $dat['value'], 'className' => $dat['class'], 'name' => $dat['name'], 'title' => $dat['title']];
     }
     foreach ($allseries as &$dat) {
         $data = [];
         foreach ($dat['values'] as $v) {
             $data[] = ['value' => $v, 'title' => $dat['title'] . ' (' . $v . ' Monthly Hits)'];
             //$data[] = $v;
         }
         $chart['all']['series'][] = ['data' => $data, 'className' => $dat['class'], 'name' => $dat['name'], 'title' => $dat['title']];
     }
     // Convert these to JSON data!
     $chart['versions'] = json_encode($chart['versions']);
     $chart['all'] = json_encode($chart['all']);
     //$chart['ips'] = json_encode($chart['ips']);
     $view->title = 't:STRING_PACKAGE_REPOSITORY_ANALYTICS';
     $view->assign('chart', $chart);
     $view->assign('raw', $raw);
     $view->assign('ip_addresses', $ipaddresses);
     $view->assign('useragents', $useragents);
     $view->assign('hosts', $hosts);
     //var_dump($chart, $useragents, $ipaddresses, $ipversion, $raw); die();
 }
示例#3
0
	/**
	 * Get the mailer responsible for sending this email.
	 *
	 * @return PHPMailer
	 */
	public function getMailer()	{
		if (!$this->_mailer) {
			$this->_mailer = new PHPMailer(true);

			// Load in some default options for this email based on the configuration options.
			$this->_mailer->From = ConfigHandler::Get('/core/email/from');
			if (!$this->_mailer->From) $this->_mailer->From = 'website@' . $_SERVER['HTTP_HOST'];
			$this->_mailer->Sender = $this->_mailer->From;

			$this->_mailer->FromName = ConfigHandler::Get('/core/email/from_name');
			$this->_mailer->Mailer   = ConfigHandler::Get('/core/email/mailer');
			$this->_mailer->Sendmail = ConfigHandler::Get('/core/email/sendmail_path');
			if ($this->_mailer->Mailer == 'smtp') {
				$this->_mailer->Host       = ConfigHandler::Get('/core/email/smtp_host');
				$this->_mailer->Port       = ConfigHandler::Get('/core/email/smtp_port');
				
				switch(ConfigHandler::Get('/core/email/smtp_auth')){
					case 'LOGIN':
					case 'PLAIN':
						$this->_mailer->AuthType = ConfigHandler::Get('/core/email/smtp_auth'); 
						$this->_mailer->Username = ConfigHandler::Get('/core/email/smtp_user');
						$this->_mailer->Password = ConfigHandler::Get('/core/email/smtp_password');
						$this->_mailer->SMTPAuth = true;
						break;
					case 'NTLM':
						$this->_mailer->AuthType = ConfigHandler::Get('/core/email/smtp_auth');
						$this->_mailer->Username = ConfigHandler::Get('/core/email/smtp_user');
						$this->_mailer->Password = ConfigHandler::Get('/core/email/smtp_password');
						$this->_mailer->Realm    = ConfigHandler::Get('/core/email/smtp_domain');
						$this->_mailer->SMTPAuth = true;
						break;
					case 'NONE':
						$this->_mailer->SMTPAuth = false;
						break;
				}
				
				$this->_mailer->SMTPSecure =
					(ConfigHandler::Get('/core/email/smtp_security') == 'none') ?
					'' : ConfigHandler::Get('/core/email/smtp_security');
			}

			// Tack on some anti-abuse and meta headers.
			// These don't actually serve an explict function, but are added because.
			$this->_mailer->AddCustomHeader('X-AntiAbuse: This header was added to track abuse, please include it with any abuse report');
			if (\Core\user()->exists()) {
				$this->_mailer->AddCustomHeader('X-AntiAbuse: User_id - ' . \Core\user()->get('id'));
				$this->_mailer->AddCustomHeader('X-AntiAbuse: User_name - ' . \Core\user()->getDisplayName());
			}

			$this->_mailer->AddCustomHeader('X-AntiAbuse: Original Domain - ' . SERVERNAME);
			$this->_mailer->AddCustomHeader('X-AntiAbuse: Sitename - ' . SITENAME);
			$this->_mailer->AddCustomHeader('MimeOLE: Core Plus');
			$this->_mailer->AddCustomHeader('X-Content-Encoded-By: Core Plus ' . Core::GetComponent()->getVersion());
			$this->_mailer->XMailer = 'Core Plus ' . Core::GetComponent()->getVersion() . ' (http://corepl.us)';
		}

		return $this->_mailer;
	}
示例#4
0
	public static function GetVersion() {
		return Core::GetComponent()->getVersionInstalled();
	}
示例#5
0
	public function fetch(){

		$generator = 'Core Plus';
		// Hide version numbers when not in development!
		if(DEVELOPMENT_MODE) $generator .= ' ' . Core::GetComponent()->getVersion();

		return array(
			'generator' => '<meta name="generator" content="' . $generator . '"/>'
		);
	}
	/**
	 * Check if this package is already installed and current (at least as new version installed)
	 *
	 * @return boolean
	 */
	public function isCurrent() {
		switch($this->getType()){
			case 'core':
			case 'component':
				$c = Core::GetComponent($this->getName());
				if (!$c) return false; // Not installed?  Not current.
				return version_compare($c->getVersion(), $this->getVersion(), 'ge');
			case 'theme':
				$t = ThemeHandler::GetTheme($this->getName());
				if (!$t) return false; // Not installed?  Not current.
				return version_compare($t->getVersion(), $this->getVersion(), 'ge');
		}
	}
示例#7
0
	/**
	 * Render this view and send all appropriate headers to the browser, (if applicable)
	 *
	 * @return void
	 */
	public function render() {

		// Before I go about rendering anything, enable UTF-8 to ensure proper i18n!
		if ($this->contenttype && $this->contenttype == View::CTYPE_HTML) {
			View::AddMeta('http-equiv="Content-Type" content="text/html;charset=UTF-8"');
		}

		$data = $this->fetch();

		// Be sure to send the content type and status to the browser, (if it's a page)
		if (
			!headers_sent() &&
			($this->mode == View::MODE_PAGE || $this->mode == View::MODE_PAGEORAJAX || $this->mode == View::MODE_AJAX || $this->mode == View::MODE_NOOUTPUT || $this->mode == View::MODE_EMAILORPRINT)
		) {
			switch ($this->error) {
				case View::ERROR_NOERROR:
					header('Status: 200 OK', true, $this->error);
					break;
				case View::ERROR_BADREQUEST:
					header('Status: 400 Bad Request', true, $this->error);
					break;
				case View::ERROR_UNAUTHORIZED:
					header('Status: 401 Unauthorized', true, $this->error);
					break;
				case View::ERROR_PAYMENTREQUIRED:
					header('Status: 402 Payment Required', true, $this->error);
					break;
				case View::ERROR_ACCESSDENIED:
					header('Status: 403 Forbidden', true, $this->error);
					break;
				case View::ERROR_NOTFOUND:
					header('Status: 404 Not Found', true, $this->error);
					break;
				case View::ERROR_METHODNOTALLOWED:
					header('Status: 405 Method Not Allowed', true, $this->error);
					break;
				case View::ERROR_NOTACCEPTABLE:
					header('Status: 406 Not Acceptable', true, $this->error);
					break;
				case View::ERROR_PROXYAUTHENTICATIONREQUIRED:
					header('Status: 407 Proxy Authentication Required', true, $this->error);
					break;
				case View::ERROR_REQUESTTIMEOUT:
					header('Status: 408 Request Time-out', true, $this->error);
					break;
				case View::ERROR_CONFLICT:
					header('Status: 409 Conflict', true, $this->error);
					break;
				case View::ERROR_GONE:
					header('Status: 410 Gone', true, $this->error);
					break;
				case View::ERROR_LENGTHREQUIRED:
					header('Status: 411 Length Required', true, $this->error);
					break;
				case View::ERROR_PRECONDITIONFAILED:
					header('Status: 412 Precondition Failed', true, $this->error);
					break;
				case View::ERROR_ENTITYTOOLARGE:
					header('Status: 413 Request Entity Too Large', true, $this->error);
					break;
				case View::ERROR_URITOOLARGE:
					header('Status: 414 Request-URI Too Large', true, $this->error);
					break;
				case View::ERROR_UNSUPPORTEDMEDIATYPE:
					header('Status: 415 Unsupported Media Type', true, $this->error);
					break;
				case View::ERROR_RANGENOTSATISFIABLE:
					header('Status: 416 Requested range not satisfiable', true, $this->error);
					break;
				case View::ERROR_EXPECTATIONFAILED:
					header('Status: 417 Expectation Failed', true, $this->error);
					break;
				case View::ERROR_SERVERERROR:
					header('Status: 500 Internal Server Error', true, $this->error);
					break;
				default:
					header('Status: 500 Internal Server Error', true, $this->error);
					break; // I don't know WTF happened...
			}

			if ($this->contenttype) {
				if ($this->contenttype == View::CTYPE_HTML) header('Content-Type: text/html; charset=UTF-8');
				else header('Content-Type: ' . $this->contenttype);
			}
			//mb_internal_encoding('utf-8');

			header('X-Content-Encoded-By: Core Plus' . (DEVELOPMENT_MODE ? ' ' . Core::GetComponent()->getVersion() : ''));
			if(\ConfigHandler::Get('/core/security/x-frame-options')){
				header('X-Frame-Options: ' . \ConfigHandler::Get('/core/security/x-frame-options'));
			}

			if(\ConfigHandler::Get('/core/security/csp-frame-ancestors')){
				header('Content-Security-Policy: frame-ancestors \'self\' ' . \ConfigHandler::Get('/core/security/content-security-policy'));
			}

			if($this->updated !== null){
				header('Last-Modified: ' . Time::FormatGMT($this->updated, Time::TIMEZONE_USER, Time::FORMAT_RFC2822));
				//header('Last-Modified: ' . Time::FormatGMT($this->updated, Time::TIMEZONE_USER, Time::FORMAT_ISO8601));
			}

			// Are there any custom headers to send also?
			foreach($this->headers as $k => $v){
				header($k . ': ' . $v);
			}
		}

		// No SSL, skip all this!
		if(SSL_MODE != SSL_MODE_DISABLED){
			// If SSL is required by the controller and it's available, redirect there!
			if($this->ssl && !SSL){
				header('Location: ' . ROOT_URL_SSL . substr(REL_REQUEST_PATH, 1));
				die('This page requires SSL, if it does not redirect you automatically, please <a href="' . ROOT_URL_SSL . substr(REL_REQUEST_PATH, 1) . '">Click Here</a>.');
			}
			// If SSL is set to be ondemand and the page does not have it set but it's enabled, redirect to the non-SSL version.
			elseif(!$this->ssl && SSL && SSL_MODE == SSL_MODE_ONDEMAND){
				header('Location: ' . ROOT_URL_NOSSL . substr(REL_REQUEST_PATH, 1));
				die('This page does not require SSL, if it does not redirect you automatically, please <a href="' . ROOT_URL_NOSSL . substr(REL_REQUEST_PATH, 1) . '">Click Here</a>.');
			}
			// Else, SSL_MODE_ALLOWED doesn't care if SSL is enabled or not!
		}

		//echo mb_convert_encoding($data, 'UTF-8', 'auto');
		//echo mb_convert_encoding($data, 'HTML-ENTITIES', 'auto');
		echo $data;
	}
示例#8
0
 /**
  * Save or get the package XML for this theme.  This is useful for the
  * packager
  *
  * @param boolean $minified
  * @param string  $filename
  */
 public function savePackageXML($minified = true, $filename = false)
 {
     // Instantiate a new XML Loader object and get it ready to use.
     $dom = new \XMLLoader();
     $dom->setRootName('package');
     $dom->load();
     // Populate the root attributes for this theme package.
     $dom->getRootDOM()->setAttribute('type', 'theme');
     $dom->getRootDOM()->setAttribute('name', $this->getName());
     $dom->getRootDOM()->setAttribute('version', $this->getVersion());
     // Declare the packager
     $dom->createElement('packager[version="' . \Core::GetComponent()->getVersion() . '"]');
     /* // Themes don't have any provide directives.
     		// Copy over any provide directives.
     		foreach ($this->_xmlloader->getRootDOM()->getElementsByTagName('provides') as $u) {
     			$newu = $dom->getDOM()->importNode($u);
     			$dom->getRootDOM()->appendChild($newu);
     		}
     		$dom->getElement('/provides[type="component"][name="' . strtolower($this->getName()) . '"][version="' . $this->getVersion() . '"]');
     		*/
     /* // Themes don't have any requrie directives.
     		// Copy over any requires directives.
     		foreach ($this->_xmlloader->getRootDOM()->getElementsByTagName('requires') as $u) {
     			$newu = $dom->getDOM()->importNode($u);
     			$dom->getRootDOM()->appendChild($newu);
     		}
     		*/
     // Copy over any upgrade directives.
     // This one can be useful for an existing installation to see if this
     // package can provide a valid upgrade path.
     foreach ($this->_xmlloader->getRootDOM()->getElementsByTagName('upgrade') as $u) {
         $newu = $dom->getDOM()->importNode($u);
         $dom->getRootDOM()->appendChild($newu);
     }
     // Tack on description
     $desc = $this->_xmlloader->getElement('/description', false);
     if ($desc) {
         $newd = $dom->getDOM()->importNode($desc);
         $newd->nodeValue = $desc->nodeValue;
         $dom->getRootDOM()->appendChild($newd);
     }
     $out = $minified ? $dom->asMinifiedXML() : $dom->asPrettyXML();
     if ($filename) {
         file_put_contents($filename, $out);
     } else {
         return $out;
     }
 }
	/**
	 * Dispatch an event, optionally passing 1 or more parameters.
	 *
	 * @param string $hookName The name of the hook to dispatch
	 * @param mixed  $args
	 *
	 * @return mixed
	 */
	public static function DispatchHook($hookName, $args = null) {
		// Prevent any hooks from being dispatched until Core is ready!
		if(!Core::GetComponent()) return null;

		$hookName = strtolower($hookName); // Case insensitive will prevent errors later on.
		Core\Utilities\Logger\write_debug('Dispatching hook ' . $hookName);
		//echo "Calling hook $hookName<br>";
		//var_dump(HookHandler::$RegisteredHooks[$hookName]);
		if (!isset(HookHandler::$RegisteredHooks[$hookName])) {
			trigger_error('Tried to dispatch an undefined hook ' . $hookName, E_USER_NOTICE);
			return null;
		}

		\Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Dispatching hook ' . $hookName);

		$args = func_get_args();
		// Drop off the hook name from the arguments.
		array_shift($args);

		$hook   = HookHandler::$RegisteredHooks[$hookName];
		$result = call_user_func_array(array(&$hook, 'dispatch'), $args);

		Core\Utilities\Logger\write_debug('Dispatched hook ' . $hookName);
		\Core\Utilities\Profiler\Profiler::GetDefaultProfiler()->record('Dispatched hook ' . $hookName);
		return $result;
	}
示例#10
0
		'component' => $core,
		'dir' => ROOT_PDIR . 'core/',
	];
	unset($core);


	// Load in all components currently on the system
	// Open the "component" directory and look for anything with a valid component.xml file.
	$dir = ROOT_PDIR . 'components';
	$dh = opendir($dir);
	while(($file = readdir($dh)) !== false){
		if($file{0} == '.') continue;
		if(!is_dir($dir . '/' . $file)) continue;
		if(!is_readable($dir . '/' . $file . '/' . 'component.xml')) continue;

		$c = Core::GetComponent($file);

		// Is this not valid?
		if(!$c){
			CLI::PrintLine('Skipping invalid component ' . $file);
			continue;
		}

		// What's this file's version?
		$xml = new XMLLoader();
		$xml->setRootName('component');
		if(!$xml->loadFromFile($dir .  '/' . $file . '/component.xml')){
			CLI::PrintLine('Skipping component ' . $file . ', unable to load XML file');
			continue;
		}
	public static function PerformInstall($type, $name, $version, $dryrun = false, $verbose = false){

		if($verbose){
			// These are needed to force the output to be sent immediately.
			while ( @ob_end_flush() ); // even if there is no nested output buffer
			if(function_exists('apache_setenv')){
				// This function doesn't exist in CGI mode :/
				apache_setenv('no-gzip', '1');
			}
			ini_set('output_buffering','on');
			ini_set('zlib.output_compression', 0);
			ob_implicit_flush();

			// Give some basic styles for this output.
			echo '<html>
	<head>
	<!-- Yes, the following is 1024 spaces.  This is because some browsers have a 1Kb buffer before they start rendering text -->
	' . str_repeat(" ", 1024) . '
		<style>
			body {
				background: none repeat scroll 0 0 black;
				color: #22EE33;
				font-family: monospace;
			}
		</style>
	</head>
	<body>';
		}

		$timer = microtime(true);
		// Give this script a few more seconds to run.
		set_time_limit(max(90, ini_get('max_execution_time')));

		// This will get a list of all available updates and their sources :)
		if($verbose) self::_PrintHeader('Retrieving Updates');
		$updates = UpdaterHelper::GetUpdates();
		if($verbose){
			self::_PrintInfo('Found ' . $updates['sitecount'] . ' repository site(s)!', $timer);
			self::_PrintInfo('Found ' . $updates['pkgcount'] . ' packages!', $timer);
		}

		// A list of changes that are to be applied, (mainly for the dry run).
		$changes = array();

		// Target in on the specific object we're installing.  Useful for a shortcut.
		switch($type){
			case 'core':
				$initialtarget = &$updates['core'];
				break;
			case 'components':
				$initialtarget = &$updates['components'][$name];
				break;
			case 'themes':
				$initialtarget = &$updates['themes'][$name];
				break;
			default:
				return [
					'status' => 0,
					'message' => '[' . $type . '] is not a valid installation type!',
				];
		}

		// This is a special case for testing the installer UI.
		$test = ($type == 'core' && $version == '99.1337~(test)');

		if($test && $verbose){
			self::_PrintHeader('Performing a test installation!');
		}

		if($test){
			if($verbose){
				self::_PrintInfo('Sleeping for a few seconds... because servers are always slow when you don\'t want them to be!', $timer);
			}
			sleep(4);

			// Also overwrite some of the target's information.
			$repo = UpdateSiteModel::Find(null, 1);
			$initialtarget['source'] = 'repo-' . $repo->get('id');
			$initialtarget['location'] = 'http://corepl.us/api/2_4/tests/updater-test.tgz.asc';
			$initialtarget['destdir'] = ROOT_PDIR;
			$initialtarget['key'] = 'B2BEDCCB';
			$initialtarget['status'] = 'update';

			//if($verbose){
			//	echo '[DEBUG]' . $nl;
			//	var_dump($initialtarget);
			//}
		}

		// Make sure the name and version exist in the updates list.
		// In theory, the latest version of core is the only one displayed.
		if(!$test && $initialtarget['version'] != $version){
			return [
				'status' => 0,
				'message' => $initialtarget['typetitle'] . ' does not have the requested version available.',
				'debug' => [
					'versionrequested' => $version,
					'versionfound' => $initialtarget['version'],
				],
			];
		}

		// A queue of components to check.
		$pendingqueue = array($initialtarget);
		// A queue of components that will be installed that have satisfied dependencies.
		$checkedqueue = array();

		// This will assemble the list of required installs in the correct order.
		// If a given dependency can't be met, the installation will be aborted.
		if($verbose){
			self::_PrintHeader('CHECKING DEPENDENCIES');
		}
		do{
			$lastsizeofqueue = sizeof($pendingqueue);

			foreach($pendingqueue as $k => $c){
				$good = true;

				if(isset($c['requires'])){
					if($verbose){
						self::_PrintInfo('Checking dependencies for ' . $c['typetitle'], $timer);
					}

					foreach($c['requires'] as $r){

						// Sometimes there will be blank requirements in the metafile.
						if(!$r['name']) continue;

						$result = UpdaterHelper::CheckRequirement($r, $checkedqueue, $updates);

						if($result === false){
							// Dependency not met
							return [
								'status' => 0,
								'message' => $c['typetitle'] . ' requires ' . $r['name'] . ' ' . $r['version']
							];
						}
						elseif($result === true){
							// Dependency met via either installed components or new components
							// yay
							if($verbose){
								self::_PrintInfo('Dependency [' . $r['name'] . ' ' . $r['version'] . '] met with already-installed packages.', $timer);
							}
						}
						else{
							if($verbose){
								self::_PrintInfo('Additional package [' . $result['typetitle'] . '] required to meet dependency [' . $r['name'] . ' ' . $r['version'] . '], adding to queue and retrying!', $timer);
							}
							// It's an array of requirements that are needed to satisfy this installation.
							$pendingqueue = array_merge(array($result), $pendingqueue);
							$good = false;
						}
					}
				}
				else{
					if($verbose){
						self::_PrintInfo('Skipping dependency check for ' . $c['typetitle'] . ', no requirements present', $timer);
					}

					// The require key isn't present... OK!
					// This happens with themes, as they do not have any dependency logic.
				}

				if($good === true){
					$checkedqueue[] = $c;
					$changes[] = (($c['status'] == 'update') ? 'Update' : 'Install') .
						' ' . $c['typetitle'] . ' ' . $c['version'];
					unset($pendingqueue[$k]);
				}
			}
		}
		while(sizeof($pendingqueue) && sizeof($pendingqueue) != $lastsizeofqueue);

		// Do validation checks on all these changes.  I need to make sure I have the GPG key for each one.
		// This is done here to save having to download the files from the remote server first.
		foreach($checkedqueue as $target){
			// It'll be validated prior to installation anyway.
			if(!$target['key']) continue;

			$output = array();
			exec('gpg --homedir "' . GPG_HOMEDIR . '" --list-public-keys "' . $target['key'] . '"', $output, $result);
			if($result > 0){
				// Key validation failed!
				if($verbose){
					echo implode("<br/>\n", $output);
				}
				return [
					'status' => 0,
					'message' => $c['typetitle'] . ' failed GPG verification! Is the key ' . $target['key'] . ' installed?'
				];
			}
		}


		// Check that the queued packages have not been locally modified if installed.
		if($verbose){
			self::_PrintHeader('Checking for local modifications');
		}
		foreach($checkedqueue as $target){
			if($target['status'] == 'update'){
				switch($target['type']){
					case 'core':
						$c = Core::GetComponent('core');
						break;
					case 'components':
						$c = Core::GetComponent($target['name']);
						break;
					case 'themes':
						$c = null;
						break;
				}

				if($c){
					// Are there changes?
					if(sizeof($c->getChangedAssets())){
						foreach($c->getChangedAssets() as $change){
							$changes[] = 'Overwrite locally-modified asset ' . $change;
						}
					}
					if(sizeof($c->getChangedFiles())){
						foreach($c->getChangedFiles() as $change){
							$changes[] = 'Overwrite locally-modified file ' . $change;
						}
					}
					if(sizeof($c->getChangedTemplates())){
						foreach($c->getChangedTemplates() as $change){
							$changes[] = 'Overwrite locally-modified template ' . $change;
						}
					}
				}
			}
		}


		// If dry run is enabled, stop here.
		// After this stage, dragons be let loose from thar cages.
		if($dryrun){
			return [
				'status' => 1,
				'message' => 'All dependencies are met, ok to install',
				'changes' => $changes,
			];
		}


		// Reset changes, in this case it'll be what was installed.
		$changes = array();

		// By now, $checkedqueue will contain all the pending changes, theoretically with
		// the initially requested package at the end of the list.
		foreach($checkedqueue as $target){

			if($verbose){
				self::_PrintHeader('PERFORMING INSTALL (' . strtoupper($target['typetitle']) . ')');
			}

			// This package is already installed and up to date.
			if($target['source'] == 'installed'){
				return [
					'status' => 0,
					'message' => $target['typetitle'] . ' is already installed and at the newest version.',
				];
			}
			// If this package is coming from a repo, install it from that repo.
			elseif(strpos($target['source'], 'repo-') !== false){
				/** @var $repo UpdateSiteModel */
				$repo = new UpdateSiteModel(substr($target['source'], 5));
				if($verbose){
					self::_PrintInfo('Using repository ' . $repo->get('url') . ' for installation source', $timer);
				}

				// Setup the remote file that will be used to download from.
				$file = new \Core\Filestore\Backends\FileRemote($target['location']);
				$file->username = $repo->get('username');
				$file->password = $repo->get('password');

				// The initial HEAD request pulls the metadata for the file, and sees if it exists.
				if($verbose){
					self::_PrintInfo('Performing HEAD lookup on ' . $file->getFilename(), $timer);
				}
				if(!$file->exists()){
					return [
						'status' => 0,
						'message' => $target['location'] . ' does not seem to exist!'
					];
				}
				if($verbose){
					self::_PrintInfo('Found a(n) ' . $file->getMimetype() . ' file that returned a ' . $file->getStatus() . ' status.', $timer);
				}

				// Get file contents will download the file.
				if($verbose){
					self::_PrintInfo('Downloading ' . $file->getFilename(), $timer);
				}
				$downloadtimer = microtime(true);
				$obj = $file->getContentsObject();
				// Getting the object simply sets it up, it doesn't download the contents yet.
				$obj->getContents();
				// Now it has :p
				// How long did it take?
				if($verbose){
					self::_PrintInfo('Downloaded ' . $file->getFilesize(true) . ' in ' . (round(microtime(true) - $downloadtimer, 2) . ' seconds'), $timer);
				}

				if(!($obj instanceof \Core\Filestore\Contents\ContentASC)){
					return [
						'status' => 0,
						'message' => $target['location'] . ' does not appear to be a valid GPG signed archive'
					];
				}

				if(!$obj->verify()){
					// Maybe it can at least get the key....
					if($key = $obj->getKey()){
						return [
							'status' => 0,
							'message' => 'Unable to locate public key for ' . $key . '.  Is it installed?'
						];
					}
					return [
						'status' => 0,
						'message' => 'Invalid GPG signature for ' . $target['typetitle'],
					];
				}

				// The object's key must also match what's in the repo.
				if($obj->getKey() != $target['key']){
					return [
						'status' => 0,
						'message' => '!!!WARNING!!!, Key for ' . $target['typetitle'] . ' is valid, but does not match what was expected form the repository data!  This could be a major risk!',
						'debug' => [
							'detectedkey' => $obj->getKey(),
							'expectedkey' => $target['key'],
						],
					];
				}
				if($verbose){
					self::_PrintInfo('Found key ' . $target['key'] . ' for package maintainer, appears to be valid.', $timer);
					exec('gpg --homedir "' . GPG_HOMEDIR . '" --list-public-keys "' . $target['key'] . '"', $output, $result);
					foreach($output as $line){
						if(trim($line)) self::_PrintInfo(htmlentities($line), $timer);
					}
				}

				if($verbose) self::_PrintInfo('Checking write permissions', $timer);
				$dir = \Core\directory($target['destdir']);
				if(!$dir->isWritable()){
					return [
						'status' => 0,
						'message' => $target['destdir'] . ' is not writable!'
					];
				}
				if($verbose) self::_PrintInfo('OK!', $timer);


				// Decrypt the signed file.
				if($verbose) self::_PrintInfo('Decrypting signed file', $timer);

				if(version_compare(Core::GetComponent('core')->getVersionInstalled(), '4.1.1', '<=') && $file->getBaseFilename() == 'download'){
					// HACK < 4.1.2
					// Retrieve the filename from the last part of the URL.
					// This is required because the URL may be /download?file=component/blah.tgz.asc
					$f = substr($file->getFilename(), strrpos($file->getFilename(), '/'), -4);
					/** @var $localfile \Core\Filestore\File */
					$localfile = $obj->decrypt('tmp/updater/' . $f);
				}
				else{
					/** @var $localfile \Core\Filestore\File */
					$localfile = $obj->decrypt('tmp/updater/');
				}

				/** @var $localobj \Core\Filestore\Contents\ContentTGZ */
				$localobj = $localfile->getContentsObject();
				if($verbose) self::_PrintInfo('OK!', $timer);

				// This tarball will be extracted to a temporary directory, then copied from there.
				if($verbose){
					self::_PrintInfo('Extracting tarball ' . $localfile->getFilename(), $timer);
				}
				$tmpdir = $localobj->extract('tmp/installer-' . Core::RandomHex(4));

				// 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){
					return [
						'status' => 0,
						'message' => 'Invalid package, ' . $target['typetitle'] . ', does not contain a "data" directory.'
					];
				}
				if($verbose) self::_PrintInfo('OK!', $timer);


				if($verbose){
					self::_PrintInfo('Installing files into ' . $target['destdir'], $timer);
				}

				// 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($target['destdir'] . substr($file->getFilename(), $datalen));
					/** @var $dest \Core\Filestore\Backends\FileLocal */
					if($verbose){
						self::_PrintInfo('...' . substr($dest->getFilename(''), 0, 67), $timer);
					}
					$dest->copyFrom($file, true);
				}
				if($verbose) self::_PrintInfo('OK!', $timer);


				// Cleanup the temp directory
				if($verbose){
					self::_PrintInfo('Cleaning up temporary directory', $timer);
				}
				$tmpdir->remove();
				if($verbose) self::_PrintInfo('OK!', $timer);

				$changes[] = 'Installed ' . $target['typetitle'] . ' ' . $target['version'];
			}
		}

		// Clear the cache so the next pageload will pick up on the new components and goodies.
		\Core\Cache::Flush();
		\Core\Templates\Backends\Smarty::FlushCache();

		// Yup, that's it.
		// Just extract the files and Core will autoinstall/autoupgrade everything on the next page view.


		// yay...
		return [
			'status' => 1,
			'message' => 'Performed all operations successfully!',
			'changes' => $changes,
		];
	}
 public function __construct()
 {
     // Load in the settings from Core.
     $this->width = ConfigHandler::Get('/captcha/width');
     $this->height = ConfigHandler::Get('/captcha/height');
     $this->minWordLength = ConfigHandler::Get('/captcha/minlength');
     $this->maxWordLength = ConfigHandler::Get('/captcha/maxlength');
     $this->lineWidth = ConfigHandler::Get('/captcha/linethrough');
     $this->Yperiod = ConfigHandler::Get('/captcha/yperiod');
     $this->Yamplitude = ConfigHandler::Get('/captcha/yamplitude');
     $this->Xperiod = ConfigHandler::Get('/captcha/xperiod');
     $this->Xamplitude = ConfigHandler::Get('/captcha/xamplitude');
     $this->maxRotation = ConfigHandler::Get('/captcha/maxrotation');
     $this->blur = ConfigHandler::Get('/captcha/blur');
     // Ensure it knows where to look for the "resources"...
     $this->resourcesPath = Core::GetComponent('coolphpcaptcha')->getBaseDir() . "libs/cool-php-captcha/resources";
 }
示例#13
0
	public function runRequirementChecks(){
		$requires = $this->getRequires();
		$results = [];
		foreach ($requires as $r) {
			$check = [
				'require' => $r,
				'result' => [
					'passed' => false,
					'available' => null,
					'message' => null,
				],
			];
			
			switch ($r['type']) {
				case 'component':
					if (!Core::IsComponentAvailable($r['name'])) {
						// Component is not available.
						$check['result']['message'] = $check['result']['message'] = 'Missing component ' . $r['name'];
					}
					elseif (!Core::IsComponentAvailable($r['name'], $r['version'], $r['operation'])) {
						$check['result']['available'] = Core::GetComponent($r['name'])->getVersionInstalled();
						$check['result']['message'] = 'Requires component ' . $r['vstring'] . ',  ' . $check['available'] . ' available.';
					}
					else{
						$check['result']['passed'] = true;
						$check['result']['available'] = Core::GetComponent($r['name'])->getVersionInstalled();
						$check['result']['message'] = 'Component ' . $r['vstring'] . ' is available';
					}

					$results[] = $check;
					break;
				
				case 'define':
					// Ensure that whatever define the script is expecting is there... this is useful for the EXEC_MODE define.
					if (!defined($r['name'])) {
						$check['result']['message'] = $check['result']['message'] = 'Missing define ' . $r['name'];
					}
					elseif ($r['value'] != null && constant($r['name']) != $r['value']) {
						// Also if they opted to include a value... check that too.
						$check['result']['message'] = $check['result']['message'] = 'Incorrect define ' . $r['name'] . ', expected value of: ' . $r['value'];
					}
					else{
						$check['result']['passed'] = true;
						$check['result']['available'] = true;
						$check['result']['message'] = 'Define ' . $r['name'] . ' is set and correct';
					}

					$results[] = $check;
					break;

				case 'function':
					// Requires a specific function to exist.  This is most common with built-in PHP functions,
					// such as gd, ldap, or imap support.
					if(!function_exists($r['name'])){
						$check['result']['message'] = $check['result']['message'] = 'Missing function ' . $r['name'];
					}
					else{
						$check['result']['passed'] = true;
						$check['result']['available'] = true;
						$check['result']['message'] = 'Function ' . $r['name'] . ' is available';
					}

					$results[] = $check;
					break;

				case 'jslibrary':
					if (!Core::IsJSLibraryAvailable($r['name'])) {
						// The library is not even available!
						$check['result']['message'] = 'Missing JSlibrary ' . $r['name'];
					}
					else{
						$check['result']['passed'] = true;
						$check['result']['available'] = true;
						$check['result']['message'] = 'JSLibrary ' . $r['name'] . ' is available';
					}

					$results[] = $check;
					break;
				
				case 'library':
					if (!Core::IsLibraryAvailable($r['name'])) {
						// The library is not even available!
						$check['result']['message'] = 'Missing library ' . $r['name'];
					}
					elseif (!Core::IsLibraryAvailable($r['name'], $r['version'], $r['operation'])) {
						// The library is available, but is out of date.
						$check['result']['available'] = Core::GetLibraryVersion($r['name']);
						$check['result']['message'] = 'Requires library ' . $r['vstring'] . ',  ' . $check['available'] . ' available.';
					}
					else{
						$check['result']['passed'] = true;
						$check['result']['available'] = Core::GetLibraryVersion($r['name']);
						$check['result']['message'] = 'Library ' . $r['vstring'] . ' is available';
					}
					
					$results[] = $check;
					break;
				
				case 'phpextension':
					$v = phpversion($r['name']);
					$l = extension_loaded($r['name']);
					if($l === false){
						$check['result']['message'] = 'Missing PHP Extension ' . $r['name'];
					}
					elseif($r['version'] && !version_compare($v, $r['version'], $r['operation'])){
						$check['result']['available'] = $v;
						$check['result']['message'] = 'Requires PHP Extension ' . $r['vstring'] . ',  ' . $check['available'] . ' available.';
					}
					else{
						$check['result']['passed'] = true;
						$check['result']['available'] = $v;
						$check['result']['message'] = 'PHP Extension ' . $r['vstring'] . ' is available';
					}

					$results[] = $check;
					break;
			}
		}
		
		return $results;
	}
	/**
	 * Page that is called to enable a given component.
	 *
	 * Performs all the necessary checks before enable, ie: dependencies from other components.
	 */
	public function component_enable() {
		$view = $this->getView();
		$req = $this->getPageRequest();

		// This is a json-only page.
		$view->contenttype = View::CTYPE_JSON;

		// This is a post-only page!
		/*if(!$req->isPost()){
			$view->error = View::ERROR_BADREQUEST;
			return;
		}*/

		$name    = strtolower($req->getParameter(0));
		$dryrun  = $req->getParameter('dryrun');
		$c = Core::GetComponent($name);

		if(!$c){
			$view->error = View::ERROR_NOTFOUND;
			return;
		}

		if($c instanceof Component){
			$view->error = View::ERROR_SERVERERROR;
			$view->jsondata = array('message' => 'Requested component is not a valid 2.1 version component, please upgrade ' . $name);
			return;
		}

		// Create a reverse map of what components are the basis of which components, this will make it easier
		// to do the necessary mapping.
		$provides = array('library' => array(), 'component' => array());
		foreach(Core::GetComponents() as $ccheck){
			// I only want to look at enabled components.
			if(!$ccheck->isEnabled()) continue;

			foreach($ccheck->getProvides() as $p){
				$provides[$p['type']][$p['name']] = $p['version'];
			}
		}

		// And check this component's requirements.
		$requires = $c->getRequires();
		foreach($requires as $r){
			if(!isset($provides[$r['type']][$r['name']])){
				$view->jsondata = array('message' => 'Unable to locate requirement ' . $r['type'] . ' ' . $r['name']);
				return;
			}

			$op = ($r['operation']) ? $r['operation'] : 'ge';

			if(!Core::VersionCompare($provides[$r['type']][$r['name']], $r['version'], $op)){
				$view->jsondata = array('message' => 'Dependency version for ' . $r['type'] . ' ' . $r['name'] . ' ' . $op . ' ' . $r['version'] . ' not met');
				return;
			}
		}

		if(!$dryrun){
			// I want to record a list of actual changes performed.
			$changes = array();

			$changes[] = 'Enabling component ' . $c->getName();
			$change = $c->enable();
			if(is_array($change)) $changes = array_merge($changes, $change);

			$logmsg = implode("\n", $changes);
			SystemLogModel::LogSecurityEvent(
				'/updater/component/enabled',
				$logmsg
			);
		}

		$view->jsondata = array('changes' => array($name), 'dryrun' => $dryrun);
	}
示例#15
0
	private function _setupComponent(){
		$this->_xmlFile = \ComponentFactory::ResolveNameToFile($this->_keyname);
		if(!$this->_xmlFile){
			throw new \Exception('XML file for requested component not found. [' . $this->_keyname . ']');
		}

		// Resolve it to the full path
		$this->_xmlFile = ROOT_PDIR . $this->_xmlFile;

		$this->_base = new DirectoryLocal(dirname($this->_xmlFile));
		$this->_iterator = new DirectoryIterator($this->_base);
		$baseDir = $this->_base->getPath();

		// Get the XMLLoader object for this file.  This will allow me to have more fine-tune control over the file.
		$this->_xmlLoader = new \XMLLoader();
		$this->_xmlLoader->setRootName('component');
		if(!$this->_xmlLoader->loadFromFile($this->_xmlFile)){
			throw new \Exception('Unable to load XML file ' . $this->_xmlFile);
		}


		$this->_iterator->findDirectories = false;
		$this->_iterator->recursive = true;
		$this->_iterator->ignores = [
			'component.xml',
			'dev/',
			'tests/',
		];

		// @todo Should I support ignored files in the component.xml file?
		// advantage, developers can have tools in their directories that are not meant to be packaged.
		// disadvantage, currently no component other than core requires this.....
		/*$list = $this->getElements('/ignorefiles/file');
		foreach($list as $el){
			$it->addIgnores($this->getBaseDir() . $el->getAttribute('filename'));
		}*/

		// Not a 2.1 component version?... well it needs to be!
		// This actually needs to work with a variety of versions.
		$componentapiversion = $this->_xmlLoader->getDOM()->doctype->systemId;
		switch($componentapiversion){
			case 'http://corepl.us/api/2_1/component.dtd':
			case 'http://corepl.us/api/2_4/component.dtd':
				// Now I can load the component itself, now that I know that the metafile is a 2.1 compatible version.
				$comp = \Core::GetComponent($this->_keyname);

				// Because the editor may request a component by key name, translate that to the pretty name.
				$this->_name = $comp->getName();

				//$comp = new \Component_2_1($this->_xmlFile);
				//$comp->load();
				break;
			default:
				throw new \Exception('Unsupported component version, please ensure that your doctype systemid is correct.');
		}

		$this->_licenses = [];
		foreach($this->_xmlLoader->getElements('//component/licenses/license') as $el){
			/** @var \DOMElement $el */
			$url = @$el->getAttribute('url');
			$this->_licenses[] = [
				'title' => $el->nodeValue,
				'url' => $url
			];
		}

		$this->_authors = [];
		foreach($this->_xmlLoader->getElements('//component/authors/author') as $el){
			$this->_authors[] = [
				'name' => $el->getAttribute('name'),
				'email' => @$el->getAttribute('email'),
			];
		}

		$this->_changelog = new Changelog\Parser($this->_name, $baseDir . 'CHANGELOG');

		$this->_gitPaths = [
			$baseDir,
		];
	}
示例#16
0
// Resolve onlyComponent and onlyTheme to their appropriate theme, when applicable.
if($onlyComponent){
	if(Core::GetComponent($onlyComponent) === null){
		// Run through and try to find it by keyname or regular name.
		foreach(Core::GetComponents() as $c){
			/** @var Component_2_1 $c */
			if($c->getKeyName() == $onlyComponent || $c->getName() == $onlyComponent){
				$onlyComponent = $c->getKeyName();
				break;
			}
		}
		unset($c);
	}

	if(Core::GetComponent($onlyComponent) === null){
		\Core\CLI\CLI::PrintError('Unable to locate component ' . $onlyComponent);
		exit;
	}
}

if($onlyTheme){
	if(ThemeHandler::GetTheme($onlyTheme) === false){
		// Run through and try to find it by keyname or regular name.
		foreach(ThemeHandler::GetAllThemes() as $t){
			/** @var \Theme\Theme $t */
			if($t->getKeyName() == $onlyTheme || $t->getName() == $onlyTheme){
				$onlyTheme = $c->getKeyName();
				break;
			}
		}
示例#17
0
	/**
	 * Display a preview of this file to the browser.  Must be an image.
	 *
	 * @param string|int $dimensions A string of the dimensions to create the image at, widthxheight.
	 *                               Also supports the previous version of simply "dimension", as an int.
	 * @param boolean    $includeHeader Include the correct mimetype header or no.
	 */
	public function displayPreview($dimensions = "300x300", $includeHeader = true) {

		$preview = $this->getPreviewFile($dimensions);

		//var_dump($preview, $this); die(';)');
		if ($includeHeader){
			header('Content-Disposition: filename="' . $this->getBaseFilename(true) . '-' . $dimensions . '.' . $this->getExtension() . '"');
			header('Content-Type: ' . $this->getMimetype());
			header('Content-Length: ' . $preview->getFilesize());
			header('X-Alternative-Location: ' . $preview->getURL());
			header('X-Content-Encoded-By: Core Plus ' . (DEVELOPMENT_MODE ? \Core::GetComponent()->getVersion() : ''));
		}
		echo $preview->getContents();
		return;
	}
示例#18
0
}
*/
if($component){
	$dir       = ROOT_PDIR . 'components/' . $component;
	$configKey = $component;
	$comp      = Core::GetComponent($component);
}
elseif($theme){
	$dir       = ROOT_PDIR . 'themes/' . $theme;
	$configKey = 'theme/' . $theme;
	$comp      = null;
}
elseif($core){
	$dir       = ROOT_PDIR . 'core/';
	$configKey = 'core';
	$comp      = Core::GetComponent('core');
}
else{
	$dir       = null;
	$configKey = null;
	$comp      = null;
}

if(!is_dir($dir)){
	$arguments->printError('Requested directory does not exist, ' . $dir);
	$arguments->printUsage();
	exit;
}

// I need to get the list of only PHP, TPL, and XML files.
exec("find " . escapeshellarg($dir) . " -type f -regex '.*\\.\\(php\\|tpl\\|xml\\)' -exec egrep -R 'STRING_|MESSAGE_|FORMAT_' {} \\;", $output);
示例#19
0
/**
 * Handle an error and report it to the Core system log.
 *
 * @param      $errno
 * @param      $errstr
 * @param      $errfile
 * @param      $errline
 * @param null $errcontext
 */
function error_handler($errno, $errstr, $errfile, $errline, $errcontext = null){
	$type       = null;
	$fatal      = false;
	$code       = null;
	$class      = '';
	// The exception to this is when error_reporting is explictly set to 0.
	// This happens when a function is called with the "@" error suppressor.
	// In this event, I still want to log the error, but simply do not display it on the screen.
	// Damn f*****g "@" operator.....
	$suppressed = (error_reporting() === 0);

	switch($errno){
		case E_ERROR:
		case E_USER_ERROR:
			$fatal = true;
			$type  = 'error';
			$class = 'error';
			$code  = 'PHP Error';
			break;
		case E_WARNING:
		case E_USER_WARNING:
			$type = 'error';
			$class = 'warning';
			$code = 'PHP Warning';
			break;
		case E_NOTICE:
		case E_USER_NOTICE:
			$type = 'info';
			$class = 'info';
			$code = 'PHP Notice';
			break;
		case E_DEPRECATED:
		case E_USER_DEPRECATED:
			$type = 'info';
			$class = 'deprecated';
			$code = 'PHP Deprecated Notice';
			break;
		case E_STRICT:
			$type = 'info';
			$class = 'warning';
			$code = 'PHP Strict Warning';
			$suppressed = true;
			break;
		default:
			$type = 'info';
			$class = 'unknown';
			$code = 'Unknown PHP Error [' . $errno . ']';
			break;
	}

	if($suppressed){
		// Ignore suppressed errors when on production.
		// This is required because PHP < 7.0 has some functions that can only be called with the '@' operator.
		// Such as LDAP binding or many things in Smarty.
		if(!DEVELOPMENT_MODE){
			return;	
		}
		$code .= ' @SUPPRESSED';
	}

	// All errors/warnings/notices get logged!
	if($errfile && strpos($errfile, ROOT_PDIR) === 0){
		$details = '[src: ' . '/' . substr($errfile, strlen(ROOT_PDIR)) . ':' . $errline . '] ';
	}
	elseif($errfile){
		$details = '[src: ' . $errfile . ':' . $errline . '] ';
	}
	else{
		$details = '';
	}

	try{
		if(!\Core::GetComponent()){
			// SQUAK!  Core isn't even loaded yet!
			return;
		}

		// Allow external systems to hook into this event.
		\HookHandler::DispatchHook('/core/error_handler', $code, $errstr);

		$log = \SystemLogModel::Factory();
		$log->setFromArray([
			'type'    => $type,
			'code'    => $code,
			'message' => $details . $errstr
		]);
		$log->save();
	}
	catch(\Exception $e){
		// meh, try a traditional log.
		try{
			if(class_exists('Core\\Utilities\\Logger\\LogFile')){
				$log = new LogFile($type);
				$log->write($details . $errstr, $code);
			}
			else{
				error_log($details . $errstr);
			}
		}
		catch(\Exception $e){
			// Really meh now!
		}
	}

	// Display all errors when in development mode.
	if(DEVELOPMENT_MODE && !$suppressed){
		// The correct way to handle output is via EXEC_MODE.
		// HOWEVER, since the unit tests emulate a WEB mode so that the scripts behave as they would in the web browser,
		// this is not a reliable test here.
		if(isset($_SERVER['TERM']) || isset($_SERVER['SHELL'])){
			print_error_as_text($class, $code, $errstr);
		}
		elseif(EXEC_MODE == 'WEB'){
			print_error_as_html($class, $code, $errstr);
		}
		else{
			print_error_as_text($class, $code, $errstr);
		}
	}

	// If it's a fatal error and it's not in development mode, simply display a friendly error page instead.
	if($fatal){
		if(EXEC_MODE == 'WEB'){
			require(ROOT_PDIR . 'core/templates/halt_pages/fatal_error.inc.html');
		}
		exit();
	}
}