コード例 #1
0
ファイル: Theme.php プロジェクト: nicholasryan/CorePlus
 /**
  * Copy in all the assets for this theme into the assets location.
  *
  * Returns false if nothing changed, else will return an array of all the changes that occured.
  *
  * @param bool $install   Set to false to uninstall the assets instead of installing.
  * @param int  $verbosity 0 for standard output, 1 for real-time, 2 for real-time verbose output.
  *
  * @return false | array
  * @throws \InstallerException
  */
 public function _parseAssets($install = true, $verbosity = 0)
 {
     $assetbase = \Core\Filestore\get_asset_path();
     $coretheme = \ConfigHandler::Get('/theme/selected');
     // WHY is core theme set to blank?!?
     // Damn installer...
     // this happens in the installer.
     if ($coretheme === null) {
         $coretheme = 'default';
     }
     $theme = $this->getKeyName();
     $changes = [];
     foreach ($this->_xmlloader->getElements('/assets/file') as $node) {
         // Cannot install assets if the directory is not setup!
         if (!$this->getAssetDir()) {
             continue;
         }
         $b = $this->getBaseDir();
         // The base filename with the directory.
         $filename = $node->getAttribute('filename');
         // The new theme asset will be installed into the same directory as its theme.
         // This differs from usual components because they just follow whatever theme is currently running.
         //$nf = Core::File($assetbase . $theme . '/' . $filename);
         $trimmedfilename = substr($b . $node->getAttribute('filename'), strlen($this->getAssetDir()));
         $themespecificfilename = $assetbase . $theme . '/' . $trimmedfilename;
         $newfilename = 'assets/' . $trimmedfilename;
         // Before anything, check and see if this file has a custom override file present.
         if (file_exists(ROOT_PDIR . 'themes/custom/' . $newfilename)) {
             // If so, then copy that asset to the custom directory too!
             $f = \Core\Filestore\Factory::File(ROOT_PDIR . 'themes/custom/' . $newfilename);
             $srcname = '!CUSTOM!';
         } else {
             // Otherwise, the local file is guaranteed to be a local file.
             $f = new \Core\Filestore\Backends\FileLocal($b . $filename);
             $srcname = '-theme- ';
         }
         if ($verbosity == 2) {
             CLI::PrintActionStart('Installing ' . $srcname . ' asset ' . $f->getBasename());
         }
         $nf = \Core\Filestore\Factory::File($newfilename);
         /*
         			// The various replacement possibilities for this file.
         			// The new destination must be in the theme-specific directory, this is a
         			// bit of a hack from the usual behaviour of the filestore system.
         			// Since that's designed to return the default if the theme-specific doesn't exist.
         			$replacements = array(
         				// The theme is not default, but the system translated the path to the default directory.
         				// This is because the file doesn't exist in any theme.
         				// This is actually expected behaviour, except unwanted here.
         				'default/' . $trimmedfilename => $theme . '/' . $trimmedfilename,
         				// The theme is not the currently installed, but the system translated the path to the that directory.
         				// This is because the filename is the same as the installed theme, so the system just translated there.
         				// We don't want that.
         				$coretheme . '/' . $trimmedfilename => $theme . '/' . $trimmedfilename,
         			);
         
         
         			foreach($replacements as $k => $v){
         				if($k == $v) continue;
         				if(strpos($nf->getFilename(), $k) !== false){
         					$nf->setFilename( str_replace($k, $v, $nf->getFilename()) );
         				}
         			}
         */
         // Check if this file even needs updated. (this is primarily used for reporting reasons)
         if ($nf->exists() && $nf->identicalTo($f)) {
             //echo "Skipping file, it's identical.<br/>";
             if ($verbosity == 2) {
                 CLI::PrintActionStatus('skip');
             }
             continue;
         } elseif ($nf->exists()) {
             $action = 'Replaced';
         } else {
             $action = 'Installed';
         }
         if (!$f->isReadable()) {
             throw new \InstallerException('Source file [' . $f->getFilename() . '] is not readable.');
         }
         try {
             $f->copyTo($nf, true);
         } catch (\Exception $e) {
             throw new \InstallerException('Unable to copy [' . $f->getFilename() . '] to [' . $nf->getFilename() . ']');
         }
         $change = $action . ' ' . $nf->getFilename();
         $changes[] = $change;
         if ($verbosity == 1) {
             CLI::PrintLine($change);
         } elseif ($verbosity == 2) {
             CLI::PrintActionStatus('ok');
         }
     }
     // If there are custom assets not registered by any application, install them too!
     // This will allow an admin to upload additional css resources and images easily.
     $directory = \Core\Filestore\Factory::Directory('themes/custom/assets');
     $ls = $directory->ls(null, true);
     $baseStrLen = strlen(ROOT_PDIR . '/themes/custom/assets');
     foreach ($ls as $fileOrDir) {
         if ($fileOrDir instanceof File) {
             $newfilename = substr($fileOrDir->getFilename(), $baseStrLen);
             if ($verbosity == 2) {
                 CLI::PrintActionStart('Installing CUSTOM   asset ' . $newfilename);
             }
             $nf = \Core\Filestore\Factory::File('asset/' . $newfilename);
             if ($nf->exists() && $nf->identicalTo($fileOrDir)) {
                 //echo "Skipping file, it's identical.<br/>";
                 if ($verbosity == 2) {
                     CLI::PrintActionStatus('skip');
                 }
                 continue;
             } elseif ($nf->exists()) {
                 $action = 'Replaced';
             } else {
                 $action = 'Installed';
             }
             try {
                 $fileOrDir->copyTo($nf, true);
             } catch (\Exception $e) {
                 throw new \InstallerException('Unable to copy [' . $fileOrDir->getFilename() . '] to [' . $nf->getFilename() . ']');
             }
             $change = $action . ' ' . $nf->getFilename();
             $changes[] = $change;
             if ($verbosity == 1) {
                 CLI::PrintLine($change);
             } elseif ($verbosity == 2) {
                 CLI::PrintActionStatus('ok');
             }
         }
     }
     if (!sizeof($changes)) {
         if ($verbosity > 0) {
             CLI::PrintLine('No changes required');
         }
         return false;
     }
     // Make sure the asset cache is purged!
     \Core\Cache::Delete('asset-resolveurl');
     return $changes;
 }
コード例 #2
0
	public function actionStart($message){
		if($this->realtime){
			CLI::PrintActionStart($message);
		}

		if($this->_actionMessage){
			$this->_profiler->record('[ABORTED]');
			$this->log[] = $this->_actionMessage . ' [ABORTED]';
		}

		$this->_profiler->record($message);
		$this->_actionMessage = $message;
	}
コード例 #3
0
ファイル: bundler.php プロジェクト: nicholasryan/CorePlus
	file_put_contents($destdir . '/' . $desttgz . '/packages.html', $changelog);

	CLI::PrintHeader('Finalizing Bundling for ' . $b['name'] . ' ' . $version);

	// create the tarballs!
	CLI::PrintActionStart("Creating tarball");
	//exec('tar -czf "' . $destdir . '/' . $desttgz . '.tgz" -C "' . $destdir . '" --exclude-vcs --exclude=*~ --exclude=._* ' . $desttgz);
	exec('tar -czf "' . $destdir . '/' . $desttgz . '.tgz" -C "' . $destdir . '/' . $desttgz . '" --exclude-vcs --exclude=*~ --exclude=._* .');
	CLI::PrintActionStatus('ok');

	CLI::PrintActionStart("Creating zip");
	//exec('cd "' . $destdir . '/"; zip -rq "' . $desttgz . '.zip" "' . $desttgz . '"; cd -');
	exec('cd "' . $destdir . '/' . $desttgz . '/"; zip -rq "../' . $desttgz . '.zip" .; cd -');
	CLI::PrintActionStatus('ok');

	CLI::PrintActionStart("Creating hashes");
	exec('md5sum "' . $destdir . '/' . $desttgz . '.tgz" > "' . $destdir . '/' . $desttgz . '.tgz.md5"');
	exec('md5sum "' . $destdir . '/' . $desttgz . '.zip" > "' . $destdir . '/' . $desttgz . '.zip.md5"');
	CLI::PrintActionStatus('ok');

	CLI::PrintActionStart("Cleaning up");
	exec('rm -fr "' . $destdir . '/' . $desttgz . '"');
	CLI::PrintActionStatus('ok');
}


// Give the option to automatically commit and tag all changes for the component.
if(CLI::PromptUser('Bundles created, GIT tag the release for ' . $version . '?', 'boolean', true)){
	exec('git tag -m "Release Version ' . $version . '" -f ' . 'v' . str_replace('~', '-', $version));
	exec('git push --tags');
}
コード例 #4
0
	public function email_test(){
		// Admin-only page.
		if(!\Core\user()->checkAccess('g:admin')){
			return View::ERROR_ACCESSDENIED;
		}

		$request = $this->getPageRequest();
		$view = $this->getView();

		if(!$request->isPost()){
			return View::ERROR_BADREQUEST;
		}

		if(!$request->getPost('email')){
			return View::ERROR_BADREQUEST;
		}

		$view->mode = View::MODE_NOOUTPUT;
		$view->contenttype = View::CTYPE_HTML;
		$view->render();

		$dest         = $request->getPost('email');
		$method       = ConfigHandler::Get('/core/email/mailer');
		$smtpHost     = ConfigHandler::Get('/core/email/smtp_host');
		$smtpUser     = ConfigHandler::Get('/core/email/smtp_user');
		$smtpPass     = ConfigHandler::Get('/core/email/smtp_password');
		$smtpPort     = ConfigHandler::Get('/core/email/smtp_port');
		$smtpSec      = ConfigHandler::Get('/core/email/smtp_security');
		$sendmailPath = ConfigHandler::Get('/core/email/sendmail_path');
		$emailDebug   = [];

		$emailDebug[] = 'Sending Method: ' . $method;

		switch($method){
			case 'smtp':
				$emailDebug[] = 'SMTP Host: ' . $smtpHost . ($smtpPort ? ':' . $smtpPort : '');
				$emailDebug[] = 'SMTP User/Pass: '******'//' . ($smtpPass ? '*** saved ***' : 'NO PASS') : 'Anonymous');
				$emailDebug[] = 'SMTP Security: ' . $smtpSec;
				break;
			case 'sendmail':
				$emailDebug[] = 'Sendmail Path: ' . $sendmailPath;
				break;
		}

		CLI::PrintHeader('Sending test email to ' . $dest);

		CLI::PrintActionStart('Initializing Email System');
		try{
			$email = new Email();
			$email->addAddress($dest);
			$email->setSubject('Test Email');
			$email->templatename = 'emails/admin/test_email.tpl';
			$email->assign('debugs', $emailDebug);
			$email->getMailer()->SMTPDebug = 2;

			CLI::PrintActionStatus(true);
		}
		catch(Exception $e){
			CLI::PrintActionStatus(false);
			CLI::PrintError($e->getMessage());
			CLI::PrintLine($e->getTrace());

			return;
		}

		CLI::PrintActionStart('Sending Email via ' . $method);
		try{
			$email->send();

			CLI::PrintActionStatus(true);
		}
		catch(Exception $e){
			CLI::PrintActionStatus(false);
			CLI::PrintError($e->getMessage());
			CLI::PrintLine(explode("\n", $e->getTraceAsString()));
		}

		CLI::PrintHeader('Sent Headers:');
		CLI::PrintLine(explode("\n", $email->getMailer()->CreateHeader()));

		CLI::PrintHeader('Sent Body:');
		CLI::PrintLine(explode("\n", $email->getMailer()->CreateBody()));
	}
コード例 #5
0
ファイル: reinstall.php プロジェクト: nicholasryan/CorePlus
			// If the class doesn't explicitly end with "Model", it's also not a model.
			continue;
		}
		if(strpos($class, '\\') !== false){
			// If this "Model" class is namespaced, it's not a valid model!
			// All Models MUST reside in the global namespace in order to be valid.
			continue;
		}

		$ref = new ReflectionClass($class);
		if(!$ref->getProperty('HasSearch')->getValue()){
			// This model doesn't have the searchable flag, skip it.
			continue;
		}

		CLI::PrintActionStart("Syncing searchable model $class");
		$fac = new ModelFactory($class);
		foreach($fac->get() as $m){
			/** @var Model $m */
			$m->set('search_index_pri', '!');
			$m->save();
		}
		CLI::PrintActionStatus('ok');
		$changes[] = "Synced searchable model " . $class;
	}
}

// Flush the system cache, just in case
\Core\Cache::Flush();
\Core\Templates\Backends\Smarty::FlushCache();
コード例 #6
0
ファイル: packager.php プロジェクト: nicholasryan/CorePlus
					else{
						CLI::PrintLine('Added ' . $linesadded . ($linesadded != 1 ? ' lines' : ' line') . ' to the changelog successfully!');
						print $thischange->fetchFormatted() . NL . NL;
					}

					// Cleanup
					unset($thischange, $versioncheck, $previouschange, $previousdate, $changes, $linecount, $linesadded, $line);
				}
				break;
			case 'viewchange':
				// Just print the current CHANGELOG section, easy now that everything is compartmentalized.
				CLI::PrintHeader('CHANGELOG for ' . $packager->getLabel() . ' ' . $packager->getVersion());
				CLI::PrintLine($packager->getChangelogSection()->fetchFormatted());
				break;
			case 'save':
				CLI::PrintActionStart('Saving ' . $packager->getLabel());
				$packager->save();
				CLI::PrintActionStatus('ok');
				$saved = true;

				$saveopts = [
				    'package-sign-commit' => 'Create signed package and GIT commit any changes',
				    'package-sign'        => 'Create signed package',
				    'package'             => 'Create unsigned package',
				    'commit'              => 'GIT commit any changes',
				    'menu'                => 'Do nothing else, back to menu',
				    'quit'                => 'Do nothing else and exit script',
				];

				if(!sizeof($autostack)){
					$saveans = CLI::PromptUser(ucfirst($packager->getLabel()) . ' saved, do you want to bundle the changes into a package?', $saveopts, 'menu');
コード例 #7
0
	/**
	 * Internal function to parse and handle the dataset in the <upgrade> and <install> tasks.
	 * This is used for installations and upgrades.
	 *
	 * Unlike the other parse functions, this handles a single node at a time.
	 *
	 * @param $node DOMElement
	 * @param $verbose bool
	 *
	 * @throws InstallerException
	 */
	private function _parseDatasetNode(DOMElement $node, $verbose = false){
		$action   = $node->getAttribute('action');
		$table    = $node->getAttribute('table');
		$haswhere = false;
		$sets     = array();
		$renames  = array();
		$ds       = new Core\Datamodel\Dataset();


		$ds->table($table);

		foreach($node->getElementsByTagName('datasetset') as $el){
			$sets[$el->getAttribute('key')] = $el->nodeValue;
		}

		foreach($node->getElementsByTagName('datasetrenamecolumn') as $el){
			// <datasetrenamecolumn oldname="ID" newname="id"/>
			$renames[$el->getAttribute('oldname')] = $el->getAttribute('newname');
		}

		foreach($node->getElementsByTagName('datasetwhere') as $el){
			$haswhere = true;
			$ds->where(trim($el->nodeValue));
		}

		switch($action){
			case 'alter':
				if(sizeof($sets)) throw new InstallerException('Invalid mix of arguments on ' . $action . ' dataset request, datasetset is not supported!');
				if($haswhere) throw new InstallerException('Invalid mix of arguments on ' . $action . ' dataset request, datasetwhere is not supported!');

				foreach($renames as $k => $v){
					// ALTER TABLE `controllers` CHANGE `ID` `id` INT( 11 ) NOT NULL AUTO_INCREMENT
					$ds->renameColumn($k, $v);
				}
				break;
			case 'update':
				foreach($sets as $k => $v){
					$ds->update($k, $v);
				}
				break;
			case 'insert':
				foreach($sets as $k => $v){
					$ds->insert($k, $v);
				}
				break;
			case 'delete':
				if(sizeof($sets)) throw new InstallerException('Invalid mix of arguments on ' . $action . ' dataset request');
				if(!$haswhere) throw new InstallerException('Cowardly refusing to delete with no where statement');
				$ds->delete();
				break;
			default:
				throw new InstallerException('Invalid action type, '. $action);
		}

		// and GO!
		if($verbose){
			CLI::PrintActionStart('Executing dataset ' . $action . ' command on ' . $table);
		}

		$ds->execute();
		if($ds->num_rows){
			CLI::PrintActionStatus(true);
			return array($action . ' on table ' . $table . ' affected ' . $ds->num_rows . ' records.');
		}
		else{
			CLI::PrintActionStatus(false);
			return false;
		}
	}