/** * load configuration from a file * * @access public * @param string $configFile full path of the config file * @param array $options various options, depending on the reader * @return array $config complete configuration */ function loadConfigFile($configFile, $options = array()) { if (!function_exists("wddx_add_vars")) { return patErrorManager::raiseError(PATCONFIGURATION_ERROR_DRIVER_NOT_WORKING, "WDDX extension is not installed on your system."); } $fp = @fopen($configFile, "r"); $wddx = fread($fp, filesize($configFile)); $conf = wddx_deserialize($wddx); if ($conf === NULL) { return patErrorManager::raiseError(PATCONFIGURATION_ERROR_CONFIG_INVALID, "{$configFile} is no valid WDDX file."); } return array("config" => $conf, "externalFiles" => array(), "cacheAble" => true); }
/** * create an ini representation of the current config * * @access private * @param array $config config to serialize * @param array $options options for the serialization * @return string $content xml representation */ function serializeConfig($config, $options) { if (!function_exists("wddx_add_vars")) { return patErrorManager::raiseError(PATCONFIGURATION_ERROR_DRIVER_NOT_WORKING, "WDDX extension is not installed on your system."); } if (!isset($options["comment"])) { $options["comment"] = "Configuration generated by patConfiguration v" . $this->configObj->systemVars["appVersion"] . ", (c) " . implode(",", $this->configObj->systemVars["author"]); } $options["comment"] = $this->replaceXMLSpecialchars($options["comment"]); $packet_id = wddx_packet_start($options["comment"]); foreach ($config as $key => $value) { ${$key} = $value; wddx_add_vars($packet_id, $key); } $packet = wddx_packet_end($packet_id); $config = "<?xml version=\"1.0\" encoding=\"{$this->configObj->encoding}\"?>" . $packet; return $config; }
/** * call the function * * @access public * @param array parameters of the function (= attributes of the tag) * @param string content of the tag * @return string content to insert into the template */ function call($params, $content) { $tmpl = $params['template']; unset($params['template']); if (!$this->_tmpl->exists($tmpl)) { return patErrorManager::raiseError(PATTEMPLATE_FUNCTION_CALL_ERROR_NO_TEMPLATE, 'Template ' . $tmpl . ' does not exist'); } /** * clear template and all of its dependencies */ $this->_tmpl->clearTemplate($tmpl, true); /** * add variables */ $this->_tmpl->addVars($tmpl, $params); $this->_tmpl->addVar($tmpl, 'CONTENT', $content); /** * get content */ return $this->_tmpl->getParsedTemplate($tmpl); }
/** * sets the way the patErrorManager will handle teh different error levels. Use this * if you want to override the default settings. * * Error handling modes: * - ignore * - trigger * - verbose * - echo * - callback * - die * * You may also set the error handling for several modes at once using PHP's bit operations. * Examples: * - E_ALL = Set the handling for all levels * - E_ERROR | E_WARNING = Set the handling for errors and warnings * - E_ALL ^ E_ERROR = Set the handling for all levels except errors * * @static * @access public * @param int $level The error level for which to set the error handling * @param string $mode The mode to use for the error handling. * @param mixed $options Optional: Any options needed for the given mode. * @return mixed $result True on success, or a patError object if failed. * @see getErrorHandling() */ function setErrorHandling($level, $mode, $options = null) { $levels = $GLOBALS['_pat_errorLevels']; $function = 'handleError' . ucfirst($mode); if (!is_callable(array('patErrorManager', $function))) { return patErrorManager::raiseError(E_ERROR, 'patErrorManager:' . PATERRORMANAGER_ERROR_ILLEGAL_MODE, 'Error Handling mode is not knwon', 'Mode: ' . $mode . ' is not implemented.'); } foreach ($levels as $eLevel => $eTitle) { if (($level & $eLevel) != $eLevel) { continue; } // set callback options if ($mode == 'callback') { if (!is_array($options)) { return patErrorManager::raiseError(E_ERROR, 'patErrorManager:' . PATERRORMANAGER_ERROR_ILLEGAL_OPTIONS, 'Options for callback not valid'); } if (!is_callable($options)) { $tmp = array('GLOBAL'); if (is_array($options)) { $tmp[0] = $options[0]; $tmp[1] = $options[1]; } else { $tmp[1] = $options; } return patErrorManager::raiseError(E_ERROR, 'patErrorManager:' . PATERRORMANAGER_ERROR_CALLBACK_NOT_CALLABLE, 'Function is not callable', 'Function:' . $tmp[1] . ' scope ' . $tmp[0] . '.'); } } // save settings $GLOBALS['_pat_errorHandling'][$eLevel] = array('mode' => $mode); if ($options != null) { $GLOBALS['_pat_errorHandling'][$eLevel]['options'] = $options; } } return true; }
/** * get the contents of a file * * @access private * @param string filename * @return string file contents */ function _getFileContents($file) { if (!$this->_isRemote && (!file_exists($file) || !is_readable($file))) { return patErrorManager::raiseError(PATTEMPLATE_READER_ERROR_NO_INPUT, "Could not load templates from {$file}."); } if (function_exists('file_get_contents')) { $content = @file_get_contents($file); } else { $content = implode('', file($file)); } /** * store the file name */ array_push($this->_files, $file); return $content; }
/** * Parse the template location syntax to a query * * @access private * @param string * @param DB_common */ function parseInputStringToQuery($input, $db) { // Input is no query if (strstr($input, 'SELECT') !== false) { return $input; } $matches = array(); if (!preg_match('/^([a-z]+)\\[([^]]+)\\]\\/@([a-z]+)$/i', $input, $matches)) { return patErrorManager::raiseError(PATTEMPLATE_READER_DB_ERROR_UNKNOWN_INPUT, 'Could not parse input string.'); } $table = $matches[1]; $templateField = $matches[3]; $where = array(); $tmp = explode(',', $matches[2]); foreach ($tmp as $clause) { list($field, $value) = explode('=', trim($clause)); if ($field[0] !== '@') { return patErrorManager::raiseError(PATTEMPLATE_READER_DB_ERROR_UNKNOWN_INPUT, 'Could not parse input string.'); } $field = substr($field, 1); array_push($where, $field . '=' . $db->quoteSmart($value)); } $query = sprintf('SELECT %s FROM %s WHERE %s', $templateField, $table, implode(' AND ', $where)); return $query; }
/** * parse all dependencies in a template * * @access private * @param string */ function _parseDependencies($template) { $countDep = count($this->_templates[$template]['currentDependencies']); for ($i = 0; $i < $countDep; $i++) { $depTemplate = $this->_templates[$template]['currentDependencies'][$i]; if ($depTemplate == $template) { return patErrorManager::raiseError(PATTEMPLATE_ERROR_RECURSION, 'You have an error in your template "' . $template . '", which leads to recursion'); } $this->parseTemplate($depTemplate); $var = $this->_startTag . 'TMPL:' . strtoupper($depTemplate) . $this->_endTag; $this->_templates[$template]['work'] = str_replace($var, $this->_templates[$depTemplate]['result'], $this->_templates[$template]['work']); } return true; }
/** * parse an external xml file * * @param string filename, without dirname * @return boolean true on success, patError on failure */ function parseXMLFile($file) { // add it to included files array_push($this->includedFiles, $file); $parserCount = count($this->parsers); $this->parsers[$parserCount] = $this->createParser(); if (!($fp = @fopen($file, 'r'))) { return patErrorManager::raiseError(PATCONFIGURATION_ERROR_FILE_NOT_FOUND, 'Could not open XML file ' . $file); } array_push($this->xmlFiles, $file); flock($fp, LOCK_SH); while ($data = fread($fp, 4096)) { if (!xml_parse($this->parsers[$parserCount], $data, feof($fp))) { $message = sprintf('XML error: %s at line %d in file %s', xml_error_string(xml_get_error_code($this->parsers[$parserCount])), xml_get_current_line_number($this->parsers[$parserCount]), $file); array_pop($this->xmlFiles); flock($fp, LOCK_UN); fclose($fp); xml_parser_free($this->parsers[$parserCount]); return patErrorManager::raiseError(PATCONFIGURATION_ERROR_CONFIG_INVALID, $message); } } array_pop($this->xmlFiles); flock($fp, LOCK_UN); fclose($fp); xml_parser_free($this->parsers[$parserCount]); return true; }
/** * Register an event handler * * An event handler can be any valid PHP callback. You may pass * one of the following values: * - string functionname to call a globally declared function * - array( string classname, string methodname) to call a static method * - array( object obj, string methodname) to call a method of an object * * When the handler is called, two parameters will be passed: * - object form : a patForms object * - string event : the name of the event has should be handled. * * An event handler should always return true. If false is returned, * the event will be cancelled. * * Currently handlers for the following events can be registered: * - onSubmit * - onSuccess * - onError * * @access public * @param string event name * @param mixed event handler * @return boolean true, if the handler could be registered * @see triggerEvent() * @see $_validEvents */ function registerEventHandler($event, $handler) { if (!in_array($event, $this->_validEvents)) { return patErrorManager::raiseError(PATFORMS_ERROR_UNKNOWN_EVENT, 'Cannot register event handler for unknown event "' . $event . '".'); } if (!is_callable($handler)) { return patErrorManager::raiseError(PATFORMS_ERROR_INVALID_HANDLER, 'Event handler is not callable.'); } if (!isset($this->_eventHandler[$event])) { $this->_eventHandler[$event] = array(); } $this->_eventHandler[$event][] =& $handler; return true; }
/** * loads a patTemplate module * * Modules are located in the patTemplate folder and include: * - Readers * - Caches * - Variable Modifiers * - Filters * - Functions * - Stats * * @access public * @param string moduleType (Reader|TemplateCache|Modifier|OutputFilter|InputFilter) * @param string moduleName * @param array parameters for the module * @return object */ function &loadModule($moduleType, $moduleName, $params = array()) { if (!isset($this->_modules[$moduleType])) { $this->_modules[$moduleType] = array(); } $sig = md5($moduleName . serialize($params)); if (isset($this->_modules[$moduleType][$sig])) { return $this->_modules[$moduleType][$sig]; } if (!class_exists('patTemplate_Module')) { $file = sprintf("%s/Module.php", $this->getIncludePath()); if (!@(include_once $file)) { return patErrorManager::raiseError(PATTEMPLATE_ERROR_BASECLASS_NOT_FOUND, 'Could not load module base class.'); } } $baseClass = 'patTemplate_' . $moduleType; if (!class_exists($baseClass)) { $baseFile = sprintf("%s/%s.php", $this->getIncludePath(), $moduleType); if (!@(include_once $baseFile)) { return patErrorManager::raiseError(PATTEMPLATE_ERROR_BASECLASS_NOT_FOUND, "Could not load base class for {$moduleType} ({$baseFile})."); } } $moduleClass = 'patTemplate_' . $moduleType . '_' . $moduleName; if (!class_exists($moduleClass)) { if (isset($this->_moduleDirs[$moduleType])) { $dirs = $this->_moduleDirs[$moduleType]; } else { $dirs = array(); } array_push($dirs, $this->getIncludePath() . '/' . $moduleType); foreach ($dirs as $dir) { $moduleFile = sprintf("%s/%s.php", $dir, str_replace('_', '/', $moduleName)); if (@(include_once $moduleFile)) { break; } return patErrorManager::raiseError(PATTEMPLATE_ERROR_MODULE_NOT_FOUND, "Could not load module {$moduleClass} ({$moduleFile})."); } } if (!class_exists($moduleClass)) { return patErrorManager::raiseError(PATTEMPLATE_ERROR_MODULE_NOT_FOUND, "Module file {$moduleFile} does not contain class {$moduleClass}."); } $this->_modules[$moduleType][$sig] =& new $moduleClass(); if (method_exists($this->_modules[$moduleType][$sig], 'setTemplateReference')) { $this->_modules[$moduleType][$sig]->setTemplateReference($this); } $this->_modules[$moduleType][$sig]->setParams($params); return $this->_modules[$moduleType][$sig]; }
/** * call the function * * @access public * @param array parameters of the function (= attributes of the tag) * @param string content of the tag * @return string content to insert into the template */ function call($params, $content) { // get the name of the template to use if (isset($params['template'])) { $tmpl = $params['template']; unset($params['template']); } elseif (isset($params['_originalTag'])) { $tmpl = $params['_originalTag']; unset($params['_originalTag']); } else { return patErrorManager::raiseError(PATTEMPLATE_FUNCTION_CALL_ERROR_NO_TEMPLATE, 'No template for Call function specified.'); } if (!$this->_tmpl->exists($tmpl)) { $tmpl = strtolower($tmpl); // try some autoloading magic $componentLocation = $this->_tmpl->getOption('componentFolder'); $componentExtension = $this->_tmpl->getOption('componentExtension'); $filename = $componentLocation . '/' . $tmpl . '.' . $componentExtension; $this->_tmpl->readTemplatesFromInput($filename); // still does not exist if (!$this->_tmpl->exists($tmpl)) { return patErrorManager::raiseError(PATTEMPLATE_FUNCTION_CALL_ERROR_NO_TEMPLATE, 'Template ' . $tmpl . ' does not exist'); } } /** * clear template and all of its dependencies */ $this->_tmpl->clearTemplate($tmpl, true); /** * add variables */ $this->_tmpl->addVars($tmpl, $params); $this->_tmpl->addVar($tmpl, 'CONTENT', $content); /** * get content */ return $this->_tmpl->getParsedTemplate($tmpl); }
/** * handle a variable * * @access private * @param array attributes of the var tag * @param string cdata between the tags (will be used as default) * @return boolean true on success */ function _handleVariable($attributes, $data) { if (!isset($attributes['name'])) { return patErrorManager::raiseError(PATTEMPLATE_READER_ERROR_NO_NAME_SPECIFIED, $this->_createErrorMessage('Variable needs a name attribute')); } $specs = array(); /** * get name */ $name = strtoupper($attributes['name']); unset($attributes['name']); $specs['name'] = $name; /** * use data as default value */ if (isset($attributes['default'])) { $data = $attributes['default']; $specs['default'] = $data; unset($attributes['default']); } else { if (!empty($data)) { $specs['default'] = $data; } } /** * add it to template, if it's not hidden */ if (!isset($attributes['hidden']) || $attributes['hidden'] == 'no') { $this->_characterData($this->_startTag . strtoupper($name) . $this->_endTag); } if (isset($attributes['hidden'])) { unset($attributes['hidden']); } /** * copy value from any other variable */ if (isset($attributes['copyfrom'])) { $specs['copyfrom'] = strtoupper($attributes['copyfrom']); if (strstr($specs['copyfrom'], '.')) { $specs['copyfrom'] = explode('.', $specs['copyfrom']); $specs['copyfrom'][0] = strtolower($specs['copyfrom'][0]); } unset($attributes['copyfrom']); } if (isset($attributes['modifier'])) { $modifier = $attributes['modifier']; unset($attributes['modifier']); $type = isset($attributes['modifiertype']) ? $attributes['modifiertype'] : 'auto'; if (isset($attributes['modifiertype'])) { unset($attributes['modifiertype']); } $specs['modifier'] = array('mod' => $modifier, 'type' => $type, 'params' => $attributes); } if (!empty($specs)) { $this->_addToParentTemplate('varspecs', $specs, $name); } }
/** * validates the current attribute collection according to the attributes definition * and the given output format, and returns the list of valid attributes. * * @access private * @param string $format The output format to retrieve the attributes for. * @return mixed $attributes The list of attributes, or false if failed. */ function getAttributesFor($format) { $attributes = array(); foreach ($this->attributeDefinition as $attributeName => $attributeDef) { if (!isset($this->attributes[$attributeName])) { if ($attributeDef["required"]) { return patErrorManager::raiseError(PATFORMS_ELEMENT_ERROR_ATTRIBUTE_REQUIRED, 'The element "' . $this->getElementName() . '" needs the attribute "' . $attributeName . '" to be set.', 'See the attribute definition of the element class "' . get_class($this) . '"'); } continue; } $attributeValue = $this->attributes[$attributeName]; // special case disabled attribute: skip this if it is not set to yes // to avoid generating a disabled field anyway (empty HTML attribute) if ($attributeName == 'disabled' && $attributeValue != 'yes') { continue; } if (isset($attributeDef["modifiers"]) && !empty($attributeDef["modifiers"])) { $modifiedValue = $this->_applyModifiers($attributeValue, $attributeDef["modifiers"]); if ($modifiedValue === false) { return patErrorManager::raiseError(PATFORMS_ELEMENT_ERROR_UNABLE_TO_APPLY_MODIFIER_TO_ATTRIBUTE, "Could not apply modifier to attribute '" . $attributeName . "' (value:'" . $attributeValue . "')"); } $attributeValue = $modifiedValue; // store this for later use too $this->attributes[$attributeName] = $attributeValue; } if (!in_array($format, $attributeDef["outputFormats"])) { continue; } if (isset($attributeDef["format"])) { if (!$this->_checkAttributeFormat($attributeValue, $attributeDef["format"])) { return patErrorManager::raiseError(PATFORMS_ELEMENT_ERROR_CAN_NOT_VERIFY_FORMAT, "Format '" . $attributeDef["format"] . "' could not be verified for attribute '" . $attributeName . "' => '" . $attributeValue . "'"); } } $attributes[$attributeName] = $attributeValue; } return $attributes; }
/** * write cache * * @access private * @param string $file filename * @param array $config configuration * @param array $externalFiles list of files used */ function writeCache($file, $config, $externalFiles) { $cacheData = serialize($config); $cacheFile = $this->cacheDir . '/' . md5($file) . '.cache'; $fp = @fopen($cacheFile, 'w'); if (!$fp) { return patErrorManager::raiseError(PATCONFIGURATION_ERROR_CACHEDIR_NOT_WRITEABLE, 'Could not write cache file in cache directory \'' . $this->cacheDir . '\'.'); } flock($fp, LOCK_EX); $cntFiles = count($externalFiles); for ($i = 0; $i < $cntFiles; $i++) { fputs($fp, "checkFile=" . $externalFiles[$i] . "\n"); } fputs($fp, "startCache=yes\n"); fwrite($fp, $cacheData); flock($fp, LOCK_UN); fclose($fp); $oldMask = umask(00); chmod($cacheFile, 0666); umask($oldMask); return true; }
/** * write a configfile * * * @access public * @param string $filename name of the configfile * @param string $format format of the config file * @param array $options options, see the writer driver for details */ function writeConfigFile($filename, $options = NULL, $oldOptions = NULL) { // older versions needed the filetype as secand parameter if (!is_array($options)) { $options = array('filetype' => $options); } // options had to be specified as third param prior to version 2.0 if (is_array($oldOptions)) { $options = array_merge($oldOptions, $options); } // no filetype given, extract from filename if (isset($options['filetype']) && !empty($options['filetype'])) { $filetype = $options['filetype']; } else { $filetype = $this->_getFiletype($filename); } $writer =& $this->_getDriver($filetype, 'Writer'); if (patErrorManager::isError($writer)) { return $writer; } // serialize the content $content = $writer->serializeConfig($this->conf, $options); if (patErrorManager::isError($content)) { return $content; } $file = $this->getFullPath($filename, NULL, false); if (patErrorManager::isError($file)) { return $file; } $fp = @fopen($file, 'w'); if (!$fp) { return patErrorManager::raiseError(PATCONFIGURATION_ERROR_FILE_NOT_WRITABLE, 'Could not write configuration to file [' . $file . '], file could not be opened.'); } flock($fp, LOCK_EX); fputs($fp, $content); flock($fp, LOCK_UN); fclose($fp); $oldMask = umask(00); chmod($file, 0666); umask($oldMask); return true; }