function Initialize() { // Set PHP configuration options $options = array('mbstring.language' => 'Neutral', 'mbstring.internal_encoding' => 'UTF-8', 'mbstring.encoding_translation' => 'On', 'mbstring.http_input' => 'auto', 'mbstring.detect_order' => 'ASCII,UTF-8,JIS,SJIS,EUC-JP', 'upload_max_filesize' => '21M', 'post_max_size' => '24M', 'display_errors' => true); foreach ($options as $key => $value) { ini_set($key, $value); } // Required for UTF-8 support mb_language('uni'); // Error display error_reporting(E_ALL ^ E_NOTICE); // Add app/ and engine/ to include path set_include_path(get_include_path() . PATH_SEPARATOR . './app' . PATH_SEPARATOR . './engine'); // Load classes $classesDir = 'engine/classes'; $dirHandle = opendir($classesDir); while ($filename = readdir($dirHandle)) { // Make sure files end in .php if ($filename != basename($filename, '.php')) { $classPath = $classesDir . '/' . $filename; if (!is_dir($classPath)) { require_once $classPath; } } } // Start caching engine; this also initializes output buffering $this->cache = new Cache(); // Start output buffering ob_start('mb_output_handler'); // Define files directory $this->filesDirectory = 'files/'; // Load configuration files $this->projectConfig = IniFile::Parse('app/config/project.ini', true); $this->serverConfig = IniFile::Parse('app/config/server.ini', true); // Define constants define('ROOT', $this->serverConfig['root']); define('ERROR_FOREIGN_KEY_CONSTRAINT', 2); // Used in engine/classes/Module.php // Load database field types $this->fieldTypes = IniFile::Parse('engine/database/types.ini'); // Load module fields $this->moduleFields = IniFile::Parse('engine/database/moduleFields.ini', true); $this->versionsSupportFields = IniFile::Parse('engine/database/versionsSupportFields.ini', true); // Load GetID3 require_once 'engine/libraries/getid3/getid3.php'; // Determine default language $this->defaultLanguage = $this->projectConfig['languages'][0]; // Determine requested language $requestedLanguage = $_GET['language']; if ($requestedLanguage && in_array($requestedLanguage, $this->projectConfig['languages'])) { // User has manually switched language Cookie::Create('language', $requestedLanguage); $this->language = $requestedLanguage; } elseif ($_COOKIE['language']) { // User has previously selected a language $this->language = $_COOKIE['language']; } else { // User has never selected a language; use default $this->language = $this->defaultLanguage; } // Load strings in the requested language $this->strings = IniFile::Parse('engine/strings/' . $this->language . '.ini', true); // Load shorthands (useful function aliases; must load after strings) require 'engine/helpers/shorthands.php'; // Connect to database $db = $this->serverConfig['database']; if (!($this->databaseLink = Database::Connect($db['server'], $db['username'], $db['password'], $db['database']))) { trigger_error("Couldn't connect to database " . $db['database'], E_USER_ERROR); } // Get available modules list $engineModules = Filesystem::GetDirNames('engine/modules'); $this->appModules = Filesystem::GetDirNames('app/modules'); $this->availableModules = $engineModules + $this->appModules; // Strip root directory and trailing slashes from full path request $pathString = $_SERVER['REQUEST_URI']; $barePath = substr($pathString, 0, strrpos($pathString, '?')); $pathString = $barePath ? $barePath : $pathString; $fullRequest = rtrim($pathString, '/'); preg_match('|^' . ROOT . '(.*)$|', $fullRequest, $requestArray); // Use requested URL, or use root path if none was requested $this->request = $requestArray[1] ? $requestArray[1] : $this->projectConfig['rootPath']; // We sync using database time (might differ from PHP time) $databaseTimeQuery = new Query(array('fields' => 'NOW()')); $databaseTime = $databaseTimeQuery->GetSingleValue(); $this->databaseTime = $databaseTime; // Make sure everything is properly initialized $tables = Database::GetTables(); if (!$tables['users'] || !$tables['_paths']) { $this->FirstRun(); } // Get installed modules list $this->installedModules = Query::SimpleResults('_modules'); // Create User object $this->user = new User(); // Create layout object $this->template = new Template(); // Determine mode $requestedMode = $_GET['mode']; $availableModes = IniFile::Parse('engine/config/modes.ini'); if ($availableModes[$requestedMode]) { // If requested mode exists, use it $this->mode = $requestedMode; } else { // HTML is the default mode $this->mode = 'html'; } // Load paths $paths = Query::FullResults('_paths'); foreach ($paths as $path) { // Use path as key in $_JAM->paths array $this->paths[$path['path']] = $path; } // Look for request in paths if ($path = $this->paths[$this->request]) { // Path does exist if ($path['current']) { // This is a valid path; proceed to module if ($this->rootModule = Module::GetNewModule($this->installedModules[$path['module']], $path['item'])) { // Check whether we have sufficient privileges to display the module if ($this->rootModule->CanView()) { // Display module $this->rootModule->Display(); // Determine path to admin pane for this item $adminPath = 'admin/' . $moduleName; if ($this->paths[$adminPath]) { if ($path['item']) { $adminPath .= '?a=edit&id=' . $path['item']; } $this->adminPath = ROOT . $adminPath; } else { $this->adminPath = ROOT . 'admin'; } } else { // Display login if we can't display $this->user->Connect(); } } else { trigger_error("Couldn't load root module", E_USER_ERROR); } } else { // This is an obsolete URL; find its current (up to date) equivalent $whereArray = array('module = ' . $path['module'], 'item = ' . $path['item'], "language = '" . $path['language'] . "'", 'current = TRUE'); $currentPath = Query::SingleValue('_paths', 'path', $whereArray); HTTP::NewLocation($currentPath); } } else { // Path does not exist; throw 404 header("HTTP/1.0 404 Not Found"); $this->rootModule = Module::GetNewModule('errors'); $this->rootModule->Display(); } // Store and flush the contents of the output buffer $buffer = ob_get_clean(); // Load and display template if ($this->mode == 'html' && $this->rootModuleName == 'admin') { // Special case for admin pages requested in HTML $templateName = 'html_admin'; } else { $templateName = $this->mode; } $this->template->SetTemplate($templateName); $this->template->Display($buffer); // Set MIME type $contentType = $this->contentType ? $this->contentType : $availableModes[$this->mode]; if ($contentType) { header('Content-Type: ' . $contentType); } // Write to cache; this also cleans output buffering $this->cache->Write(); }
function FetchItems($queryParams = '') { global $_JAM; $query = new Query(); $query->AddFrom($this->name); if ($this->config['keepVersions']) { // This is a multiversions table; fetch 'master' field $query->AddFields(array('master' => 'IF(' . $this->name . '.master IS NULL, ' . $this->name . '.id, ' . $this->name . '.master)')); $query->AddWhere($this->name . '.current = TRUE'); } else { // This is a standard table; fetch 'id' field $query->AddFields(array('id' => $this->name . '.id')); } /* // Order by master if we're keeping versions if ($this->config['keepVersions']) { $query->AddOrderBy('master DESC'); }*/ // Add localized data if ($this->isLocalizable) { $localizedTable = $this->name . '_localized'; $query->AddFields(array('language' => $localizedTable . '.language')); $query->AddFrom($localizedTable); $where = array($localizedTable . '.item = ' . $this->name . '.id', $localizedTable . ".language = '" . $_JAM->language . "'"); $query->AddWhere($where); } // Load all fields if none were specified if (!$queryParams['fields']) { foreach ($this->schema as $name => $info) { $queryParams['fields'][] = $name; } } foreach ($this->schema as $name => $info) { // Manually remove multi fields from query; they will be processed anyway (possibly kludgy) if ($info['type'] == 'multi') { if ($multiFieldKey = array_search($name, $queryParams['fields'])) { unset($queryParams['fields'][$multiFieldKey]); } } // Process custom parameters if ($info['localizable']) { $replaceString = $this->name . '_localized.' . $name; } else { $replaceString = $this->name . '.' . $name; } // Fetch data for related modules if (@in_array($name, $queryParams['fields'])) { if ($info['type'] == 'int' && ($relatedModule = $info['relatedModule']) && $relatedModule != 'users' && $relatedModule != $this->name) { // Add fields from foreign module $relatedModuleSchema = Module::ParseConfigFile($relatedModule, 'config/schema.ini', true); foreach ($relatedModuleSchema as $foreignName => $foreignInfo) { $fields[$name . '_' . $foreignName] = $relatedModule . '.' . $foreignName; } $query->AddFields($fields); // Determine whether we should look for 'master' or 'id' field $relatedModuleConfig = Module::ParseConfigFile($relatedModule, 'config/config.ini', true); $joinCondition = $this->name . '.' . $name . ' = '; if ($relatedModuleConfig['keepVersions']) { $joinCondition .= $relatedModule . '.master AND ' . $relatedModule . '.current = TRUE'; } else { $joinCondition .= $relatedModule . '.id'; } // Build query $joinTable = $relatedModule; $query->AddJoin($this->name, $joinTable, $joinCondition); } } $queryParams = Module::InsertTableNames($queryParams, $name, $replaceString); } // Load custom parameters $query->LoadParameters($queryParams); // Load paths if appropriate if ($this->config['autoPaths'] || get_parent_class($this) && method_exists($this, 'GetPath')) { $query->AddFields(array('path' => '_paths.path')); $joinTable = '_paths'; $joinConditions[] = '_paths.module = ' . $this->moduleID; $joinConditions[] = '_paths.current = 1'; if ($this->config['keepVersions']) { $joinConditions[] = '((_paths.item = ' . $this->name . '.id AND ' . $this->name . '.master IS NULL) OR ' . '_paths.item = ' . $this->name . '.master)'; } else { $joinConditions[] = '_paths.item = ' . $this->name . '.id'; } $query->AddJoin($this->name, $joinTable, $joinConditions); if ($this->isLocalizable) { $query->AddWhere($this->name . '_localized.language = _paths.language'); } } // Debug query: //dp($query->GetQueryString()); // Fetch actual module data if ($this->rawData = $query->GetArray()) { // Load data for 'multi' fields if ($this->hasMulti) { $where = 'frommodule = ' . $this->moduleID; if ($multiArray = Query::FullResults('_relationships', $where)) { foreach ($this->rawData as $id => $item) { foreach ($multiArray as $multiData) { if ($multiData['fromid'] == $id) { $this->rawData[$id][$this->multiRelatedModules[$multiData['tomodule']]][] = $multiData['toid']; } } } } } // Make a copy of the data for processing so we can keep the raw data available $this->processedData = $this->rawData; // Post-process data foreach ($this->schema as $name => $info) { foreach ($this->processedData as $id => $data) { if ($this->processedData[$id][$name]) { switch ($info['type']) { case 'string': $this->processedData[$id][$name] = TextRenderer::SmartizeText($data[$name]); break; case 'text': case 'shorttext': if (!$info['wysiwyg']) { // Render text using TextRenderer if it's not a WYSIWYG field if (strstr($data[$name], "\n") !== false) { // String contains newline characters; format as multiline text $this->processedData[$id][$name] = TextRenderer::TextToHTML($data[$name]); } else { // String is a single line; format as single line $this->processedData[$id][$name] = TextRenderer::SmartizeText($data[$name]); } } break; case 'datetime': case 'timestamp': case 'date': case 'time': $this->processedData[$id][$name] = new Date($data[$name]); break; case 'file': $this->processedData[$id][$name] = $this->NestModule('files', $data[$name]); break; } } } } // Subclasses can provide a method to further format data if (method_exists($this, 'FormatData')) { $this->FormatData(); } if ($this->items) { // If $this->items is already set, don't overwrite it return $this->processedData; } else { return $this->items = $this->processedData; } } else { return false; } }