* @package MCMS\System */ abstract class SystemBase extends \Mammut\StrictObject implements \MCMS\Interfaces\iSystem { /** * * @var \Mammut\Log\Logger */ protected $LOG; /** * The active system instance * * @var \MCMS\Interfaces\iSystem */ protected static $instance = NULL; protected $weaving = array(); private $siteId = -1; private $target = array(); /** * * @var DB */ protected $db = NULL; /** * Private data VFS * @var iVFS */ protected $privatVFS = NULL; /** * Public data VFS * @var iVFS */ protected $publicVFS = NULL; /** * * @var array additional database conenctions */ protected $dbx = array(); protected $config = array(); //'timezone' => 'UTC','cache' => array('type' => 'mcms.MMPICacheNull'),'log' => 'none'); protected $plugins = array(); private $formBuilderClass; private $formFetcherClass; protected $context = array(); protected function __construct() { $this->LOG = \Mammut\Log\Logger::getInstance(get_called_class()); $this->formBuilderClass = \MCMS\_\Com\MCMS\Form\Builder::clazz(); $this->formFetcherClass = \MCMS\_\Com\MCMS\Form\Fetcher::clazz(); $this->privatVFS = new FileVFS(_DATAPATHX_.__DS__.'files'.__DS__.'private'.__DS__); $this->publicVFS = new FileVFS(_DATAPATHX_.__DS__.'files'.__DS__.'public'.__DS__); } static public function isInitialized() { // Logger::getInstance(__CLASS__)->traceStart(); return is_object(self::$instance); } /** * * @return \MCMS\Interfaces\iSystem */ static public final function getInstance() { // Logger::getInstance(__CLASS__)->traceStart(); self::__inStatic(); self::checkForInit(); return self::$instance; } public static function output($data) { } public function initContext($type, iContext $instance, $overwrite = false) { $this->LOG->traceStart(); if (!$overwrite && $this->isContextSet($type)) throw new IllegalStateException("Context {$type} is set already"); if (in_array($type,[iSystem::CTX_REQ, iSystem::CTX_SECURITY])) throw new IllegalStateException("Context {$type} cannot be set"); $this->context[$type] = $instance; $this->LOG->traceEnd(); } public function isContextSet($type) { return !empty($this->context[$type]); } static public function getContext($type) { // Logger::getInstance(__CLASS__)->traceStart(); // special context objects are redirected switch($type) { case self::CTX_REQ: return self::getInstance()->getRequest(); break; case self::CTX_SECURITY: return self::getInstance()->getUserSvc(); break; } // other context objects are served directly if (isset(self::getInstance()->context[$type])) return self::getInstance()->context[$type]; throw new ContextException("Context not found: {$type}"); } public function getWeaving() { return $this->weaving; } public function getCache() { return $this->context[iSystem::CTX_CACHE]; } public function getPrivateVFS() { return $this->privatVFS; } public function getPublicVFS() { return $this->publicVFS; } public function initDB($dsn, $user, $password, array $options = array()) { $this->LOG->traceStart(); $this->__inInstance(); if ($dsn instanceof DB) { $this->db = $dsn; return; } if(!isset($options['encoding'])) $options['encoding'] = 'utf8'; if(is_object($this->db)) throw new IllegalStateException('database already initalized'); $this->db = DB::newInstance($dsn, $user, $password, $options); $this->LOG->traceEnd(); } public function addDB($name, $dsn, $user, $password, array $options = array()) { $this->LOG->traceStart(); $this->__inInstance(); if(!empty($this->dbx[$name]) && is_object($this->dbx[$name])) throw new IllegalStateException('database already initalized'); $this->dbx[$name] = DB::newInstance($dsn, $user, $password, $options); $this->LOG->traceEnd(); } public function getDBXList() { // $this->LOG->traceStart(); return array_keys($this->dbx); } public function shutdownDB($name = NULL) { $this->LOG->traceStart(); if(empty($name)) { if(is_object($this->db)) $this->db->close(); $this->db = NULL; } else { if(!empty($this->dbx[$name]) && is_object($this->dbx[$name])) $this->dbx[$name]->close(); $this->dbx[$name] = NULL; } $this->LOG->traceEnd(); } /** * * @param int $siteId */ public function setSiteId($siteId) { $this->siteId = (int) $siteId; } public function isMultiLocale($siteId = -1) { return $this->getSiteParam($siteId, '','multilang') == 'y'; } public function getActiveLocale($siteId = -1) { $this->LOG->traceStart(); $locale = isset($this->config['defaultlocale']) ? $this->config['defaultlocale'] : NULL; if ($siteId > 0) { $db = $this->getDB(); $select = $db->select()->from('websitesettings')->columns(['value'])->where([ 'site_id' => $siteId, 'instance' => '', 'key' => 'defaultlang', ]); $result = $db->getObject($select); if (!empty($result)) { $locale = $result->value; } $locList = $this->getSiteParam($siteId, '','lang'); $locList = explode(',', $locList); $autoSel = $this->getSiteParam($siteId, '','autolangsel'); if ($autoSel == 'y') $locale = Locale::findBestLocale($_SERVER['HTTP_ACCEPT_LANGUAGE'], $locList, $locale); if(isset($_COOKIE['mcms_user_locale'])) { if(in_array($_COOKIE['mcms_user_locale'], $locList)) $locale = $_COOKIE['mcms_user_locale']; } } $this->LOG->traceEnd(); return $locale; } public function setUserLocale($locale, $siteId = -1) { setcookie("mcms_user_locale", $locale, 3600 * 24 * 90); } public function getActiveTimezone() { return new \DateTimeZone(date_default_timezone_get()); } public function getAllLocales($siteId = -1) { // $this->LOG->traceStart(); if($siteId == -1) $siteId = System::getInstance()->getSiteId(); $result = array(Locale::getInstance('de'),Locale::getInstance('en')); return $result; } public function getSiteId() { return $this->siteId; } public function setTarget($key, $value) { $this->target[$key] = $value; } public function getTarget($key) { if(isset($this->target[$key])) return $this->target[$key]; return NULL; } public function getConfig($name) { if(isset($this->config[$name])) return $this->config[$name]; else return NULL; } /** * Sets a system configuration * * @param string $name * the setting name * @param string $value * the setting value */ public function setConfig($name, $value) { $this->config[$name] = $value; } public function getDB($name = NULL) { // $this->LOG->traceStart(); if(empty($name)) { if(is_object($this->db)) return $this->db; else throw new IllegalStateException('database not initalized'); } else { if(!empty($this->dbx[$name]) && is_object($this->dbx[$name])) return $this->dbx[$name]; else throw new IllegalStateException('subdatabase ' . $name . ' not initalized'); } } /** * Loads a plugin into the system */ public function loadPlugin($category, $name, $priority = 1) { $this->LOG->traceStart(); $class = loadPlugin($category, $name); if(!class_exists($class)) throw new \Exception('Invalid plugin class ' . $class . ' for ' . $category . ':' . $name); $obj = new $class(); $this->plugins[$priority][$name] = &$obj; $this->LOG->traceEnd(); return $obj; } /** * Fetches a loaded plugin instance from the active system instance * * @param string $name * name of the plugin * @return \MCMS\Plugin\iPlugIn plugin instance */ public function getPlugin($name) { // $this->LOG->traceStart(); foreach($this->plugins as $priority_plugins) { if(isset($priority_plugins[$name])) return $priority_plugins[$name]; } return NULL; } /** * Get all plugins * * @return array */ public function getAllPlugins() { $this->LOG->traceStart(); $result = array(); foreach($this->plugins as $priority_plugins) { foreach($priority_plugins as &$p) $result[] = $p; } $this->LOG->traceEnd(); return $result; } /** * Unloads a plugin * * @param $name string * the plugin id */ public function unloadPlugin($name) { $this->LOG->traceStart(); $result = false; foreach($this->plugins as $priority_plugins) { if(isset($priority_plugins[$name])) { unset($priority_plugins[$name]); $result = true; } } $this->LOG->traceEnd(); return $result; } public function setFormBuilderClass($class) { // $this->LOG->traceStart(); $this->formBuilderClass = $class; } public function getFormBuilderClass() { // $this->LOG->traceStart(); return $this->formBuilderClass; } public function setFormFetcherClass($class) { // $this->LOG->traceStart(); $this->formFetcherClass = $class; } public function getFormFetcherClass() { // $this->LOG->traceStart(); return $this->formFetcherClass; } public function registerFormDatatype($typename, $formEditorComponentClass, $fetcherClass) { // $this->LOG->traceStart(); $this->editorClasses[$typename] = $formEditorComponentClass; $this->fetcherClasses[$typename] = $fetcherClass; } public function unregisterFormDatatype($typename) { // $this->LOG->traceStart(); unset($this->editorClasses[$typename], $this->fetcherClasses[$typename]); } protected function getEditorClasses() { $this->LOG->traceStart(); $editors = ComUtils::getActiveEditors(); $eclass = array(); foreach($editors as $type=>$id) $eclass[$type] = ComUtils::getEditorClass($type, $id); // $keyfield = $this->db->escapeColumnName('key'); // $result = $this->db->query('SELECT ' . $keyfield . ',' . $this->db->escapeColumnName('value') . ' FROM ' . $this->db->escapeTableName('websitesettings') . ' WHERE ' . $this->db->escapeColumnName('site_id') . '=0 AND' . ' ' . $this->db->escapeColumnName('instance') . '=\'\' AND ' . $keyfield . ' LIKE \'editors.%\''); // unset($keyfield); // while($row = $result->fetchRow()) { // $parts = explode('.', $row[0]); // $info = get_configfile_array(_COMPATHX_ . __DS__ . 'editor' . __DS__ . $parts[1] . __DS__ . $row[1] . __DS__ . '_info_.php', 'info'); // if(empty($info)) { // $info = get_configfile_array(_COMPATH_ . __DS__ . 'editor' . __DS__ . $parts[1] . __DS__ . $row[1] . __DS__ . '_info_.php', 'info'); // if(!empty($info['class'])) // $eclass[$parts[1]] = $row[1] . '.' . $info['class']; // } // elseif(!empty($info['class'])) // $eclass[$parts[1]] = $row[1] . '.' . $info['class']; // } // $result->close(); $this->LOG->traceEnd(); return $eclass; } protected function getFetcherClasses() { // $this->LOG->traceStart(); return $this->getEditorClasses(); } public function getFormDatatypeHandlers($type) { $this->LOG->traceStart(); $types_editor = $this->getEditorClasses(); $types_fetcher = $this->getFetcherClasses(); $result = array('editor' => $types_editor[$type],'fetcher' => $types_fetcher[$type]); $this->LOG->traceEnd(); return $result; } public function createFormBuilder($target = false) { $this->LOG->traceStart(); // foreach($this->getEditorClasses() as $type=>$classpath) // loadComponent('EDITOR', $type . '.' . $classpath); $builderClass = $this->formBuilderClass; $builder = new $builderClass($target, $this->getEditorClasses()); $this->LOG->traceEnd(); return $builder; } public function createFormFetcher($target = false, array $ignore = array()) { $this->LOG->traceStart(); // foreach($this->getEditorClasses() as $type=>$classpath) // loadComponent('EDITOR', $type . '.' . $classpath); $fetcherClass = $this->formFetcherClass; $fetcher = new $fetcherClass($target, $this->getFetcherClasses(), $ignore); $this->LOG->traceEnd(); return $fetcher; } /** * Checks if the system has been initalized. * * @throws IllegalStateException if system has not been initialized */ protected static function checkForInit() { // Logger::getInstance(__CLASS__)->traceStart(); if(!is_object(self::$instance)) throw new IllegalStateException('system not initalized'); } public function translate($text, $siteId = -1) { // $this->LOG->traceStart(); return $text; } public function injectSession(\MCMS\Plugin\iPlugInSession $session) { $this->LOG->traceStart(); $this->initContext(iSystem::CTX_SESSION, $session, true); $this->LOG->traceEnd(); } public function getSession() { // $this->LOG->traceStart(); return $this->context[iSystem::CTX_SESSION]; } public function getFileCacheDir($instance, $siteId = -1) { $this->LOG->traceStart(); if($siteId < 0) $siteId = $this->getSiteId(); $path = _DATAPATH_ . __DS__ . 'cache' . __DS__ . 'public' . __DS__ . $siteId . __DS__ . $instance . __DS__; if(!is_dir($path)) { if(!is_dir(_DATAPATH_ . __DS__ . 'cache' . __DS__ . 'public' . __DS__ . $siteId)) mkdir(_DATAPATH_ . __DS__ . 'cache' . __DS__ . 'public' . __DS__ . $siteId); if(!is_dir(_DATAPATH_ . __DS__ . 'cache' . __DS__ . 'public' . __DS__ . $siteId . __DS__ . $instance)) mkdir(_DATAPATH_ . __DS__ . 'cache' . __DS__ . 'public' . __DS__ . $siteId . __DS__ . $instance); } $this->LOG->traceEnd(); return $path; } public function purgeFileCacheDir($instance, $sideId = -1) { $this->LOG->traceStart(); if($sideId < 0) $siteId = $this->getSiteId(); $path = _DATAPATH_ . __DS__ . 'cache' . __DS__ . 'public' . __DS__ . $siteId . __DS__ . $instance . __DS__; if(is_dir($path)) rmdir_deep($path); $this->LOG->traceEnd(); return true; } public function getFileCacheURL($instance, $siteId = -1) { $this->LOG->traceStart(); if($siteId < 0) $siteId = $this->getSiteId(); $result = _DATAURL_ . '/cache/public/' . $siteId . '/' . $instance . '/'; $this->LOG->traceEnd(); return $result; } /** * Creates the file storage directory path from the parameters given * * @param string $instance * @param number $sideId * @param boolean $public * @return \Mammut\IO\File the file system path */ protected static function buildFileStorePath($instance, $sideId, $public) { Logger::getInstance(__CLASS__)->traceStart(); $tgtname = _DATAPATHX_ . __DS__ . 'files' . __DS__; $tgtname .= ($public ? 'public' : 'private') . __DS__; $tgtname .= $sideId . __DS__ . $instance . __DS__; Logger::getInstance(__CLASS__)->traceEnd(); return new \Mammut\IO\File($tgtname); } public function createFileStoreDir($instance, $sideId = -1, $public = true) { $this->LOG->traceStart(); $dir = self::buildFileStorePath($instance, $sideId, $public); if(!$dir->exists()) { $result = mkdir($dir->getPath(), 0777); chmod($dir->getPath(), 0777); $this->LOG->traceEnd(); return $result; } $this->LOG->traceEnd(); return false; } public function fileStoreExists($instance, $sideId = -1, $public = true) { $this->LOG->traceStart(); $dir = self::buildFileStorePath($instance, $sideId, $public); $this->LOG->traceEnd(); return $dir->exists(); } public function deleteFileStoreDir($instance, $sideId = -1, $public = true) { $this->LOG->traceStart(); $dir = self::buildFileStorePath($instance, $sideId, $public); if($dir->exists() && $dir->isDir()) $dir->delete(true); $this->LOG->traceEnd(); } public function getFileStoreDir($instance, $sideId = -1, $public = true) { $this->LOG->traceStart(); $dir = self::buildFileStorePath($instance, $sideId, $public); $this->LOG->traceEnd(); return $dir; } public function getFileStoreURL($instance, $sideId = -1) { $this->LOG->traceStart(); $tgtname = _DATAURLX_ . '/files/'; $tgtname .= 'public/' . $sideId . '/' . $instance . '/'; $this->LOG->traceEnd(); return $tgtname; } public function __destruct() { $this->LOG->traceStart(); $this->shutdownDB(); // if someone forgot that, shutdown db $this->LOG->traceEnd(); } }