diff --git a/.gitignore b/.gitignore index 14bc68c..2120487 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -/nbproject/private/ \ No newline at end of file +/nbproject/private/ +/data/config/production/config.php +/_dev/ +/conlite/plugins/pluginmanager/_src/ \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/Util/Zip/Contenido_ArchiveExtractor.class.php b/conlite/plugins/pluginmanager/classes/Util/Zip/Contenido_ArchiveExtractor.class.php new file mode 100644 index 0000000..acbc065 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/Util/Zip/Contenido_ArchiveExtractor.class.php @@ -0,0 +1,212 @@ + + * @license http://www.contenido.org/license/LIZENZ.txt + * @link http://www.4fb.de + * @link http://www.contenido.org + * @since file available since contenido release 4.8.7 + * + * {@internal + * created 2008-06-06 + * modified 2008-07-03, Frederic Schneider, add security fix + * + * $Id: Contenido_ArchiveExtractor.class.php 7 2015-06-23 11:01:26Z oldperl $: + * }} + * + */ + +if(!defined('CON_FRAMEWORK')) { + die('Illegal call'); +} + +plugin_include('pluginmanager', 'classes/Exceptions/Contenido_ArchiveExtractor_Exception.php'); +//cInclude('pear', 'PHP/Archive.php'); +cInclude('pear', 'File/Archive.php'); + +class Contenido_ArchiveExtractor { + + /** + * The archive file + * @var string + */ + protected $sSource = ""; + + /** + * The destination path + * @var string + */ + protected $sDestination = ""; + + /** + * List of all files in the archive + * @var array + */ + protected $aFileList = array(); + + /** + * The absolute path + * @var string + */ + protected $sAbsPath = ""; + + /** + * Constructor of ArchiveExtractor, load the file list + * @access public + * @param string $sSource + * @return void + */ + public function __construct($sSource) { + global $cfg; + + $this->sSource = (string) $sSource; + + if (file_exists($sSource)) { + + $sTrailingSlash = substr($this->sSource, -1); + + if( $sTrailingSlash != DIRECTORY_SEPARATOR) { + $this->sSource = $this->sSource . DIRECTORY_SEPARATOR; + } + + // generate absolute path to the plugin manager directory + $this->sAbsPath = $cfg['path']['contenido'] . $cfg['path']['plugins'] . "pluginmanager" . DIRECTORY_SEPARATOR; + + $this->getFileList(); + + } else { + throw new Contenido_ArchiveExtractor_Exception("Source file does not exists"); + } + + } + + public function setErrorHandling($mode, $options) { + PEAR::setErrorHandling($mode, $options); // use temporary the error handler of PEAR + } + + /** + * Sets the path where the extractor extracts the archive files + * @access public + * @param string $sDestination + * @return void + */ + public function setDestinationPath($sDestination) { + + if (!is_dir($sDestination)) { + $bMakeDirectory = mkdir($sDestination, 0777); + + if ($bMakeDirectory != true) { + throw new Contenido_ArchiveExtractor_Exception("Can not set destination path: directoy is not writable"); + } + + $this->sDestination = (string) $sDestination; + + } else { + throw new Contenido_ArchiveExtractor_Exception("Destination already exists"); + } + + } + + /** + * Extracts the whole archive + * @access public + * @return void + */ + public function extractArchive() { + + if ($this->sDestination != "") { + File_Archive::extract($this->sSource, $this->sDestination); + } else { + throw new Contenido_ArchiveExtractor_Exception("Extraction failed: no destination path setted"); + } + + } + + /** + * Loads the file list of the archive + * @access public + * @return void + */ + public function getFileList(){ + $objArchiveReader = File_Archive::read($this->sSource); + $this->aFileList = $objArchiveReader->getFileList(); + } + + /** + * Extract only one specific file from archive + * @access public + * @param string $sFilename + * @return void + */ + public function extractArchiveFile($sFilename) { + + $sFilename = (string) $sFilename; + $sExtractFile = $this->sSource . $sFilename; + + if ($this->sDestination != "") { + File_Archive::extract($sExtractFile, $this->sDestination); + } else { + throw new Contenido_ArchiveExtractor_Exception("Extraction failed: no destination path setted"); + } + + } + + /** + * Returns the archives file list + * @access public + * @return array + */ + public function getArchiveFileList() { + return $this->aFileList; + } + + /** + * Checks if a specific file exists in archive + * @access public + * @param string $sFilename + * @return boolean + */ + public function existsInArchive($sFilename) { + + $aFileList = $this->getArchiveFileList(); + + if (in_array($sFilename, $aFileList)) { + $bFileCheck = true; + } else { + $bFileCheck = false; + } + + return $bFileCheck; + + } + + /** + * Extracts a specific file from archive and return its content to use it in a variable + * @access public + * @param string $sFilename + * @return string + */ + public function extractArchiveFileToVariable($sFilename) { + + $sFilename = (string) $sFilename; + $sExtractFile = $this->sSource . $sFilename; + + File_Archive::extract($sExtractFile, File_Archive::toVariable($sReturn)); + return $sReturn; + + } + +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/Util/Zip/class.pim.plugin.archive.extractor.php b/conlite/plugins/pluginmanager/classes/Util/Zip/class.pim.plugin.archive.extractor.php new file mode 100644 index 0000000..ad2c1a3 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/Util/Zip/class.pim.plugin.archive.extractor.php @@ -0,0 +1,143 @@ +_extractor = new ZipArchive(); + + // path to temp directory + $this->tempDir = $source; + + // temp directory with zip archive + $this->_source = (string) $source . (string) $filename; + + if (file_exists($source)) { + // generate absolute path to the plugin manager directory + $this->_absPath = $cfg['path']['contenido'] . $cfg['path']['plugins'] . 'pluginmanager' . DIRECTORY_SEPARATOR; + + // open the zip archive + $this->_extractor->open($this->_source); + } else { + throw new pimException('Source file does not exists'); + } + } + + public function closeArchive() { + $this->_extractor->close(); + } + + /** + * + * @param string $destination + * @throws pimException + */ + public function setDestinationPath($destination) { + if (!is_dir($destination)) { + $makeDirectory = mkdir($destination, 0777); + if ($makeDirectory != true) { + throw new pimException('Can not set destination path: directoy is not writable'); + } + $this->_destination = (string) $destination; + } else { + throw new pimException('Destination already exists'); + } + } + + /** + * + * @throws pimException + */ + public function extractArchive() { + if ($this->_destination != '') { + $this->_extractor->extractTo($this->_destination); + } else { + throw new pimException('Extraction failed: no destination path setted'); + } + } + + /** + * + * @param string $filename + * @param boolean $content + * @return type + */ + public function extractArchiveFileToVariable($filename, $content = true) { + $filename = (string) $filename; + $this->_extractor->extractTo($this->tempDir, $filename); + + if ($content) { + return file_get_contents($this->tempDir . $filename); + } else { + return $this->tempDir . $filename; + } + } + + /** + * + */ + public function destroyTempFiles() { + + // remove plugin.xml if exists + if (file_exists($this->tempDir . 'cl_plugin.xml')) { + unlink($this->tempDir . 'cl_plugin.xml'); + } + + // remove plugin_install.sql if exists + if (file_exists($this->tempDir . 'plugin_install.sql')) { + unlink($this->tempDir . 'plugin_install.sql'); + } + + // remove temporary plugin dir if exists + if (file_exists($this->_source)) { + unlink($this->_source); + } + } +} diff --git a/conlite/plugins/pluginmanager/classes/Util/class.pim.sql.parser.php b/conlite/plugins/pluginmanager/classes/Util/class.pim.sql.parser.php new file mode 100644 index 0000000..8616bef --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/Util/class.pim.sql.parser.php @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/class.pim.plugin.dummy.php b/conlite/plugins/pluginmanager/classes/class.pim.plugin.dummy.php new file mode 100644 index 0000000..20e0c8b --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/class.pim.plugin.dummy.php @@ -0,0 +1,34 @@ + \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/class.pim.plugin.handler.php b/conlite/plugins/pluginmanager/classes/class.pim.plugin.handler.php new file mode 100644 index 0000000..82e59e6 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/class.pim.plugin.handler.php @@ -0,0 +1,271 @@ +_oDomDocument = new DOMDocument(); + $this->_oDomDocument->preserveWhiteSpace = FALSE; + } + + /** + * + * @param int $iPluginId + * @return boolean + */ + public function loadPluginFromDb($iPluginId) { + $this->_oPlugin = new pimPlugin($iPluginId); + if ($this->_oPlugin->isLoaded()) { + $this->_iPluginId = $this->_oPlugin->get('idplugin'); + $this->_sPluginPath = cRegistry::getBackendPath() + . cRegistry::getConfigValue('path', 'plugins') + . $this->_oPlugin->get('folder') + . "/"; + return TRUE; + } + $this->_oPlugin = NULL; + return FALSE; + } + + /** + * + * @param string $sPluginFolderName + * @return boolean + */ + public function installPlugin($sPluginFolderName) { + $iNewPluginId = 0; + if (empty($sPluginFolderName)) { + return FALSE; + } + $pluginPath = cRegistry::getBackendPath() + . cRegistry::getConfigValue('path', 'plugins') + . $sPluginFolderName + . "/"; + + if (is_null($this->getCfgXmlObject())) { + $sPiCfg = $pluginPath . 'cl_plugin.xml'; + if (is_dir($pluginPath) && file_exists($sPiCfg)) { + $this->loadXmlFile($sPiCfg); + } else { + return FALSE; + } + } + + $oPluginInstaller = new pimSetupPluginInstall(); + $oPluginInstaller->setXsdFile($this->_xsd); + $oPluginInstaller->setXmlObject($this->getCfgXmlObject()); + $oPluginInstaller->setPluginPath($pluginPath); + $this->_iPluginId = $oPluginInstaller->installPlugin(); + if ($this->_iPluginId > 0) { + return TRUE; + } + return FALSE; + } + + /** + * + * @param string $sHandleSql + * @return boolean + */ + public function uninstallPlugin($sHandleSql) { + $oPluginUninstall = new pimSetupPluginUninstall(); + $oPluginUninstall->setPluginPath($this->_sPluginPath); + return $oPluginUninstall->uninstallPlugin($this->_iPluginId, $sHandleSql); + } + + /** + * + * @return int + */ + public function getPluginId() { + return $this->_iPluginId; + } + + /** + * + * @param string $sFile + * @return boolean + */ + public function loadXmlFile($sFile) { + $this->_oDomDocument->load($sFile); + if ($this->_validateXml()) { + $this->_oPiXml = simplexml_load_string($this->_oDomDocument->C14N()); + } + return (is_a($this->_oPiXml, "SimpleXMLElement")) ? TRUE : FALSE; + } + + /** + * + * @return object|null + */ + public function getCfgXmlObject() { + if (is_object($this->_oPiXml)) { + return $this->_oPiXml; + } + return NULL; + } + + /** + * + * @return array + */ + public function getPiGeneralArray() { + $aGeneral = array(); + if (is_object($this->_oPiXml)) { + $aGeneral = $this->_xml2Array($this->_oPiXml->general); + if($aDependencies = $this->_getDepencyArray()) { + foreach ($aDependencies as $aDependency) { + + } + } + $aGeneral['dependencies'] = print_r($aDependencies, TRUE); + } + return $aGeneral; + } + + /** + * Returns generated list entry (li) for plugin or empty string + * + * @param int $iPluginId + * @return string + */ + public function getInfoInstalled($iPluginId) { + $oPlugin = new pimPlugin($iPluginId); + if ($oPlugin->isLoaded()) { + $oView = new pimView(); + $oView->setMultiVariables($oPlugin->toArray()); + $aLang = array( + 'LANG_FOLDERNAME' => i18n("Foldername", "pluginmanager"), + 'LANG_AUTHOR' => i18n("Author", "pluginmanager"), + 'LANG_CONTACT' => i18n("Contact", "pluginmanager"), + 'LANG_LICENSE' => i18n("License", "pluginmanager"), + 'LANG_INSTALLED' => i18n('Installed since', 'pluginmanager'), + 'LANG_DEPENDENCIES' => i18n("Dependencies", "pluginmanager"), + 'LANG_WRITEABLE' => i18n("Writable", "pluginmanager"), + 'LANG_INSTALL' => i18n("Install", "pluginmanager"), + 'LANG_REMOVE' => i18n("Remove", "pluginmanager"), + 'LANG_UPDATE' => i18n('Update', 'pluginmanager'), + 'LANG_UPDATE_CHOOSE' => i18n('Please choose your new file', 'pluginmanager'), + 'LANG_UPDATE_UPLOAD' => i18n('Update', 'pluginmanager'), + 'LANG_REMOVE_SQL' => i18n('Execute uninstall.sql', 'pluginmanager') + ); + $oView->setMultiVariables($aLang); + // nav sub placeholder, @Todo: fill with content + $oView->set('s', 'NAVSUB', ''); + // enable / disable functionality + $activeStatus = $oPlugin->get('active'); + $oButton = new cHTMLButton('toggle_active'); + $oButton->setID("but-toggle-plugin-" . $oPlugin->get("idplugin")); + $oButton->setClass("pimImgBut"); + $oButton->setMode('image'); + $oButtonLabel = new cHTMLLabel("placeholder", $oButton->getID()); + $oButtonLabel->setClass("pimButLabel"); + if ($activeStatus == 1) { + $oButton->setAlt("Click to toggle status"); + $oButton->setImageSource('images/online.gif'); + $oButtonLabel->setLabelText(i18n("Plugin is active", "pluginmanager")); + } else { + $oButton->setImageSource('images/offline.gif'); + $oButtonLabel->setLabelText(i18n("Plugin not active", "pluginmanager")); + } + $oView->set('s', 'BUT_ACTIVESTATUS', $oButton->render() . ' ' . $oButtonLabel->render()); + + // update button - not used right now + $oView->set('s', 'BUT_UPDATE_PLUGIN', ''); + + // uninstall + $oDelBut = new cHTMLButton('uninstall_plugin'); + $oDelBut->setImageSource('images/but_cancel.gif'); + $oDelBut->setID("but-uninstall-plugin-" . $oPlugin->get("idplugin")); + $oDelBut->setClass("pimImgBut"); + $oDelBut->setMode('image'); + $oDelSqlCheckbox = new cHTMLCheckbox("delete_sql", "TRUE"); + $oDelSqlCheckbox->setStyle("display: inline-block;"); + $sDelSqlTxt = " " . sprintf(i18n("(%s remove database tables)", "pluginmanager"), $oDelSqlCheckbox->toHtml(FALSE)); + $oDelButLabel = new cHTMLLabel("placeholder", $oDelBut->getID()); + $oDelButLabel->setClass("pimButLabel"); + $oDelButLabel->setLabelText(i18n("Uninstall Plugin", "pluginmanager") . $sDelSqlTxt); + $oView->set('s', 'BUT_UNINSTALL_PLUGIN', $oDelBut->render() . ' ' . $oDelButLabel->render()); + + $oView->setTemplate('pi_manager_installed_plugins.html'); + return $oView->getRendered(1); + } + return ''; + } + + protected function _getDepencyArray() { + $aDependencies = array(); + $aAttributes = array(); + $iCountDependencies = count($this->_oPiXml->dependencies); + if($iCountDependencies > 0) { + for ($i = 0; $i < $iCountDependencies; $i++) { + $sPluginName = cSecurity::escapeString($this->_oPiXml->dependencies[$i]->depend); + foreach ($this->_oPiXml->dependencies[$i]->depend->attributes() as $sKey => $sValue) { + $aAttributes[$sKey] = cSecurity::escapeString($sValue); + } + $aDependencies[$i]["name"] = $sPluginName; + $aDependencies[$i] = array_merge($aDependencies[$i],$aAttributes); + } + return $aDependencies; + } + + return FALSE; + } + + /** + * + * @return boolean + * @throws pimXmlStructureException + */ + private function _validateXml() { + if ($this->_oDomDocument->schemaValidate($this->_xsd)) { + $this->_bValid = true; + return true; + } else { + return FALSE; + } + } + + /** + * + * @param xml $xml + * @return array + */ + private function _xml2Array($xml) { + $string = json_encode($xml); + $array = json_decode($string, true); + return $array; + } + +} diff --git a/conlite/plugins/pluginmanager/classes/class.pim.plugin.php b/conlite/plugins/pluginmanager/classes/class.pim.plugin.php new file mode 100644 index 0000000..2ab1531 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/class.pim.plugin.php @@ -0,0 +1,34 @@ + + */ +class pimPluginCollection extends ItemCollection { + + public function __construct() { + global $cfg; + parent::__construct($cfg['tab']['plugins'], 'idplugin'); + $this->_setItemClass("pimPlugin"); + } +} + +class pimPlugin extends Item { + + public function __construct($mId = false) { + global $cfg; + parent::__construct($cfg['tab']['plugins'], 'idplugin'); + + if ($mId !== false) { + $this->loadByPrimaryKey($mId); + } + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/class.pim.plugin.relation.php b/conlite/plugins/pluginmanager/classes/class.pim.plugin.relation.php new file mode 100644 index 0000000..fe37081 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/class.pim.plugin.relation.php @@ -0,0 +1,58 @@ + + */ +class pimPluginRelationCollection extends ItemCollection { + + const REL_AREA = 'area'; + const REL_ACTION = 'action'; + const REL_NAVS = 'navs'; + const REL_CTYPE = 'ctype'; + + public function __construct() { + global $cfg; + parent::__construct($cfg['tab']['plugins_rel'], 'idpluginrelation'); + $this->_setItemClass("pimPluginRelation"); + } + + public function create($idItem, $idPlugin, $type) { + // create a new entry + $item = parent::create(); + $item->set('iditem', $idItem); + $item->set('idplugin', $idPlugin); + $item->set('type', $type); + + $item->store(); + return $item; + } + + public function getRelations($idPlugin, $type=NULL) { + return; + } + + public function deleteRelations($idPlugin, $type=NULL) { + return; + } +} + +class pimPluginRelation extends Item { + + public function __construct($mId = false) { + global $cfg; + parent::__construct($cfg['tab']['plugins_rel'], 'idpluginrelation'); + + if ($mId !== false) { + $this->loadByPrimaryKey($mId); + } + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/class.pim.view.php b/conlite/plugins/pluginmanager/classes/class.pim.view.php new file mode 100644 index 0000000..9c3183c --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/class.pim.view.php @@ -0,0 +1,83 @@ + + * @license http://www.contenido.org/license/LIZENZ.txt + * @link http://www.4fb.de + * @link http://www.contenido.org + * @since file available since contenido release 4.8.7 + * + * {@internal + * created 2008-03-17 + * modified 2008-07-04, Frederic Schneider, add security fix and tpl settings + * + * $Id: class.pim.view.php 11 2015-07-14 12:34:24Z oldperl $: + * }} + * + */ + +if(!defined('CON_FRAMEWORK')) { + die('Illegal call'); +} + +class pimView extends Template{ + + protected $sPathToTpl; + protected $bIsGenerated; + protected $_sTplPath; + + public function __construct($tags = false, $parser = false) { + $this->reset(); + $this->set('s', 'SESSID', cRegistry::getSessionId()); + $this->bIsGenerated = false; + $this->_sTplPath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR."templates".DIRECTORY_SEPARATOR; + parent::__construct($tags, $parser); + } + + public function setTemplate($sTplName) { + $this->sPathToTpl = $this->_sTplPath.$sTplName; + } + + public function setMultiVariables($aVariables) { + if(is_array($aVariables)) { + foreach($aVariables as $sName=>$sContent) { + if(is_numeric($sName)) { + continue; + } + $this->setVariable($sContent, strtoupper($sName)); + } + } + } + + public function setVariable($sVariable, $sName = '') { + if(empty($sName)) { + $sName = strtoupper($$sVariable); + } + $this->set('s', $sName, $sVariable); + } + + public function getRendered($mode = '') { + $this->bIsGenerated = true; + return $this->generate($this->sPathToTpl, $mode); + } + + public function __destruct() { + if ($this->bIsGenerated === false) { + $this->generate($this->sPathToTpl, true, false); + } + } + +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/class.pluginmanager.ajax.php b/conlite/plugins/pluginmanager/classes/class.pluginmanager.ajax.php new file mode 100644 index 0000000..99239b0 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/class.pluginmanager.ajax.php @@ -0,0 +1,104 @@ +isLoaded()) { + $iCurrentStat = (int) $oPlugin->get('active'); + $iNewStat = ($iCurrentStat == 1)?0:1; + $oPlugin->set('active', $iNewStat); + if($oPlugin->store()) { + $sString = "Ok:".$iNewStat; + if($iNewStat) { + $sString .= ":".i18n("Plugin is active", "pluginmanager"); + } else { + $sString .= ":".i18n("Plugin not active", "pluginmanager"); + } + break; + } + } + $sString = "Error:no changes! (Err21)"; + break; + + // save sortorder of plugins + case 'pim_save_sort': + parse_str($_REQUEST['plugins'], $aPlugins); + //print_r($aPlugins['plugin']); + if(is_array($aPlugins['plugin']) && count($aPlugins['plugin']) > 0) { + foreach($aPlugins['plugin'] as $sortorder=>$pluginid) { + $oPlugin = new pimPlugin($pluginid); + $oPlugin->set('executionorder', $sortorder); + $oPlugin->store(); + } + } + $sString = "Ok:executionorder saved"; + break; + + // install plugin with existing source in plugin dir + case 'pim_install': + //sleep(3); + $iNewPluginId = 0; + $sPluginPath = cRegistry::getBackendPath() + .cRegistry::getConfigValue('path', 'plugins') + .Contenido_Security::escapeDB($_POST['plugin_folder']).DIRECTORY_SEPARATOR; + + if(is_dir($sPluginPath) && is_readable($sPluginPath."cl_plugin.xml")) { + $oPluginHandler = new pimPluginHandler(); + if($oPluginHandler->loadXmlFile($sPluginPath."cl_plugin.xml")) { + if($oPluginHandler->installPlugin(Contenido_Security::escapeDB($_POST['plugin_folder']))) { + $iNewPluginId = $oPluginHandler->getPluginId(); + if($iNewPluginId > 0) { + $sString = "Ok:".$iNewPluginId.":Plugin successfully installed!"; + } else { + $sString = "Error:".$iNewPluginId.":Plugin not installed! (Err10)"; + } + } else { + $sString = "Error:0:Plugin not installed! (Err12)"; + } + } else { + $sString = "Error:0:Plugin xml-file missing or not correct! (Err13)"; + } + break; + } + $sString = "Error:0:Plugin folder missing or no readable xml-file found! (Err14)"; + break; + + // return info about installed plugin + case 'pim_get_info_installed': + $oPluginHandler = new pimPluginHandler(); + $sString = $oPluginHandler->getInfoInstalled((int) $_POST['plugin_id']); + break; + + //if action is unknown generate error message + default: + $sString = "Unknown Ajax Action! (Err01)"; + break; + } + return $sString; + } + +} diff --git a/conlite/plugins/pluginmanager/classes/exeptions/class.pim.exeption.php b/conlite/plugins/pluginmanager/classes/exeptions/class.pim.exeption.php new file mode 100644 index 0000000..76397ad --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/exeptions/class.pim.exeption.php @@ -0,0 +1,46 @@ + cRegistry::getConfigValue('path', 'data') + . 'logs/exception.log' + )); + $this->_logger = new cLog($writer); + + // determine if exception should be logged + if (false === $this->_log_exception + && !is_null(cRegistry::getConfigValue('debug', 'log_exeptions'))) { + $this->_log_exception = cRegistry::getConfigValue('debug', 'log_exeptions'); + } + + // log the exception if it should be logged + if (true === $this->_log_exception) { + $this->log(); + } + } + + public function log() { + // construct the log message with all infos and write it via the logger + $logMessage = get_class($this) . ' thrown at line ' . $this->getLine() . ' of file ' . $this->getFile() . ".\r\n"; + $logMessage .= 'Exception message: ' . $this->getMessage() . "\r\n"; + $logMessage .= "Call stack:\r\n"; + $logMessage .= $this->getTraceAsString(); + $logMessage .= "\r\n"; + $this->_logger->log($logMessage); + } +} + +class pimXmlStructureException extends pimExeption { + +} \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/classes/plugin/class.plugin.handler.abstract.php b/conlite/plugins/pluginmanager/classes/plugin/class.plugin.handler.abstract.php new file mode 100644 index 0000000..28be1a8 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/plugin/class.plugin.handler.abstract.php @@ -0,0 +1,67 @@ +getFileName())); + } + return self::$_piPath; + } +} diff --git a/conlite/plugins/pluginmanager/classes/plugin/interface.plugins.php b/conlite/plugins/pluginmanager/classes/plugin/interface.plugins.php new file mode 100644 index 0000000..1e8fb24 --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/plugin/interface.plugins.php @@ -0,0 +1,19 @@ + 'idaction', + 'area' => 'idarea', + 'files' => 'idfile', + 'framefiles' => 'idframefile', + 'nav_main' => 'idnavm', + 'nav_sub' => 'idnavs', + 'plugins' => 'idplugin' + ); + + /** + * holds db object + * @var DB_ConLite + */ + protected $_oDb; + protected $_aSql = array(); + protected $_iPiId = 0; + protected $_iCntQueries = 0; + protected $_iClient; + protected $_aRelations; + + /** + * + * @var pimPluginCollection + */ + protected $_PimPluginCollection; + + /** + * + * @var pimPluginRelationCollection + */ + protected $_PimPluginRelationCollection; + protected $_sPluginPath; + + public function __construct() { + $this->_oDb = new DB_ConLite(); + $this->_iClient = cRegistry::getClientId(); + $this->_xmlParseIntoStruct(); + + $this->_PimPluginCollection = new pimPluginCollection(); + $this->_PimPluginRelationCollection = new pimPluginRelationCollection(); + + //print_r($this->_getAttrForTag("area")); + } + + public function setPluginPath($sPath) { + $this->_sPluginPath = $sPath; + } + + public function getPluginPath() { + return $this->_sPluginPath; + } + + /** + * + * @return boolean + */ + public function doQueries() { + if (!is_array($this->_aSql) || count($this->_aSql) <= 0) { + return TRUE; + } + $iQueries = count($this->_aSql); + + if ($iQueries > 0 && is_a($this->_oDb, "DB_ConLite")) { + foreach ($this->_aSql as $sSql) { + try { + $this->_oDb->query($sSql); + } catch (Exception $exc) { + self::error($exc->getTraceAsString()); + } + $this->_iCntQueries++; + } + if ($iQueries == $this->_iCntQueries) { + return TRUE; + } + } + return FALSE; + } + + public function undoQueries() { + + } + + public function setXmlObject($oXml, $bSplit = TRUE) { + if (is_object($oXml)) { + $this->_oXml = & $oXml; + } + + if ($bSplit) { + $this->_setXml(); + } + } + + public function setXsdFile($sFile) { + $this->_sXsdPath = $sFile; + } + + /** + * Returns next id for given table + * + * @param string $sTable + * @return int the next usable table id + */ + protected function _getNextId($sTable) { + cInclude("includes", "functions.database.php"); + dbUpdateSequence(cRegistry::getConfigValue("tab", "sequence"), cRegistry::getConfigValue('tab', $sTable), cRegistry::getDb()); + + $iNextId = $this->_oDb->nextid(cRegistry::getConfigValue('tab', $sTable)); + // id must be over 10.000 + if ($iNextId < 10000) { + $iNextId = 10000; + } + + // added ten + $iNextId = $iNextId + 10; + + // how long is the number? + $iResultStrlen = strlen($iNextId); + + // removed the last number + $iNextId = substr($iNextId, 0, $iResultStrlen - 1); + + return Contenido_Security::toInteger($iNextId . 0); // last number is always a zero + } + + protected function _getAttrForTag($sTag) { + foreach ($this->_aXmlDefaultValues as $Key => $aValue) { + if ($aValue['tag'] === strtoupper($sTag) && $aValue['type'] === "complete") { + if (isset($aValue['attributes']) && is_array($aValue['attributes'])) { + return array_change_key_case($aValue['attributes']); + } + } + } + return FALSE; + } + + protected function _getPluginSql() { + $sSqlFile = $this->_sPluginPath . static::SQL_FILE; + if (file_exists($sSqlFile) && is_readable($sSqlFile)) { + $this->_aSql = pimSqlParser::parse(file_get_contents($sSqlFile)); + } else if (!is_array($this->_aSql)) { + $this->_aSql = array(); + } + } + + protected static function error($sMessage, $iPiId = NULL) { + if (!is_null($iPiId)) { + $oUnInstall = new pimSetupPluginUninstall(); + $oUnInstall->uninstallPlugin($iPiId, ''); + } + print "Error:0:" . $sMessage; + die(); + } + + protected function _getRelations() { + $aTmpArray = array(); + $this->_PimPluginRelationCollection->setWhere('idplugin', $this->_iPiId); + $this->_PimPluginRelationCollection->query(); + if ($this->_PimPluginRelationCollection->count() > 0) { + while ($oPluginRelation = $this->_PimPluginRelationCollection->next()) { + if (isset($aTmpArray[$oPluginRelation->get('type')]) && is_array($aTmpArray[$oPluginRelation->get('type')])) { + array_push($aTmpArray[$oPluginRelation->get('type')], $oPluginRelation->get('iditem')); + } else { + $aTmpArray[$oPluginRelation->get('type')] = array($oPluginRelation->get('iditem')); + } + } + $this->_aRelations = $aTmpArray; + unset($aTmpArray); + } + } + + protected function _deleteRelations() { + $iDeletetRelations = $this->_PimPluginRelationCollection->deleteByWhereClause("idplugin = " . $this->_iPiId); + } + + protected function _deleteRelationEntries() { + $oDb = new DB_ConLite(); + foreach ($this->_aRelations as $sType => $aIds) { + $sSQL = 'DELETE FROM ' . cRegistry::getConfigValue('tab', $sType) . ' WHERE ' . $this->_aTables[$sType] . ' IN (' . implode(',', $aIds) . ')'; + if ($oDb->query($sSQL) == FALSE) { + return FALSE; + } + } + unset($oDb); + return TRUE; + } + + protected function _updateSortOrder() { + if(!isset($_REQUEST['new_position'])) { + return 0; + } + + $oPluginColl = new pimPluginCollection(); + $oPluginColl->setWhere("executionorder", (int) $_REQUEST['new_position'], ">="); + $oPluginColl->query(); + if($oPluginColl->count() > 0) { + /* @var $oPlugin cApiPlugin */ + while ($oPlugin = $oPluginColl->next()) { + $iOrder = $oPlugin->get("executionorder"); + $oPlugin->set("executionorder", $iOrder++); + $oPlugin->store(); + } + } + return (int) $_REQUEST['new_position']; + } + + /** + * Set temporary xml content to static variables + * + * @param string $xml + */ + private function _setXml() { + //simplexml_tree($this->_oXml); + // General plugin informations + self::$XmlGeneral = $this->_oXml->general; + + // Plugin requirements + self::$XmlRequirements = $this->_oXml->requirements; + + // Plugin dependencies + self::$XmlDependencies = $this->_oXml->dependencies; + + // CONTENIDO areas: *_area + self::$XmlArea = $this->_oXml->conlite->areas; + + // CONTENIDO actions: *_actions + self::$XmlActions = $this->_oXml->conlite->actions; + + // CONTENIDO frames: *_frame_files and *_files + self::$XmlFrames = $this->_oXml->conlite->frames; + + // CONTENIDO main navigations: *_nav_main + self::$XmlNavMain = $this->_oXml->conlite->nav_main; + + // CONTENIDO sub navigations: *_nav_sub + self::$XmlNavSub = $this->_oXml->conlite->nav_sub; + + // CONTENIDO Content Types: *_type + self::$XmlContentType = $this->_oXml->content_types; + } + + private function _xmlParseIntoStruct() { + $sData = implode("", file($this->_xmlDefault)); + $oParser = xml_parser_create(); + xml_parse_into_struct($oParser, $sData, $this->_aXmlDefaultValues, $this->_aXmlDefaultIndex); + xml_parser_free($oParser); + } + + private function _updateSequence($table = false) { + global $db, $cfg; + if (!$table) { + $sql = "SHOW TABLES"; + $db->query($sql); + while ($db->next_record()) { + dbUpdateSequence($cfg['sql']['sqlprefix'] . "_sequence", $db->f(0)); + } + } else { + dbUpdateSequence($cfg['sql']['sqlprefix'] . "_sequence", $table); + } + } +} diff --git a/conlite/plugins/pluginmanager/classes/setup/class.pim.setup.plugin.install.php b/conlite/plugins/pluginmanager/classes/setup/class.pim.setup.plugin.install.php new file mode 100644 index 0000000..64db36b --- /dev/null +++ b/conlite/plugins/pluginmanager/classes/setup/class.pim.setup.plugin.install.php @@ -0,0 +1,427 @@ +_initInstalledAreasArray(); + } + + public function installPlugin() { + if (is_null($this->_oXml)) { + cWarning(__FILE__, __LINE__, "installPlugin: No plugin xml loaded!"); + return 0; + } + $this->_installCheckUuid(); + $this->_installCheckRequirements(); + + $oPiColl = new pimPluginCollection(); + $this->_oPlugin = $oPiColl->createNewItem(); + if ($this->_oPlugin->isLoaded()) { + $this->_iPiId = $this->_oPlugin->get('idplugin'); + $this->_insertDbEntries(); + $this->_getPluginSql(); + if ($this->doQueries()) { + $this->_oPlugin->set('idclient', $this->_iClient, FALSE); + $this->_oPlugin->set('name', Contenido_Security::escapeDB(self::$XmlGeneral->plugin_name)); + $this->_oPlugin->set('description', Contenido_Security::escapeDB(self::$XmlGeneral->description)); + $this->_oPlugin->set('author', Contenido_Security::escapeDB(self::$XmlGeneral->author)); + $this->_oPlugin->set('copyright', Contenido_Security::escapeDB(self::$XmlGeneral->copyright)); + $this->_oPlugin->set('mail', Contenido_Security::escapeDB(self::$XmlGeneral->mail)); + $this->_oPlugin->set('website', Contenido_Security::escapeDB(self::$XmlGeneral->website)); + $this->_oPlugin->set('version', Contenido_Security::escapeDB(self::$XmlGeneral->version)); + $this->_oPlugin->set('folder', Contenido_Security::escapeDB(self::$XmlGeneral->plugin_foldername)); + $this->_oPlugin->set('uuid', Contenido_Security::escapeDB(self::$XmlGeneral->uuid)); + $this->_oPlugin->set('executionorder', $this->_updateSortOrder(), FALSE); + $this->_oPlugin->set('installed', date('Y-m-d H:i:s'), FALSE); + $this->_oPlugin->set('active', (int) self::$XmlGeneral['active'], FALSE); + + if ($this->_oPlugin->store()) { + //echo "stored: ".$this->_iPiId; + return $this->_iPiId; + } + } else { + $this->_removeEmptyPlugin(); + } + } + // something went wrong, return 0 + return 0; + } + + protected function _insertDbEntries() { + $this->_addAreas(); + $this->_addActions(); + $this->_addFrames(); + $this->_addNavMain(); + $this->_addNavSub(); + } + + protected function _addRelation($iIdItem, $sType) { + $oPluginRelation = $this->_PimPluginRelationCollection->createNewItem(); + $oPluginRelation->set('iditem', $iIdItem, FALSE); + $oPluginRelation->set('idplugin', $this->_iPiId, FALSE); + $oPluginRelation->set('type', $sType); + $oPluginRelation->store(); + unset($oPluginRelation); + } + + private function _addAreas() { + $aAttributes = array(); + $aDefaultAttr = array( + 'menuless' => 0, + 'parent' => 0, + 'relevant' => 1 + ); + + $iCountAreas = count(self::$XmlArea->area); + if ($iCountAreas > 0) { + $oAreaColl = new cApiAreaCollection(); + for ($i = 0; $i < $iCountAreas; $i++) { + $sName = Contenido_Security::escapeDB(self::$XmlArea->area[$i], $this->oDb); + // build attributes + foreach (self::$XmlArea->area[$i]->attributes() as $sKey => $sValue) { + $aAttributes[$sKey] = (string) $sValue; + } + $aAttributes = array_merge($aDefaultAttr, $aAttributes); + /* @var $oArea cApiArea */ + $oArea = $oAreaColl->createNewItem($this->_getNextId("area")); + $oArea->set('parent_id', Contenido_Security::escapeDB($aAttributes['parent'], $this->oDb)); + $oArea->set('name', $sName); + $oArea->set('menuless', Contenido_Security::toInteger($aAttributes['menuless'])); + $oArea->set('relevant', 1, FALSE); + $oArea->set('online', 1, FALSE); + if ($oArea->store()) { + $iIdItem = $oArea->get($oArea->primaryKey); + $this->_aAreas[$sName] = $iIdItem; + $this->_aInstalledAreas[] = $sName; + $this->_addRelation($iIdItem, 'area'); + } + } + } + } + + private function _addActions() { + $aAttributes = array(); + $aDefaultAttr = array( + 'relevant' => 1 + ); + + $iCountActions = count(self::$XmlActions->action); + if ($iCountActions > 0) { + $oActionColl = new cApiActionCollection(); + for ($i = 0; $i < $iCountActions; $i++) { + $sName = Contenido_Security::escapeDB(self::$XmlActions->action[$i], $this->_oDb); + foreach (self::$XmlActions->action[$i]->attributes() as $sKey => $sValue) { + $aAttributes[$sKey] = cSecurity::escapeString($sValue); + } + $aAttributes = array_merge($aDefaultAttr, array_filter($aAttributes)); + if (!in_array($aAttributes['area'], $this->_aInstalledAreas)) { + parent::error(sprintf(i18n('Defined area %s are not found on your ConLite installation. Please contact your plugin author.', 'pluginmanager'), $aAttributes['area'])); + } + /* @var $oAction cApiAction */ + $oAction = $oActionColl->createNewItem($this->_getNextId("actions")); + if ($oAction->isLoaded()) { + $oAction->set("idarea", $this->_getIdForArea($aAttributes['area'])); + $oAction->set("name", $sName); + $oAction->set("code", ''); + $oAction->set("location", ''); + $oAction->set("relevant", (int) $aAttributes['relevant']); + if ($oAction->store()) { + $this->_addRelation($oAction->get('idaction'), 'actions'); + } + } + //$oAction = $oActionColl->create($aAttributes['area'], $sName, '', '', $aAttributes['relevant']); + //$this->_addRelation($oAction->get('idaction'), 'actions'); + } + unset($oActionColl); + unset($oAction); + } + } + + private function _addFrames() { + $aAttributes = array(); + $aDefaultAttr = array(); + + $iCountFrames = count(self::$XmlFrames->frame); + if ($iCountFrames > 0) { + $oFrameFileColl = new cApiFrameFileCollection(); + $oFileColl = new cApiFileCollection(); + + for ($i = 0; $i < $iCountFrames; $i++) { + // Build attributes with security checks + foreach (self::$XmlFrames->frame[$i]->attributes() as $sKey => $sValue) { + $aAttributes[$sKey] = cSecurity::escapeString($sValue); + } + $aAttributes = array_merge($aDefaultAttr, array_filter($aAttributes)); + + // Check for valid area + if (!array_key_exists($aAttributes['area'], $this->_aAreas) && !in_array($aAttributes['area'], $this->_aInstalledAreas)) { + parent::error(sprintf(i18n('Defined area %s are not found on your ConLite installation. Please contact your plugin author.', 'pluginmanager'), $aAttributes['area'])); + } + + /* @var $oFile cApiFile */ + $oFile = $oFileColl->createNewItem($this->_getNextId("files")); + if ($oFile->isLoaded()) { + $this->_addRelation($oFile->get('idfile'), 'files'); + + $oFile->set("idarea", $this->_getIdForArea($aAttributes['area'])); + $oFile->set("filename", $aAttributes['name']); + $oFile->set("filetype", cSecurity::escapeString($aAttributes['filetype'])); + + if ($oFile->store()) { + if (!empty($aAttributes['frameId'])) { + /* @var $oFrameFile cApiFrameFile */ + $oFrameFile = $oFrameFileColl->createNewItem($this->_getNextId("framefiles")); + if ($oFrameFile->isLoaded()) { + $this->_addRelation($oFrameFile->get('idframefile'), 'framefiles'); + + $oFrameFile->set("idarea", $this->_getIdForArea($aAttributes['area'])); + $oFrameFile->set("idframe", (int) $aAttributes['frameId'], FALSE); + $oFrameFile->set("idfile", (int) $oFile->get('idfile'), FALSE); + + $oFrameFile->store(); + } + } + } + } + } + unset($oFrameFileColl); + unset($oFileColl); + unset($oFile); + unset($oFrameFile); + } + } + + private function _addNavMain() { + $aAttributes = array(); + + $iCountNavMain = count(self::$XmlNavMain->nav); + if ($iCountNavMain > 0) { + $oNavMainColl = new cApiNavMainCollection(); + + for ($i = 0; $i < $iCountNavMain; $i++) { + $sLocation = cSecurity::escapeString(self::$XmlNavMain->nav[$i]); + if (empty($sLocation)) { + parent::error(i18n('There seem to be an empty main navigation entry in plugin.xml. Please contact your plugin author.', 'pluginmanager'), $this->_iPiId); + } + + // Build attributes with security checks + foreach (self::$XmlNavMain->nav[$i]->attributes() as $sKey => $sValue) { + $aAttributes[$sKey] = cSecurity::escapeString($sValue); + } + + /* @var $oNavMain cApiNavMain */ + $oNavMain = $oNavMainColl->createNewItem($this->_getNextId("nav_main")); + if($oNavMain->isLoaded()) { + $this->_addRelation($oNavMain->get('idnavm'), 'nav_main'); + + $oNavMain->set("location", $sLocation, FALSE); + $oNavMain->set("name", cSecurity::escapeString($aAttributes['name'])); + + $oNavMain->store(); + } + } + unset($oNavMainColl); + unset($oNavMain); + } + } + + private function _addNavSub() { + $aAttributes = array(); + $this->_initInstalledNavMainArray(); + $iCountNavSub = count(self::$XmlNavSub->nav); + + if ($iCountNavSub > 0) { + $oNavSubColl = new cApiNavSubCollection(); + + for ($i = 0; $i < $iCountNavSub; $i++) { + $sLocation = cSecurity::escapeString(self::$XmlNavSub->nav[$i]); + + if (empty($sLocation)) { + parent::error(i18n('There seem to be an empty sub navigation entry in plugin.xml. Please contact your plugin author.', 'pluginmanager'), $this->_iPiId); + } + + // Build attributes with security checks + foreach (self::$XmlNavSub->nav[$i]->attributes() as $sKey => $sValue) { + $aAttributes[$sKey] = cSecurity::escapeString($sValue); + } + /* @var $oNavSub cApiNavSub */ + $oNavSub = $oNavSubColl->createNewItem($this->_getNextId("nav_sub")); + if ($oNavSub->isLoaded()) { + $this->_addRelation($oNavSub->get('idnavs'), 'nav_sub'); + + $oNavSub->set("idnavm", $this->_getIdForNavMain($aAttributes['navm'])); + $oNavSub->set("idarea", $this->_getIdForArea($aAttributes['area'])); + $oNavSub->set("level", (int) $aAttributes['level']); + $oNavSub->set("location", $sLocation, FALSE); + $oNavSub->set("online", 1, FALSE); + + $oNavSub->store(); + } + } + unset($oNavSubColl); + unset($oNavSub); + } + } + + private function _removeEmptyPlugin() { + if (empty($this->_iPiId)) { + return FALSE; + } + $this->_getRelations(); + if (count($this->_aRelations) > 0) { + $this->_deleteRelationEntries(); + $this->_deleteRelations(); + } + $this->_PimPluginCollection->delete($this->_iPiId); + } + + /** + * Check uuId: You can install a plugin only for one time + */ + private function _installCheckUuid() { + $this->_PimPluginCollection->setWhere('uuid', self::$XmlGeneral->uuid); + $this->_PimPluginCollection->query(); + if ($this->_PimPluginCollection->count() > 0) { + parent::error(i18n('You can install this plugin only for one time.', 'pluginmanager')); + } + } + + private function _installCheckRequirements() { + + // Check min ConLite version + if (version_compare(CL_VERSION, self::$XmlRequirements->conlite->attributes()->minversion, '<')) { + parent::error(sprintf(i18n('You have to install ConLite %s or higher to install this plugin!', 'pluginmanager'), self::$XmlRequirements->conlite->attributes()->minversion)); + } + + // Check max ConLite version + if (self::$XmlRequirements->conlite->attributes()->maxversion) { + if (version_compare(CL_VERSION, self::$XmlRequirements->conlite->attributes()->maxversion, '>')) { + parent::error(sprintf(i18n('Your current ConLite version is to new - max ConLite version %s', 'pluginmanager'), self::$XmlRequirements->conlite->attributes()->maxversion)); + } + } + + // Check PHP version + if (version_compare(phpversion(), self::$XmlRequirements->attributes()->php, '<')) { + parent::error(sprintf(i18n('You have to install PHP %s or higher to install this plugin!', 'pluginmanager'), self::$XmlRequirements->attributes()->php)); + } + + /* @todo check and implement other requirement checks + // Check extensions + if (count(parent::$XmlRequirements->extension) != 0) { + + for ($i = 0; $i < count(parent::$XmlRequirements->extension); $i++) { + + if (!extension_loaded(parent::$XmlRequirements->extension[$i]->attributes()->name)) { + parent::error(sprintf(i18n('The plugin could not find the PHP extension %s. Because this is required by the plugin, it can not be installed.', 'pim'), parent::$XmlRequirements->extension[$i]->attributes()->name)); + } + } + } + + // Check classes + if (count(parent::$XmlRequirements->class) != 0) { + + for ($i = 0; $i < count(parent::$XmlRequirements->class); $i++) { + + if (!class_exists(parent::$XmlRequirements->class[$i]->attributes()->name)) { + parent::error(sprintf(i18n('The plugin could not find the class %s. Because this is required by the plugin, it can not be installed.', 'pim'), parent::$XmlRequirements->class[$i]->attributes()->name)); + } + } + } + + // Check functions + if (count(parent::$XmlRequirements->function) != 0) { + + for ($i = 0; $i < count(parent::$XmlRequirements->function); $i++) { + + if (!function_exists(parent::$XmlRequirements->function[$i]->attributes()->name)) { + parent::error(sprintf(i18n('The plugin could not find the function %s. Because this is required by the plugin, it can not be installed.', 'pim'), parent::$XmlRequirements->function[$i]->attributes()->name)); + } + } + } + * + */ + } + + private function _initInstalledAreasArray() { + $this->_aInstalledAreas = array(); + $oAreaColl = new cApiAreaCollection(); + $oAreaColl->select(); + //$oAreaColl->query(); + /* @var $oArea cApiArea */ + while ($oArea = $oAreaColl->next()) { + $this->_aInstalledAreas[] = $oArea->get('name'); + } + //print_r($this->_aInstalledAreas); + } + + private function _initInstalledNavMainArray() { + $this->_aInstalledNavMain = array(); + $oNavMainColl = new cApiNavMainCollection(); + $oNavMainColl->select(); + //$oNavMainColl->query(); + /* @var $oArea cApiArea */ + while ($oNavMain = $oNavMainColl->next()) { + $this->_aInstalledNavMain[$oNavMain->get('name')] = $oNavMain->get('idnavm'); + } + } + + private function _initInstalledNavSubArray() { + $this->_aInstalledNavSub = array(); + $oNavSubColl = new cApiNavSubCollection(); + $oNavMainColl->select(); + //$oNavSubColl->query(); + /* @var $oArea cApiArea */ + while ($oNavSub = $oNavSubColl->next()) { + $this->_aInstalledNavMain[$oNavSub->get('idnavsub')] = $oNavSub->get('name'); + } + } + + private function _getIdForArea($sArea) { + if (array_key_exists($sArea, $this->_aAreas)) { + return $this->_aAreas[$sArea]; + } + + if (in_array($sArea, $this->_aInstalledAreas)) { + $oArea = new cApiArea(); + $oArea->loadBy("name", $sArea); + if ($oArea->isLoaded()) { + return $oArea->get($oArea->primaryKey); + } + } + parent::error(sprintf(i18n('Defined area %s not found on your ConLite installation. Please contact your plugin author.', "pluginmanager"), $sArea), $this->_iPiId); + } + + private function _getIdForNavMain($sNavMain) { + if($sNavMain == "0") { + return $sNavMain; + } + if (array_key_exists($sNavMain, $this->_aInstalledNavMain)) { + return $this->_aInstalledNavMain[$sNavMain]; + } + parent::error(sprintf(i18n('Defined nav main %s not found on your ConLite installation. Please contact your plugin author.', "pluginmanager"), $sNavMain), $this->_iPiId); + } + + public function __destruct() { + //echo "
";
+        //print_r($this->_aAreas);
+    }
+
+}
diff --git a/conlite/plugins/pluginmanager/classes/setup/class.pim.setup.plugin.uninstall.php b/conlite/plugins/pluginmanager/classes/setup/class.pim.setup.plugin.uninstall.php
new file mode 100644
index 0000000..b52ea86
--- /dev/null
+++ b/conlite/plugins/pluginmanager/classes/setup/class.pim.setup.plugin.uninstall.php
@@ -0,0 +1,38 @@
+isLoaded()) { // plugin exists in db
+            $this->_iPiId = (int) $iIdPlugin;
+            $this->_getRelations();
+            if(is_array($this->_aRelations) && count($this->_aRelations) > 0) {
+                if($this->_deleteRelationEntries()) {
+                    $this->_deleteRelations();
+                } else {
+                    return FALSE;
+                }
+            }
+            
+            if($sDeleteSql == "delete") {
+                $this->_getPluginSql();
+            }
+            
+            if($this->doQueries()) {
+                return $this->_PimPluginCollection->delete($iIdPlugin);
+            }
+        }
+        return FALSE;
+    }
+}
\ No newline at end of file
diff --git a/conlite/plugins/pluginmanager/css/images/error.png b/conlite/plugins/pluginmanager/css/images/error.png
new file mode 100644
index 0000000..296415e
Binary files /dev/null and b/conlite/plugins/pluginmanager/css/images/error.png differ
diff --git a/conlite/plugins/pluginmanager/css/images/info.png b/conlite/plugins/pluginmanager/css/images/info.png
new file mode 100644
index 0000000..83de654
Binary files /dev/null and b/conlite/plugins/pluginmanager/css/images/info.png differ
diff --git a/conlite/plugins/pluginmanager/css/images/success.png b/conlite/plugins/pluginmanager/css/images/success.png
new file mode 100644
index 0000000..743ef89
Binary files /dev/null and b/conlite/plugins/pluginmanager/css/images/success.png differ
diff --git a/conlite/plugins/pluginmanager/css/images/warning.png b/conlite/plugins/pluginmanager/css/images/warning.png
new file mode 100644
index 0000000..1c6b8eb
Binary files /dev/null and b/conlite/plugins/pluginmanager/css/images/warning.png differ
diff --git a/conlite/plugins/pluginmanager/css/pluginmanager.css b/conlite/plugins/pluginmanager/css/pluginmanager.css
new file mode 100644
index 0000000..2239862
--- /dev/null
+++ b/conlite/plugins/pluginmanager/css/pluginmanager.css
@@ -0,0 +1,101 @@
+/**
+ *
+ * @package pluginmanager
+ * @version $Rev:$
+ * @author Ortwin Pinke
+ *
+ * $Id:$
+ */
+
+#addplugin {
+    border: 1px solid #B5B5B5;
+    border-top: 0px;
+    height: 40px;
+    padding: 8px;
+    margin-left: 10px;
+    width: 650px;
+    text-align: center;
+}
+
+.plugininfo {
+    width: 550px;
+    margin-top: 10px;
+}
+
+hr {
+    border-color: #B5B5B5;
+    line-leight: 1em;
+}
+
+ul#pimPluginsInstalled, ul#pimPluginsExtracted {
+    max-width: 550px;
+    list-style-type: none;
+    margin: 0;
+    padding: 5px;
+    margin-top: 10px;
+    background: #eee;
+}
+
+ul#pimPluginsInstalled li, ul#pimPluginsExtracted li {
+    margin: 0 5px 5px 5px;
+    padding: 5px;
+    font-size: 1.2em;
+}
+
+ul#pimPluginsInstalled li>div .pimHeadline, ul#pimPluginsExtracted li>div .pimHeadline {
+    cursor: move;
+}
+
+.ui-state-highlight {
+    height: 1.5em;
+    line-height: 1.2em;
+    background-color: #eee;
+}
+
+ul#pimPluginsInstalled li:nth-of-type(even) {
+    background-color: #dddddd;
+}
+
+.loadie {
+    position: absolute;
+    top: 0;
+    left: 0;
+    background-color: #000;
+    width: 0;
+    height: 4px;
+    -webkit-transition: width 0.5s ease-out;
+    box-shadow: 0px 1px 5px rgba(0,0,0,0.25);
+}
+
+#pimmsg {    
+    font-family:Arial, Helvetica, sans-serif; 
+    font-size:13px;
+    margin: 10px 0px;
+    padding:15px 10px 15px 50px;
+    background-repeat: no-repeat;
+    background-position: 10px center;
+    box-shadow: 10px 10px 10px grey;
+    border: 1px solid grey;
+}
+
+.info, .success, .warning, .error, .validation {}
+.info {
+    color: #00529B;
+    background-color: #BDE5F8;
+    background-image: url('images/info.png');
+}
+.success {
+    color: #4F8A10;
+    background-color: #DFF2BF;
+    background-image:url('images/success.png');
+}
+.warning {
+    color: #9F6000;
+    background-color: #FEEFB3;
+    background-image: url('images/warning.png');
+}
+.error {
+    color: #D8000C;
+    background-color: #FFBABA;
+    background-image: url('images/error.png');
+}
\ No newline at end of file
diff --git a/conlite/plugins/pluginmanager/docs/Dokumentation Contenido Plugin Manager.pdf b/conlite/plugins/pluginmanager/docs/Dokumentation Contenido Plugin Manager.pdf
new file mode 100644
index 0000000..07a29ae
Binary files /dev/null and b/conlite/plugins/pluginmanager/docs/Dokumentation Contenido Plugin Manager.pdf differ
diff --git a/conlite/plugins/pluginmanager/docs/install.sql b/conlite/plugins/pluginmanager/docs/install.sql
new file mode 100644
index 0000000..f951845
--- /dev/null
+++ b/conlite/plugins/pluginmanager/docs/install.sql
@@ -0,0 +1,42 @@
+INSERT INTO `cl_area` (`idarea`, `parent_id`, `name`, `relevant`, `online`, `menuless`) VALUES ('10000', '0', 'pluginmanager', '1', '1', '1');
+INSERT INTO `cl_files` (`idfile`, `idarea`, `filename`, `filetype`) VALUES ('10000', '10000', 'pluginmanager/includes/include.right_bottom.php', 'main');
+INSERT INTO `cl_frame_files` (`idframefile`, `idarea`, `idframe`, `idfile`) VALUES ('10000', '10000', '4', '10000');
+INSERT INTO `cl_actions` (`idaction`, `idarea`, `alt_name`, `name`, `code`, `location`, `relevant`) VALUES ('10000', '10000', '', 'pluginmanager', '', '', '1');
+INSERT INTO `cl_nav_sub` (`idnavs`, `idnavm`, `idarea`, `level`, `location`, `online`) VALUES ('10000', '5', '10000', '0', 'pluginmanager/xml/plugin.xml;navigation/administration/pluginmanager/main', '1');
+
+
+--
+-- Table structure for table `cl_plugins`
+--
+
+CREATE TABLE IF NOT EXISTS `cl_plugins` (
+  `idplugin` int(11) NOT NULL AUTO_INCREMENT,
+  `idclient` int(11) DEFAULT NULL,
+  `name` varchar(255) NOT NULL,
+  `description` text NOT NULL,
+  `author` varchar(255) NOT NULL,
+  `copyright` varchar(255) NOT NULL,
+  `mail` varchar(255) NOT NULL,
+  `website` varchar(255) NOT NULL,
+  `version` varchar(10) NOT NULL,
+  `folder` varchar(255) NOT NULL,
+  `uuid` varchar(255) NOT NULL,
+  `executionorder` int(11) NOT NULL DEFAULT '0',
+  `installed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `active` tinyint(1) DEFAULT NULL,
+  PRIMARY KEY (`idplugin`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `cl_plugins_rel`
+--
+
+CREATE TABLE IF NOT EXISTS `cl_plugins_rel` (
+  `idpluginrelation` int(11) NOT NULL AUTO_INCREMENT,
+  `iditem` int(11) NOT NULL,
+  `idplugin` int(11) NOT NULL,
+  `type` varchar(8) NOT NULL DEFAULT 'area',
+  PRIMARY KEY (`idpluginrelation`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
\ No newline at end of file
diff --git a/conlite/plugins/pluginmanager/docs/linkchecker.zip b/conlite/plugins/pluginmanager/docs/linkchecker.zip
new file mode 100644
index 0000000..d84bc16
Binary files /dev/null and b/conlite/plugins/pluginmanager/docs/linkchecker.zip differ
diff --git a/conlite/plugins/pluginmanager/docs/localize.txt b/conlite/plugins/pluginmanager/docs/localize.txt
new file mode 100644
index 0000000..b426da4
--- /dev/null
+++ b/conlite/plugins/pluginmanager/docs/localize.txt
@@ -0,0 +1,2 @@
+find . \( -path "./_module" -o -path "./_src" -o -path "./docs" \) -prune ! -type d -o -iname "*.php" -o -iname "*.html" > ./locale/potfiles.txt
+xgettext --from-code=utf-8 --keyword=i18n -f ./locale/potfiles.txt -o ./locale/pluginmanager.pot
\ No newline at end of file
diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive.php
new file mode 100644
index 0000000..091d8ad
--- /dev/null
+++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive.php
@@ -0,0 +1,1434 @@
+
+ * @copyright  1997-2005 The PHP Group
+ * @license    http://www.gnu.org/copyleft/lesser.html  LGPL
+ * @version    CVS: $Id: Archive.php 2 2010-11-23 14:32:26Z oldperl $
+ * @link       http://pear.php.net/package/File_Archive
+ */
+
+/**
+ * To have access to PEAR::isError and PEAR::raiseError
+ * We should probably use lazy include and remove this inclusion...
+ */
+require_once "PEAR.php";
+
+function File_Archive_cleanCache($file, $group)
+{
+    $file = split('_', $file);
+    if (count($file) != 3) {
+        return false; //not a File_Archive file, keep it
+    }
+
+    $name = $file[2];
+    $name = urldecode($name);
+
+    $group = $file[1];
+
+    //clean the cache only for files in File_Archive groups
+    return substr($group, 0, 11) == 'FileArchive' &&
+           !file_exists($name); //and only if the related file no longer exists
+}
+
+/**
+ * Factory to access the most common File_Archive features
+ * It uses lazy include, so you dont have to include the files from
+ * File/Archive/* directories
+ */
+class File_Archive
+{
+    function& _option($name)
+    {
+        static $container = array(
+            'zipCompressionLevel' => 9,
+             'gzCompressionLevel' => 9,
+            'tmpDirectory' => '.',
+            'cache' => null,
+            'appendRemoveDuplicates' => false,
+            'blockSize' => 65536,
+            'cacheCondition' => false
+        );
+        return $container[$name];
+    }
+    /**
+     * Sets an option that will be used by default by all readers or writers
+     * Option names are case sensitive
+     * Currently, the following options are used:
+     *
+     * "cache"
+     *      Instance of a Cache_Lite object used to cache some compressed
+     *      data to speed up future compressions of files
+     *      Default: null (no cache used)
+     *
+     * "zipCompressionLevel"
+     *      Value between 0 and 9 specifying the default compression level used
+     *      by Zip writers (0 no compression, 9 highest compression)
+     *      Default: 9
+     *
+     * "gzCompressionLevel"
+     *      Value between 0 and 9 specifying the default compression level used
+     *      by Gz writers (0 no compression, 9 highest compression)
+     *      Default: 9
+     *
+     * "tmpDirectory"
+     *      Directory where the temporary files generated by File_Archive will
+     *      be created
+     *      Default: '.'
+     *
+     * "appendRemoveDuplicates"
+     *      If set to true, the appender created will by default remove the
+     *      file present in the archive when adding a new one. This will slow the
+     *      appending of files to archives
+     *      Default: false
+     *
+     * "blockSize"
+     *      To transfer data from a reader to a writer, some chunks a read from the
+     *      source and written to the writer. This parameter controls the size of the
+     *      chunks
+     *      Default: 64kB
+     *
+     * "cacheCondition"
+     *      This parameter specifies when a cache should be used. When the cache is
+     *      used, the data of the reader is saved in a temporary file for future access.
+     *      The cached reader will be read only once, even if you read it several times.
+     *      This can be usefull to read compressed files or downloaded files (from http or ftp)
+     *      The possible values for this option are
+     *       - false: never use cache
+     *       - a regexp: A cache will be used if the specified URL matches the regexp
+     *         preg_match is used
+     *      Default: false
+     *      Example: '/^(http|ftp):\/\//' will cache all files downloaded via http or ftp
+     *
+     */
+    function setOption($name, $value)
+    {
+        $option =& File_Archive::_option($name);
+        $option = $value;
+        if ($name == 'cache' && $value !== null) {
+            //TODO: ask to Cache_Lite to allow that
+            $value->_fileNameProtection = false;
+        }
+    }
+
+    /**
+     * Retrieve the value of an option
+     */
+    function getOption($name)
+    {
+        return File_Archive::_option($name);
+    }
+
+    /**
+     * Create a reader to read the URL $URL.
+     * If the URL is a directory, it will recursively read that directory.
+     * If $uncompressionLevel is not null, the archives (files with extension
+     * tar, zip, gz or tgz) will be considered as directories (up to a depth of
+     * $uncompressionLevel if $uncompressionLevel > 0). The reader will only
+     * read files with a directory depth of $directoryDepth. It reader will
+     * replace the given URL ($URL) with $symbolic in the public filenames
+     * The default symbolic name is the last filename in the URL (or '' for
+     * directories)
+     *
+     * Examples:
+     * Considere the following file system
+     * 
+     * a.txt
+     * b.tar (archive that contains the following files)
+     *     c.txt
+     *     d.tgz (archive that contains the following files)
+     *         e.txt
+     *         dir1/
+     *             f.txt
+     * dir2/
+     *     g.txt
+     *     dir3/
+     *         h.tar (archive that contains the following files)
+     *             i.txt
+     * 
+ * + * read('.') will return a reader that gives access to following + * files (recursively read current dir): + *
+     * a.txt
+     * b.tar
+     * dir2/g.txt
+     * dir2/dir3/h.tar
+     * 
+ * + * read('.', 'myBaseDir') will return the following reader: + *
+     * myBaseDir/a.txt
+     * myBaseDir/b.tar
+     * myBaseDir/dir2/g.txt
+     * myBaseDir/dir2/dir3/h.tar
+     * 
+ * + * read('.', '', -1) will return the following reader (uncompress + * everything) + *
+     * a.txt
+     * b.tar/c.txt
+     * b.tar/d.tgz/e.txt
+     * b.tar/d.tgz/dir1/f.txt
+     * dir2/g.txt
+     * dir2/dir3/h.tar/i.txt
+     * 
+ * + * read('.', '', 1) will uncompress only one level (so d.tgz will + * not be uncompressed): + *
+     * a.txt
+     * b.tar/c.txt
+     * b.tar/d.tgz
+     * dir2/g.txt
+     * dir2/dir3/h.tar/i.txt
+     * 
+ * + * read('.', '', 0, 0) will not recurse into subdirectories + *
+     * a.txt
+     * b.tar
+     * 
+ * + * read('.', '', 0, 1) will recurse only one level in + * subdirectories + *
+     * a.txt
+     * b.tar
+     * dir2/g.txt
+     * 
+ * + * read('.', '', -1, 2) will uncompress everything and recurse in + * only 2 levels in subdirectories or archives + *
+     * a.txt
+     * b.tar/c.txt
+     * b.tar/d.tgz/e.txt
+     * dir2/g.txt
+     * 
+ * + * The recursion level is determined by the real path, not the symbolic one. + * So read('.', 'myBaseDir', -1, 2) will result to the same files: + *
+     * myBaseDir/a.txt
+     * myBaseDir/b.tar/c.txt
+     * myBaseDir/b.tar/d.tgz/e.txt (accepted because the real depth is 2)
+     * myBaseDir/dir2/g.txt
+     * 
+ * + * Use readSource to do the same thing, reading from a specified reader instead of + * reading from the system files + * + * To read a single file, you can do read('a.txt', 'public_name.txt') + * If no public name is provided, the default one is the name of the file + * read('dir2/g.txt') contains the single file named 'g.txt' + * read('b.tar/c.txt') contains the single file named 'c.txt' + * + * Note: This function uncompress files reading their extension + * The compressed files must have a tar, zip, gz or tgz extension + * Since it is impossible for some URLs to use is_dir or is_file, this + * function may not work with + * URLs containing folders which name ends with such an extension + */ + function readSource(&$source, $URL, $symbolic = null, + $uncompression = 0, $directoryDepth = -1) + { + return File_Archive::_readSource($source, $URL, $reachable, $baseDir, + $symbolic, $uncompression, $directoryDepth); + } + + /** + * This function performs exactly as readSource, but with two additional parameters + * ($reachable and $baseDir) that will be set so that $reachable."/".$baseDir == $URL + * and $reachable can be reached (in case of error) + * + * @access private + */ + function _readSource(&$toConvert, $URL, &$reachable, &$baseDir, $symbolic = null, + $uncompression = 0, $directoryDepth = -1) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if (is_array($URL)) { + $converted = array(); + foreach($URL as $key => $foo) { + $converted[] =& File_Archive::_convertToReader($URL[$key]); + } + return File_Archive::readMulti($converted); + } + + //No need to uncompress more than $directoryDepth + //That's not perfect, and some archives will still be uncompressed just + //to be filtered out :( + if ($directoryDepth >= 0) { + $uncompressionLevel = min($uncompression, $directoryDepth); + } else { + $uncompressionLevel = $uncompression; + } + + require_once 'File/Archive/Reader.php'; + $std = File_Archive_Reader::getStandardURL($URL); + + //Modify the symbolic name if necessary + $slashPos = strrpos($std, '/'); + if ($symbolic === null) { + if ($slashPos === false) { + $realSymbolic = $std; + } else { + $realSymbolic = substr($std, $slashPos+1); + } + } else { + $realSymbolic = $symbolic; + } + if ($slashPos !== false) { + $baseFile = substr($std, 0, $slashPos+1); + $lastFile = substr($std, $slashPos+1); + } else { + $baseFile = ''; + $lastFile = $std; + } + + if (strpos($lastFile, '*')!==false || + strpos($lastFile, '?')!==false) { + //We have to build a regexp here + $regexp = str_replace( + array('\*', '\?'), + array('[^/]*', '[^/]'), + preg_quote($lastFile) + ); + $result = File_Archive::_readSource($source, $baseFile, + $reachable, $baseDir, null, 0, -1); + return File_Archive::filter( + File_Archive::predEreg('^'.$regexp.'$'), + $result + ); + } + + //If the URL can be interpreted as a directory, and we are reading from the file system + if ((empty($URL) || is_dir($URL)) && $source === null) { + require_once "File/Archive/Reader/Directory.php"; + + if ($uncompressionLevel != 0) { + require_once "File/Archive/Reader/Uncompress.php"; + $result = new File_Archive_Reader_Uncompress( + new File_Archive_Reader_Directory($std, '', $directoryDepth), + $uncompressionLevel + ); + } else { + $result = new File_Archive_Reader_Directory($std, '', $directoryDepth); + } + + if ($directoryDepth >= 0) { + require_once 'File/Archive/Reader/Filter.php'; + require_once 'File/Archive/Predicate/MaxDepth.php'; + + $tmp =& File_Archive::filter( + new File_Archive_Predicate_MaxDepth($directoryDepth), + $result + ); + unset($result); + $result =& $tmp; + } + if (!empty($realSymbolic)) { + if ($symbolic === null) { + $realSymbolic = ''; + } + require_once "File/Archive/Reader/ChangeName/AddDirectory.php"; + $tmp = new File_Archive_Reader_ChangeName_AddDirectory( + $realSymbolic, + $result + ); + unset($result); + $result =& $tmp; + } + + //If the URL can be interpreted as a file, and we are reading from the file system + } else if (is_file($URL) && substr($URL, -1)!='/' && $source === null) { + require_once "File/Archive/Reader/File.php"; + $result = new File_Archive_Reader_File($URL, $realSymbolic); + + //Else, we will have to build a complex reader + } else { + require_once "File/Archive/Reader/File.php"; + + $realPath = $std; + + // Try to find a file with a known extension in the path ( + // (to manage URLs like archive.tar/directory/file) + $pos = 0; + do { + if ($pos+1setBaseDir($std); + if (PEAR::isError($isDir)) { + return $isDir; + } + if ($isDir && $symbolic==null) { + //Default symbolic name for directories is empty + $realSymbolic = ''; + } + + if ($directoryDepth >= 0) { + //Limit the maximum depth if necessary + require_once "File/Archive/Reader/Filter.php"; + require_once "File/Archive/Predicate/MaxDepth.php"; + + $tmp = new File_Archive_Reader_Filter( + new File_Archive_Predicate( + $directoryDepth + + substr_count(substr($std, $pos+1), '/') + ), + $result + ); + unset($result); + $result =& $tmp; + } + + if ($std != $realSymbolic) { + require_once "File/Archive/Reader/ChangeName/Directory.php"; + + //Change the base name to the symbolic one if necessary + $tmp = new File_Archive_Reader_ChangeName_Directory( + $std, + $realSymbolic, + $result + ); + unset($result); + $result =& $tmp; + } + } + + $cacheCondition = File_Archive::getOption('cacheCondition'); + if ($cacheCondition !== false && + preg_match($cacheCondition, $URL)) { + $tmp =& File_Archive::cache($result); + unset($result); + $result =& $tmp; + } + + return $result; + } + function read($URL, $symbolic = null, + $uncompression = 0, $directoryDepth = -1) + { + $source = null; + return File_Archive::readSource($source, $URL, $symbolic, $uncompression, $directoryDepth); + } + + /** + * Create a file reader on an uploaded file. The reader will read + * $_FILES[$name]['tmp_name'] and will have $_FILES[$name]['name'] + * as a symbolic filename. + * + * A PEAR error is returned if one of the following happen + * - $_FILES[$name] is not set + * - $_FILES[$name]['error'] is not 0 + * - is_uploaded_file returns false + * + * @param string $name Index of the file in the $_FILES array + * @return File_Archive_Reader File reader on the uploaded file + */ + function readUploadedFile($name) + { + if (!isset($_FILES[$name])) { + return PEAR::raiseError("File $name has not been uploaded"); + } + switch ($_FILES[$name]['error']) { + case 0: + //No error + break; + case 1: + return PEAR::raiseError( + "The upload size limit didn't allow to upload file ". + $_FILES[$name]['name'] + ); + case 2: + return PEAR::raiseError( + "The form size limit didn't allow to upload file ". + $_FILES[$name]['name'] + ); + case 3: + return PEAR::raiseError( + "The file was not entirely uploaded" + ); + case 4: + return PEAR::raiseError( + "The uploaded file is empty" + ); + default: + return PEAR::raiseError( + "Unknown error ".$_FILES[$name]['error']." in file upload. ". + "Please, report a bug" + ); + } + if (!is_uploaded_file($_FILES[$name]['tmp_name'])) { + return PEAR::raiseError("The file is not an uploaded file"); + } + + require_once "File/Archive/Reader/File.php"; + return new File_Archive_Reader_File( + $_FILES[$name]['tmp_name'], + $_FILES[$name]['name'], + $_FILES[$name]['type'] + ); + } + + /** + * Adds a cache layer above the specified reader + * The data of the reader is saved in a temporary file for future access. + * The cached reader will be read only once, even if you read it several times. + * This can be usefull to read compressed files or downloaded files (from http or ftp) + * + * @param mixed $toConvert The reader to cache + * It can be a File_Archive_Reader or a string, which will be converted using the + * read function + */ + function cache(&$toConvert) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once 'File/Archive/Reader/Cache.php'; + return new File_Archive_Reader_Cache($source); + } + + /** + * Try to interpret the object as a reader + * Strings are converted to readers using File_Archive::read + * Arrays are converted to readers using File_Archive::readMulti + * + * @access private + */ + function &_convertToReader(&$source) + { + if (is_string($source)) { + $cacheCondition = File_Archive::getOption('cacheCondition'); + if ($cacheCondition !== false && + preg_match($cacheCondition, $source)) { + $obj = File_Archive::cache(File_Archive::read($source)); + return $obj; + } else { + $obj = File_Archive::read($source); + return $obj; + } + } else if (is_array($source)) { + return File_Archive::readMulti($source); + } else { + return $source; + } + } + + /** + * Try to interpret the object as a writer + * Strings are converted to writers using File_Archive::appender + * Arrays are converted to writers using a multi writer + * + * @access private + */ + function &_convertToWriter(&$dest) + { + if (is_string($dest)) { + $obj =& File_Archive::appender($dest); + return $obj; + } else if (is_array($dest)) { + require_once 'File/Archive/Writer/Multi.php'; + $writer = new File_Archive_Writer_Multi(); + foreach($dest as $key => $foo) { + $writer->addWriter($dest[$key]); + } + return $writer; + } else { + return $dest; + } + } + + /** + * Check if a file with a specific extension can be read as an archive + * with File_Archive::read* + * This function is case sensitive. + * + * @param string $extension the checked extension + * @return bool whether this file can be understood reading its extension + * Currently, supported extensions are tar, zip, jar, gz, tgz, + * tbz, bz2, bzip2, ar, deb + */ + function isKnownExtension($extension) + { + return $extension == 'tar' || + $extension == 'zip' || + $extension == 'jar' || + $extension == 'gz' || + $extension == 'tgz' || + $extension == 'tbz' || + $extension == 'bz2' || + $extension == 'bzip2' || + $extension == 'ar' || + $extension == 'deb' /* || + $extension == 'cab' || + $extension == 'rar' */; + } + + /** + * Create a reader that will read the single file source $source as + * a specific archive + * + * @param string $extension determines the kind of archive $source contains + * $extension is case sensitive + * @param File_Archive_Reader $source stores the archive + * @param bool $sourceOpened specifies if the archive is already opened + * if false, next will be called on source + * Closing the returned archive will close $source iif $sourceOpened + * is true + * @return A File_Archive_Reader that uncompresses the archive contained in + * $source interpreting it as a $extension archive + * If $extension is not handled return false + */ + function readArchive($extension, &$toConvert, $sourceOpened = false) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + switch($extension) { + case 'tgz': + return File_Archive::readArchive('tar', + File_Archive::readArchive('gz', $source, $sourceOpened) + ); + case 'tbz': + return File_Archive::readArchive('tar', + File_Archive::readArchive('bz2', $source, $sourceOpened) + ); + case 'tar': + require_once 'File/Archive/Reader/Tar.php'; + return new File_Archive_Reader_Tar($source, $sourceOpened); + + case 'gz': + case 'gzip': + require_once 'File/Archive/Reader/Gzip.php'; + return new File_Archive_Reader_Gzip($source, $sourceOpened); + + case 'zip': + case 'jar': + require_once 'File/Archive/Reader/Zip.php'; + return new File_Archive_Reader_Zip($source, $sourceOpened); + + case 'bz2': + case 'bzip2': + require_once 'File/Archive/Reader/Bzip2.php'; + return new File_Archive_Reader_Bzip2($source, $sourceOpened); + + case 'deb': + case 'ar': + require_once 'File/Archive/Reader/Ar.php'; + return new File_Archive_Reader_Ar($source, $sourceOpened); + +/* case 'cab': + require_once 'File/Archive/Reader/Cab.php'; + return new File_Archive_Reader_Cab($source, $sourceOpened); + + + case 'rar': + require_once "File/Archive/Reader/Rar.php"; + return new File_Archive_Reader_Rar($source, $sourceOpened); */ + + default: + return false; + } + } + + /** + * Contains only one file with data read from a memory buffer + * + * @param string $memory content of the file + * @param string $filename public name of the file + * @param array $stat statistics of the file. Index 7 (size) will be + * overwritten to match the size of $memory + * @param string $mime mime type of the file. Default will determine the + * mime type thanks to the extension of $filename + * @see File_Archive_Reader_Memory + */ + function readMemory($memory, $filename, $stat=array(), $mime=null) + { + require_once "File/Archive/Reader/Memory.php"; + return new File_Archive_Reader_Memory($memory, $filename, $stat, $mime); + } + + /** + * Contains several other sources. Take care the sources don't have several + * files with the same filename. The sources are given as a parameter, or + * can be added thanks to the reader addSource method + * + * @param array $sources Array of strings or readers that will be added to + * the multi reader. If the parameter is a string, a reader will be + * built thanks to the read function + * @see File_Archive_Reader_Multi, File_Archive::read() + */ + function readMulti($sources = array()) + { + require_once "File/Archive/Reader/Multi.php"; + $result = new File_Archive_Reader_Multi(); + foreach ($sources as $index => $foo) { + $s =& File_Archive::_convertToReader($sources[$index]); + if (PEAR::isError($s)) { + return $s; + } else { + $result->addSource($s); + } + } + return $result; + } + /** + * Make the files of a source appear as one large file whose content is the + * concatenation of the content of all the files + * + * @param File_Archive_Reader $toConvert The source whose files must be + * concatened + * @param string $filename name of the only file of the created reader + * @param array $stat statistics of the file. Index 7 (size) will be + * overwritten to match the total size of the files + * @param string $mime mime type of the file. Default will determine the + * mime type thanks to the extension of $filename + * @see File_Archive_Reader_Concat + */ + function readConcat(&$toConvert, $filename, $stat=array(), $mime=null) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once "File/Archive/Reader/Concat.php"; + return new File_Archive_Reader_Concat($source, $filename, $stat, $mime); + } + + /** + * Changes the name of each file in a reader by applying a custom function + * The function must return false if the file is to be discarded, or the new + * name of the file else + * + * @param Callable $function Function called to modify the name of the file + * $function takes the name of the file as a parameter and returns the + * new name, or false if the file must be discarded + * @param File_Archive_Reader $toConvert The files of this source will be + * modified + * @return File_Archive_Reader a new reader that contains the same files + * as $toConvert but with a different name + */ + function changeName($function, &$toConvert) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once "File/Archive/Reader/ChangeName.php"; + return new File_Archive_Reader_RemoveDirectory($source); + } + + /** + * Removes from a source the files that do not follow a given predicat + * + * @param File_Archive_Predicate $predicate Only the files for which + * $predicate->isTrue() will be kept + * @param File_Archive_Reader $source Source that will be filtered + * @see File_Archive_Reader_Filter + */ + function filter($predicate, &$toConvert) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once "File/Archive/Reader/Filter.php"; + return new File_Archive_Reader_Filter($predicate, $source); + } + /** + * Predicate that always evaluate to true + * + * @see File_Archive_Predicate_True + */ + function predTrue() + { + require_once "File/Archive/Predicate/True.php"; + return new File_Archive_Predicate_True(); + } + /** + * Predicate that always evaluate to false + * + * @see File_Archive_Predicate_False + */ + function predFalse() + { + require_once "File/Archive/Predicate/False.php"; + return new File_Archive_Predicate_False(); + } + /** + * Predicate that evaluates to the logical AND of the parameters + * You can add other predicates thanks to the + * File_Archive_Predicate_And::addPredicate() function + * + * @param File_Archive_Predicate (any number of them) + * @see File_Archive_Predicate_And + */ + function predAnd() + { + require_once "File/Archive/Predicate/And.php"; + $pred = new File_Archive_Predicate_And(); + $args = func_get_args(); + foreach ($args as $p) { + $pred->addPredicate($p); + } + return $pred; + } + /** + * Predicate that evaluates to the logical OR of the parameters + * You can add other predicates thanks to the + * File_Archive_Predicate_Or::addPredicate() function + * + * @param File_Archive_Predicate (any number of them) + * @see File_Archive_Predicate_Or + */ + function predOr() + { + require_once "File/Archive/Predicate/Or.php"; + $pred = new File_Archive_Predicate_Or(); + $args = func_get_args(); + foreach ($args as $p) { + $pred->addPredicate($p); + } + return $pred; + } + /** + * Negate a predicate + * + * @param File_Archive_Predicate $pred Predicate to negate + * @see File_Archive_Predicate_Not + */ + function predNot($pred) + { + require_once "File/Archive/Predicate/Not.php"; + return new File_Archive_Predicate_Not($pred); + } + /** + * Evaluates to true iif the file is larger than a given size + * + * @param int $size the minimal size of the files (in Bytes) + * @see File_Archive_Predicate_MinSize + */ + function predMinSize($size) + { + require_once "File/Archive/Predicate/MinSize.php"; + return new File_Archive_Predicate_MinSize($size); + } + /** + * Evaluates to true iif the file has been modified after a given time + * + * @param int $time Unix timestamp of the minimal modification time of the + * files + * @see File_Archive_Predicate_MinTime + */ + function predMinTime($time) + { + require_once "File/Archive/Predicate/MinTime.php"; + return new File_Archive_Predicate_MinTime($time); + } + /** + * Evaluates to true iif the file has less that a given number of + * directories in its path + * + * @param int $depth Maximal number of directories in path of the files + * @see File_Archive_Predicate_MaxDepth + */ + function predMaxDepth($depth) + { + require_once "File/Archive/Predicate/MaxDepth.php"; + return new File_Archive_Predicate_MaxDepth($depth); + } + /** + * Evaluates to true iif the extension of the file is in a given list + * + * @param array or string $list List or comma separated string of possible + * extension of the files + * @see File_Archive_Predicate_Extension + */ + function predExtension($list) + { + require_once "File/Archive/Predicate/Extension.php"; + return new File_Archive_Predicate_Extension($list); + } + /** + * Evaluates to true iif the MIME type of the file is in a given list + * + * @param array or string $list List or comma separated string of possible + * MIME types of the files. You may enter wildcards like "image/*" to + * select all the MIME in class image + * @see File_Archive_Predicate_MIME, MIME_Type::isWildcard() + */ + function predMIME($list) + { + require_once "File/Archive/Predicate/MIME.php"; + return new File_Archive_Predicate_MIME($list); + } + /** + * Evaluates to true iif the name of the file follow a given regular + * expression + * + * @param string $ereg regular expression that the filename must follow + * @see File_Archive_Predicate_Ereg, ereg() + */ + function predEreg($ereg) + { + require_once "File/Archive/Predicate/Ereg.php"; + return new File_Archive_Predicate_Ereg($ereg); + } + /** + * Evaluates to true iif the name of the file follow a given regular + * expression (case insensitive version) + * + * @param string $ereg regular expression that the filename must follow + * @see File_Archive_Predicate_Eregi, eregi + */ + function predEregi($ereg) + { + require_once "File/Archive/Predicate/Eregi.php"; + return new File_Archive_Predicate_Eregi($ereg); + } + /** + * Evaluates to true only after a given number of evaluations + * This can be used to select files by index since the evaluation is done + * once per file + * + * @param array The indexes for which the returned predicate will return true + * are the keys of the array + * The predicate will return true if isset($indexes[$pos]) + */ + function predIndex($indexes) + { + require_once "File/Archive/Predicate/Index.php"; + return new File_Archive_Predicate_Index($indexes); + } + /** + * Custom predicate built by supplying a string expression + * + * Here are different ways to create a predicate that keeps only files + * with names shorter than 100 chars + * + * File_Archive::predCustom("return strlen($name)<100;") + * File_Archive::predCustom("strlen($name)<100;") + * File_Archive::predCustom("strlen($name)<100") + * File_Archive::predCustom("strlen($source->getFilename())<100") + * + * + * @param string $expression String containing an expression that evaluates + * to a boolean. If the expression doesn't contain a return + * statement, it will be added at the begining of the expression + * A ';' will be added at the end of the expression so that you don't + * have to write it. You may use the $name variable to refer to the + * current filename (with path...), $time for the modification time + * (unix timestamp), $size for the size of the file in bytes, $mime + * for the MIME type of the file + * @see File_Archive_Predicate_Custom + */ + function predCustom($expression) + { + require_once "File/Archive/Predicate/Custom.php"; + return new File_Archive_Predicate_Custom($expression); + } + + /** + * Send the files as a mail attachment + * + * @param Mail $mail Object used to send mail (see Mail::factory) + * @param array or String $to An array or a string with comma separated + * recipients + * @param array $headers The headers that will be passed to the Mail_mime + * object + * @param string $message Text body of the mail + * @see File_Archive_Writer_Mail + */ + function toMail($to, $headers, $message, $mail = null) + { + require_once "File/Archive/Writer/Mail.php"; + return new File_Archive_Writer_Mail($to, $headers, $message, $mail); + } + /** + * Write the files on the hard drive + * + * @param string $baseDir if specified, the files will be created in that + * directory. If they don't exist, the directories will automatically + * be created + * @see File_Archive_Writer_Files + */ + function toFiles($baseDir = "") + { + require_once "File/Archive/Writer/Files.php"; + return new File_Archive_Writer_Files($baseDir); + } + /** + * Send the content of the files to a memory buffer + * + * toMemory returns a writer where the data will be written. + * In this case, the data is accessible using the getData member + * + * toVariable returns a writer that will write into the given + * variable + * + * @param out $data if specified, the data will be written to this buffer + * Else, you can retrieve the buffer with the + * File_Archive_Writer_Memory::getData() function + * @see File_Archive_Writer_Memory + */ + function toMemory() + { + $v = ''; + return File_Archive::toVariable($v); + } + function toVariable(&$v) + { + require_once "File/Archive/Writer/Memory.php"; + return new File_Archive_Writer_Memory($v); + } + /** + * Duplicate the writing operation on two writers + * + * @param File_Archive_Writer $a, $b writers where data will be duplicated + * @see File_Archive_Writer_Multi + */ + function toMulti(&$aC, &$bC) + { + $a =& File_Archive::_convertToWriter($aC); + $b =& File_Archive::_convertToWriter($bC); + + if (PEAR::isError($a)) { + return $a; + } + if (PEAR::isError($b)) { + return $b; + } + + require_once "File/Archive/Writer/Multi.php"; + $writer = new File_Archive_Writer_Multi(); + $writer->addWriter($a); + $writer->addWriter($b); + return $writer; + } + /** + * Send the content of the files to the standard output (so to the client + * for a website) + * + * @param bool $sendHeaders If true some headers will be sent to force the + * download of the file. Default value is true + * @see File_Archive_Writer_Output + */ + function toOutput($sendHeaders = true) + { + require_once "File/Archive/Writer/Output.php"; + return new File_Archive_Writer_Output($sendHeaders); + } + /** + * Compress the data to a tar, gz, tar/gz or zip format + * + * @param string $filename name of the archive file + * @param File_Archive_Writer $innerWriter writer where the archive will be + * written + * @param string $type can be one of tgz, tbz, tar, zip, gz, gzip, bz2, + * bzip2 (default is the extension of $filename) or any composition + * of them (for example tar.gz or tar.bz2). The case of this + * parameter is not important. + * @param array $stat Statistics of the archive (see stat function) + * @param bool $autoClose If set to true, $innerWriter will be closed when + * the returned archive is close. Default value is true. + */ + function toArchive($filename, &$toConvert, $type = null, + $stat = array(), $autoClose = true) + { + $innerWriter =& File_Archive::_convertToWriter($toConvert); + if (PEAR::isError($innerWriter)) { + return $innerWriter; + } + $shortcuts = array("tgz" , "tbz" ); + $reals = array("tar.gz", "tar.bz2"); + + if ($type === null) { + $extensions = strtolower($filename); + } else { + $extensions = strtolower($type); + } + $extensions = explode('.', str_replace($shortcuts, $reals, $extensions)); + if ($innerWriter !== null) { + $writer =& $innerWriter; + } else { + $writer = File_Archive::toFiles(); + } + $nbCompressions = 0; + $currentFilename = $filename; + while (($extension = array_pop($extensions)) !== null) { + unset($next); + switch($extension) { + case "tar": + require_once "File/Archive/Writer/Tar.php"; + $next = new File_Archive_Writer_Tar( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "zip": + require_once "File/Archive/Writer/Zip.php"; + $next = new File_Archive_Writer_Zip( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "gz": + case "gzip": + require_once "File/Archive/Writer/Gzip.php"; + $next = new File_Archive_Writer_Gzip( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "bz2": + case "bzip2": + require_once "File/Archive/Writer/Bzip2.php"; + $next = new File_Archive_Writer_Bzip2( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "deb": + case "ar": + require_once "File/Archive/Writer/Ar.php"; + $next = new File_Archive_Writer_Ar( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + default: + if ($type !== null || $nbCompressions == 0) { + return PEAR::raiseError("Archive $extension unknown"); + } + break; + } + $nbCompressions ++; + $autoClose = true; + $currentFilename = implode(".", $extensions); + } + return $writer; + } + + + /** + * File_Archive::extract($source, $dest) is equivalent to $source->extract($dest) + * If $source is a PEAR error, the error will be returned + * It is thus easier to use this function than $source->extract, since it reduces the number of + * error checking and doesn't force you to define a variable $source + * + * You may use strings as source and dest. In that case the source is automatically + * converted to a reader using File_Archive::read and the dest is converted to a + * writer using File_Archive::appender + * Since PHP doesn't allow to pass literal strings by ref, you will have to use temporary + * variables. + * File_Archive::extract($src = 'archive.zip/', $dest = 'dir') will extract the archive to 'dir' + * It is the same as + * File_Archive::extract( + * File_Archive::read('archive.zip/'), + * File_Archive::appender('dir') + * ); + * You may use any variable in the extract function ($from/$to, $a/$b...). + * + * @param File_Archive_Reader $source The source that will be read + * @param File_Archive_Writer $dest Where to copy $source files + * @param bool $autoClose if true (default), $dest will be closed after the extraction + * @param int $bufferSize Size of the buffer to use to move data from the reader to the buffer + * If $bufferSize <= 0 (default), the blockSize option is used + * You shouldn't need to change that + * @return null or a PEAR error if an error occured + */ + function extract(&$sourceToConvert, &$destToConvert, $autoClose = true, $bufferSize = 0) + { + $source =& File_Archive::_convertToReader($sourceToConvert); + if (PEAR::isError($source)) { + return $source; + } + $dest =& File_Archive::_convertToWriter($destToConvert); + return $source->extract($dest, $autoClose, $bufferSize); + } + + /** + * Create a writer that can be used to append files to an archive inside a source + * If the archive can't be found in the source, it will be created + * If source is set to null, File_Archive::toFiles will be assumed + * If type is set to null, the type of the archive will be determined looking at + * the extension in the URL + * stat is the array of stat (returned by stat() PHP function of Reader getStat()) + * to use if the archive must be created + * + * This function allows to create or append data to nested archives. Only one + * archive will be created and if your creation requires creating several nested + * archives, a PEAR error will be returned + * + * After this call, $source will be closed and should not be used until the + * returned writer is closed. + * + * @param File_Archive_Reader $source A reader where some files will be appended + * @param string $URL URL to reach the archive in the source. + * if $URL is null, a writer to append files to the $source reader will + * be returned + * @param bool $unique If true, the duplicate files will be deleted on close + * Default is false (and setting it to true may have some performance + * consequences) + * @param string $type Extension of the archive (or null to use the one in the URL) + * @param array $stat Used only if archive is created, array of stat as returned + * by PHP stat function or Reader getStat function: stats of the archive) + * Time (index 9) will be overwritten to current time + * @return File_Archive_Writer a writer that you can use to append files to the reader + */ + function appenderFromSource(&$toConvert, $URL = null, $unique = null, + $type = null, $stat = array()) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if ($unique == null) { + $unique = File_Archive::getOption("appendRemoveDuplicates"); + } + + //Do not report the fact that the archive does not exist as an error + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + + if ($URL === null) { + $result =& $source; + } else { + if ($type === null) { + $result = File_Archive::_readSource($source, $URL.'/', $reachable, $baseDir); + } else { + $result = File_Archive::readArchive( + $type, + File_Archive::_readSource($source, $URL, $reachable, $baseDir) + ); + } + } + + PEAR::popErrorHandling(); + + if (!PEAR::isError($result)) { + if ($unique) { + require_once "File/Archive/Writer/UniqueAppender.php"; + return new File_Archive_Writer_UniqueAppender($result); + } else { + return $result->makeAppendWriter(); + } + } + + //The source can't be found and has to be created + $stat[9] = $stat['mtime'] = time(); + + if (empty($baseDir)) { + if ($source !== null) { + $writer =& $source->makeWriter(); + } else { + $writer =& File_Archive::toFiles(); + } + if (PEAR::isError($writer)) { + return $writer; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $result = File_Archive::toArchive($reachable, $writer, $type); + PEAR::popErrorHandling(); + + if (PEAR::isError($result)) { + $result = File_Archive::toFiles($reachable); + } + } else { + $reachedSource = File_Archive::readSource($source, $reachable); + if (PEAR::isError($reachedSource)) { + return $reachedSource; + } + $writer = $reachedSource->makeWriter(); + if (PEAR::isError($writer)) { + return $writer; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $result = File_Archive::toArchive($baseDir, $writer, $type); + PEAR::popErrorHandling(); + + if (PEAR::isError($result)) { + require_once "File/Archive/Writer/AddBaseName.php"; + $result = new File_Archive_Writer_AddBaseName( + $baseDir, $writer); + if (PEAR::isError($result)) { + return $result; + } + } + } + return $result; + } + + /** + * Create a writer that allows appending new files to an existing archive + * This function actes as appendToSource with source being the system files + * $URL can't be null here + * + * @param File_Archive_Reader $source A reader where some files will be appended + * @return File_Archive_Writer a writer that you can use to append files to the reader + */ + function appender($URL, $unique = null, $type = null, $stat = array()) + { + $source = null; + return File_Archive::appenderFromSource($source, $URL, $unique, $type, $stat); + } + + /** + * Remove the files that follow a given predicate from the source + * If URL is null, the files will be removed from the source directly + * Else, URL must link to a source from which the files will be removed + * + * @param File_Archive_Predicate $pred The files that follow the predicate + * (for which $pred->isTrue($source) is true) will be erased + * @param File_Archive_Reader $source A reader that contains the files to remove + */ + function removeFromSource(&$pred, &$toConvert, $URL = null) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if ($URL === null) { + $result = &$source; + } else { + if (substr($URL, -1) !== '/') { + $URL .= '/'; + } + $result = File_Archive::readSource($source, $URL); + } + + $writer = $result->makeWriterRemoveFiles($pred); + if (PEAR::isError($writer)) { + return $writer; + } + $writer->close(); + } + + /** + * Remove the files that follow a given predicate from the archive specified + * in $URL + * + * @param $URL URL of the archive where some files must be removed + */ + function remove($pred, $URL) + { + $source = null; + return File_Archive::removeFromSource($pred, $source, $URL); + } + + /** + * Remove duplicates from a source, keeping the most recent one (or the one that has highest pos in + * the archive if the files have same date or no date specified) + * + * @param File_Archive_Reader a reader that may contain duplicates + */ + function removeDuplicatesFromSource(&$toConvert, $URL = null) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if ($URL !== null && substr($URL, -1) != '/') { + $URL .= '/'; + } + + if ($source === null) { + $source = File_Archive::read($URL); + } + + require_once "File/Archive/Predicate/Duplicate.php"; + $pred = new File_Archive_Predicate_Duplicate($source); + $source->close(); + return File_Archive::removeFromSource( + $pred, + $source, + null + ); + } + + /** + * Remove duplicates from the archive specified in the URL + */ + function removeDuplicates($URL) + { + $source = null; + return File_Archive::removeDuplicatesFromSource($source, $URL); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate.php new file mode 100644 index 0000000..6f171b4 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate.php @@ -0,0 +1,57 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Predicate.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * A predicate is an object that can evaluate to true or false depending on the + * file currently read by a File_Archive_Reader + * + * @see File_Archive_Reader_Filter + */ +class File_Archive_Predicate +{ + /** + * Indicates whether the current file from the reader should be kept + * + * @param File_Archive_Reader $source Reader which will be filtered + * @return bool False if the current file must be filtered out + */ + function isTrue(&$source) + { + return PEAR::raiseError("Predicat abstract function call"); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/And.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/And.php new file mode 100644 index 0000000..674d80a --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/And.php @@ -0,0 +1,87 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: And.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true iif all predicates given as constructor parameters evaluate + * to true + * + * Example: + * new File_Archive_Predicate_And($pred1, $pred2, $pred3) + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_And extends File_Archive_Predicate +{ + /** + * @var Array List of File_Archive_Predicate objects given as an argument + * @access private + */ + var $preds; + + /** + * Build the predicate using the optional File_Archive_Predicates given as + * arguments + * + * Example: + * new File_Archive_Predicate_And($pred1, $pred2, $pred3) + */ + function File_Archive_Predicate_And() + { + $this->preds = func_get_args(); + } + + /** + * Add a new predicate to the list + * + * @param File_Archive_Predicate The predicate to add + */ + function addPredicate($pred) + { + $this->preds[] = $pred; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + foreach ($this->preds as $p) { + if (!$p->isTrue($source)) { + return false; + } + } + return true; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Current.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Current.php new file mode 100644 index 0000000..2276a74 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Current.php @@ -0,0 +1,52 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Current.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true only once, and then always to false + */ +class File_Archive_Predicate_Current extends File_Archive_Predicate +{ + var $value = true; + + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $tmp = $this->value; + $this->value = false; + return $tmp; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Custom.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Custom.php new file mode 100644 index 0000000..1b43655 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Custom.php @@ -0,0 +1,88 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Custom.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Custom predicate built by supplying a string expression + * + * Example: + * new File_Archive_Predicate_Custom("return strlen($name)<100;") + * new File_Archive_Predicate_Custom("strlen($name)<100;") + * new File_Archive_Predicate_Custom("strlen($name)<100") + * new File_Archive_Predicate_Custom("strlen($source->getFilename())<100") + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Custom extends File_Archive_Predicate +{ + var $expression; + var $useName; + var $useStat; + var $useMIME; + + /** + * @param string $expression PHP code that evaluates too a boolean + * It can use the $source variable. If return is ommited, it will be + * added to the begining of the expression. A ; will also be added at + * the end so that you don't need to write it + */ + function File_Archive_Predicate_Custom($expression) + { + $this->expression = $expression.";"; + if (strpos($this->expression, "return") === false) { + $this->expression = "return ".$this->expression; + } + $this->useName = (strpos($this->expression, '$name') !== false); + $this->useStat = (strpos($this->expression, '$stat') !== false); + $this->useMIME = (strpos($this->expression, '$mime') !== false); + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + if ($this->useName) { + $name = $source->getFilename(); + } + if ($this->useStat) { + $stat = $source->getStat(); + $size = $stat[7]; + $time = (isset($stat[9]) ? $stat[9] : null); + } + if ($this->useMIME) { + $mime = $source->getMIME(); + } + return (bool)eval($this->expression); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Duplicate.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Duplicate.php new file mode 100644 index 0000000..16ad94e --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Duplicate.php @@ -0,0 +1,116 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Duplicate.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true if a for the files for which a newer version + * can be found in a specified archive + * Comparison is by default made on dates of the files, or position + * in the archive (if two files have the same date or the date of a + * file is not specified). + */ +class File_Archive_Predicate_Duplicate extends File_Archive_Predicate +{ + /** + * @var array Key is the filename, value is an array of date (index 0) and + * position in the archive (index) 1 of the newest entry with this filename + */ + var $newest = array(); + + /** + * @var int The current position of the file in the source + */ + var $pos = 0; + + /** + * @param File_Archive_Reader $source The source will be inspected to find + * the date of old files + * The predicate should then be used on the same source to remove the + * old duplicate files + */ + function File_Archive_Predicate_Duplicate(&$source) + { + //Ensure we are at the begining of the file + $source->close(); + $pos = 0; + while ($source->next()) { + $filename = $source->getFilename(); + $stat = $source->getStat(); + $value = isset($this->newest[$filename]) ? $this->newest[$filename] : null; + + if ($value === null || + $this->compare($stat[9], $value[0]) >= 0 + ) { + $this->newest[$filename] = array($stat[9], $pos); + } + $pos++; + } + } + + /** + * Compare the dates of two files. null is considered infinitely old + * + * @return int < 0 if $a can be considered older than $b + * = 0 if $a and $b can be considered same age + * > 0 if $a can be considered newer than $b + */ + function compare($a, $b) { + return ($a === null ? -1 : $a) - ($b === null ? -1 : $b); + } + + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $filename = $source->getFilename(); + $stat = $source->getStat(); + $value = isset($this->newest[$filename]) ? $this->newest[$filename] : null; + if ($value === null) { + $delete = false; + } else { + $comp = $this->compare($stat[9], $value[0]); + + $delete = $comp < 0 || + ($comp == 0 && $this->pos != $value[1]); + + } + $this->pos++; + return $delete; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Ereg.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Ereg.php new file mode 100644 index 0000000..e2bbd9d --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Ereg.php @@ -0,0 +1,59 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Ereg.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files which name follow a given regular expression + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter ereg + */ +class File_Archive_Predicate_Ereg extends File_Archive_Predicate +{ + var $ereg; + + /** + * @param string $ereg is the regular expression + */ + function File_Archive_Predicate_Ereg($ereg) + { + $this->ereg = $ereg; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return (bool)ereg($this->ereg, $source->getFilename()); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Eregi.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Eregi.php new file mode 100644 index 0000000..540f1c4 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Eregi.php @@ -0,0 +1,61 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Eregi.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files which name follow a given case insensitive regular + * expression + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter eregi + */ +class File_Archive_Predicate_Eregi extends File_Archive_Predicate +{ + var $ereg; + + /** + * @param string $ereg is the regular expression + */ + function File_Archive_Predicate_Eregi($ereg) + { + $this->ereg = $ereg; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return (bool)eregi($this->ereg, $source->getFilename()); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Extension.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Extension.php new file mode 100644 index 0000000..419e643 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Extension.php @@ -0,0 +1,71 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Extension.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files that have a specific extension + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Extension extends File_Archive_Predicate +{ + var $extensions; + + /** + * @param $extensions array or comma separated string of allowed extensions + */ + function File_Archive_Predicate_Extension($extensions) + { + if (is_string($extensions)) { + $this->extensions = explode(",",$extensions); + } else { + $this->extensions = $extensions; + } + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $filename = $source->getFilename(); + $pos = strrpos($filename, '.'); + $extension = ""; + if ($pos !== FALSE) { + $extension = strtolower(substr($filename, $pos+1)); + } + $result = in_array($extension, $this->extensions); + + return $result; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/False.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/False.php new file mode 100644 index 0000000..cfa20b2 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/False.php @@ -0,0 +1,47 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: False.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Always evaluate to false + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_False extends File_Archive_Predicate +{ + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) { return false; } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Index.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Index.php new file mode 100644 index 0000000..9fde26c --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Index.php @@ -0,0 +1,62 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Index.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true if the index is in a given array of indexes + * The array has the indexes in key (so you may want to call + * array_flip if your array has indexes as value) + */ +class File_Archive_Predicate_Index extends File_Archive_Predicate +{ + var $indexes; + var $pos = 0; + + /** + * @param $extensions array or comma separated string of allowed extensions + */ + function File_Archive_Predicate_Index($indexes) + { + $this->indexes = $indexes; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return isset($this->indexes[$this->pos++]); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MIME.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MIME.php new file mode 100644 index 0000000..54c3d61 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MIME.php @@ -0,0 +1,75 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MIME.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; +require_once "MIME/Type.php"; + +/** + * Keep only the files that have a specific MIME type + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MIME extends File_Archive_Predicate +{ + var $mimes; + + /** + * @param $extensions array or comma separated string of allowed extensions + */ + function File_Archive_Predicate_MIME($mimes) + { + if (is_string($mimes)) { + $this->mimes = explode(",",$mimes); + } else { + $this->mimes = $mimes; + } + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $sourceMIME = $source->getMIME(); + foreach ($this->mimes as $mime) { + if (MIME_Type::isWildcard($mime)) { + $result = MIME_Type::wildcardMatch($mime, $sourceMIME); + } else { + $result = ($mime == $sourceMIME); + } + if ($result !== false) { + return $result; + } + } + return false; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MaxDepth.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MaxDepth.php new file mode 100644 index 0000000..5d78f40 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MaxDepth.php @@ -0,0 +1,63 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MaxDepth.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Remove the URLs with a too high number of nested directories + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MaxDepth extends File_Archive_Predicate +{ + var $maxDepth; + + /** + * @param int $maxDepth Maximal number of folders before the actual file in + * $source->getFilename(). + * '1/2/3/4/foo.txt' will be accepted with $maxDepth == 4 and + * rejected with $maxDepth == 5 + */ + function File_Archive_Predicate_MaxDepth($maxDepth) + { + $this->maxDepth = $maxDepth; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $url = parse_url($source->getFilename()); + return substr_count($url['path'], '/') <= $this->maxDepth ; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MinSize.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MinSize.php new file mode 100644 index 0000000..9825622 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MinSize.php @@ -0,0 +1,59 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MinSize.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files larger than a given size + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MinSize extends File_Archive_Predicate +{ + var $minSize = 0; + + /** + * @param int $minSize minimal size of the file (in Bytes) + */ + function File_Archive_Predicate_MinSize($minSize) + { + $this->minSize = $minSize; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $stat = $source->getStat(); + return !isset($stat[7]) || $stat[7]>=$this->minSize; + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MinTime.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MinTime.php new file mode 100644 index 0000000..7770b59 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/MinTime.php @@ -0,0 +1,63 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MinTime.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files modified after a given date (or with unknown modification + * date) + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MinTime extends File_Archive_Predicate +{ + var $minTime = 0; + + /** + * @param int $minTime Unix timestamp of the minimal modification date of + * the files + */ + function File_Archive_Predicate_MinTime($minTime) + { + $this->minTime = $minTime; + + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $stat = $source->getStat(); + return !isset($stat[9]) || $stat[9]>=$this->minTime; + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Not.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Not.php new file mode 100644 index 0000000..b058fe8 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Not.php @@ -0,0 +1,55 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Not.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true iif the predicate given in parameter evaluates to false + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Not extends File_Archive_Predicate +{ + var $pred; + function File_Archive_Predicate_Not($pred) + { + $this->pred = $pred; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return !$this->pred->isTrue($source); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Or.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Or.php new file mode 100644 index 0000000..db82e4a --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/Or.php @@ -0,0 +1,85 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Or.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true iif one at least of the predicates + * given as constructor parameters evaluate to true + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Or extends File_Archive_Predicate +{ + /** + * @var Array List of File_Archive_Predicate objects given as an argument + * @access private + */ + var $preds; + + /** + * Build the predicate using the optional File_Archive_Predicates given as + * arguments + * + * Example: + * new File_Archive_Predicate_And($pred1, $pred2, $pred3) + */ + function File_Archive_Predicate_And() + { + $this->preds = func_get_args(); + } + + /** + * Add a new predicate to the list + * + * @param File_Archive_Predicate The predicate to add + */ + function addPredicate($pred) + { + $this->preds[] = $pred; + } + + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + foreach ($this->preds as $p) { + if ($p->isTrue($source)) { + return true; + } + } + return false; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/True.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/True.php new file mode 100644 index 0000000..fdfa5d0 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Predicate/True.php @@ -0,0 +1,45 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: True.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Always evaluate to true + */ +class File_Archive_Predicate_True extends File_Archive_Predicate +{ + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) { return true; } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader.php new file mode 100644 index 0000000..7c5db43 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader.php @@ -0,0 +1,427 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Reader.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "PEAR.php"; + +/** + * Abstract base class for all the readers + * + * A reader is a compilation of serveral files that can be read + */ +class File_Archive_Reader +{ + /** + * Move to the next file or folder in the reader + * + * @return bool false iif no more files are available + */ + function next() + { + return false; + } + + /** + * Move to the next file whose name is in directory $filename + * or is exactly $filename + * + * @param string $filename Name of the file to find in the archive + * @param bool $close If true, close the reader and search from the first file + * @return bool whether the file was found in the archive or not + */ + function select($filename, $close = true) + { + $std = $this->getStandardURL($filename); + if (substr($std, -1)=='/') { + $std = substr($std, 0, -1); + } + + if ($close) { + $error = $this->close(); + if (PEAR::isError($error)) { + return $error; + } + } + while (($error = $this->next()) === true) { + $sourceName = $this->getFilename(); + if ( + empty($std) || + + //$std is a file + $std == $sourceName || + + //$std is a directory + (strncmp($std.'/', $sourceName, strlen($std)+1) == 0 && + strlen($sourceName) > strlen($std)+1) + ) { + return true; + } + } + return $error; + } + + /** + * Returns the standard path + * Changes \ to / + * Removes the .. and . from the URL + * @param string $path a valid URL that may contain . or .. and \ + * @static + */ + function getStandardURL($path) + { + if ($path == '.') { + return ''; + } + $std = str_replace("\\", "/", $path); + while ($std != ($std = preg_replace("/[^\/:?]+\/\.\.\//", "", $std))) ; + $std = str_replace("/./", "", $std); + if (strncmp($std, "./", 2) == 0) { + /** + * If return value is going to be / (root on POSIX) + */ + if (substr($std, 2) === '/') { + return $std; + } + return substr($std, 2); + } else { + return $std; + } + } + + /** + * Returns the name of the file currently read by the reader + * + * Warning: undefined behaviour if no call to next have been + * done or if last call to next has returned false + * + * @return string Name of the current file + */ + function getFilename() + { + return PEAR::raiseError("Reader abstract function call (getFilename)"); + } + + /** + * Returns the list of filenames from the current pos to the end of the source + * The source will be closed after having called this function + * This function goes through the whole archive (which may be slow). + * If you intend to work on the reader, doing it in one pass would be faster + * + * @return array filenames from the current pos to the end of the source + */ + function getFileList() + { + $result = array(); + while ( ($error = $this->next()) === true) { + $result[] = $this->getFilename(); + } + $this->close(); + if (PEAR::isError($error)) { + return $error; + } else { + return $result; + } + } + + /** + * Returns an array of statistics about the file + * (see the PHP stat function for more information) + * + * The returned array may be empty, even if readers should try + * their best to return as many data as possible + */ + function getStat() { return array(); } + + /** + * Returns the MIME associated with the current file + * The default function does that by looking at the extension of the file + */ + function getMime() + { + require_once "File/Archive/Reader/MimeList.php"; + return File_Archive_Reader_GetMime($this->getFilename()); + } + + /** + * If the current file of the archive is a physical file, + * + * @return the name of the physical file containing the data + * or null if no such file exists + * + * The data filename may not be the same as the filename. + */ + function getDataFilename() { return null; } + + /** + * Reads some data from the current file + * If the end of the file is reached, returns null + * If $length is not specified, reads up to the end of the file + * If $length is specified reads up to $length + */ + function getData($length = -1) + { + return PEAR::raiseError("Reader abstract function call (getData)"); + } + + /** + * Skip some data and returns how many bytes have been skipped + * This is strictly equivalent to + * return strlen(getData($length)) + * But could be far more efficient + */ + function skip($length = -1) + { + $data = $this->getData($length); + if (PEAR::isError($data)) { + return $data; + } else { + return strlen($data); + } + } + + /** + * Move the current position back of a given amount of bytes. + * Not all readers may implement this function (a PEAR error will + * be returned if the reader can't rewind) + * + * @param int $length number of bytes to seek before the current pos + * or -1 to move back to the begining of the current file + * @return the number of bytes really rewinded (which may be less than + * $length if the current pos is less than $length + */ + function rewind($length = -1) + { + return PEAR::raiseError('Rewind function is not implemented on this reader'); + } + + /** + * Returns the current offset in the current file + */ + function tell() + { + $offset = $this->rewind(); + $this->skip($offset); + return $offset; + } + + /** + * Put back the reader in the state it was before the first call + * to next() + */ + function close() + { + } + + /** + * Sends the current file to the Writer $writer + * The data will be sent by chunks of at most $bufferSize bytes + * If $bufferSize <= 0 (default), the blockSize option is used + */ + function sendData(&$writer, $bufferSize = 0) + { + if (PEAR::isError($writer)) { + return $writer; + } + if ($bufferSize <= 0) { + $bufferSize = File_Archive::getOption('blockSize'); + } + + $filename = $this->getDataFilename(); + if ($filename !== null) { + $error = $writer->writeFile($filename); + if (PEAR::isError($error)) { + return $error; + } + } else { + while (($data = $this->getData($bufferSize)) !== null) { + if (PEAR::isError($data)) { + return $data; + } + $error = $writer->writeData($data); + if (PEAR::isError($error)) { + return $error; + } + } + } + } + + /** + * Sends the whole reader to $writer and close the reader + * + * @param File_Archive_Writer $writer Where to write the files of the reader + * @param bool $autoClose If true, close $writer at the end of the function. + * Default value is true + * @param int $bufferSize Size of the chunks that will be sent to the writer + * If $bufferSize <= 0 (default value), the blockSize option is used + */ + function extract(&$writer, $autoClose = true, $bufferSize = 0) + { + if (PEAR::isError($writer)) { + $this->close(); + return $writer; + } + + while (($error = $this->next()) === true) { + if ($writer->newFileNeedsMIME()) { + $mime = $this->getMime(); + } else { + $mime = null; + } + + $error = $writer->newFile( + $this->getFilename(), + $this->getStat(), + $mime + ); + if (PEAR::isError($error)) { + break; + } + $error = $this->sendData($writer, $bufferSize); + if (PEAR::isError($error)) { + break; + } + } + $this->close(); + if ($autoClose) { + $writer->close(); + } + if (PEAR::isError($error)) { + return $error; + } + } + + /** + * Extract only one file (given by the URL) + * + * @param string $filename URL of the file to extract from this + * @param File_Archive_Writer $writer Where to write the file + * @param bool $autoClose If true, close $writer at the end of the function + * Default value is true + * @param int $bufferSize Size of the chunks that will be sent to the writer + * If $bufferSize <= 0 (default value), the blockSize option is used + */ + function extractFile($filename, &$writer, + $autoClose = true, $bufferSize = 0) + { + if (PEAR::isError($writer)) { + return $writer; + } + + if (($error = $this->select($filename)) === true) { + $result = $this->sendData($writer, $bufferSize); + if (!PEAR::isError($result)) { + $result = true; + } + } else if ($error === false) { + $result = PEAR::raiseError("File $filename not found"); + } else { + $result = $error; + } + if ($autoClose) { + $error = $writer->close(); + if (PEAR::isError($error)) { + return $error; + } + } + return $result; + } + + /** + * Return a writer that allows appending files to the archive + * After having called makeAppendWriter, $this is closed and should not be + * used until the returned writer is closed. + * + * @return a writer that will allow to append files to an existing archive + * @see makeWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Predicate/False.php"; + return $this->makeWriterRemoveFiles(new File_Archive_Predicate_False()); + } + + /** + * Return a writer that has the same properties as the one returned by + * makeAppendWriter, but after having removed all the files that follow a + * given predicate. + * After a call to makeWriterRemoveFiles, $this is closed and should not + * be used until the returned writer is closed + * + * @param File_Archive_Predicate $pred the predicate verified by removed files + * @return File_Archive_Writer that allows to append files to the archive + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError("Reader abstract function call (makeWriterRemoveFiles)"); + } + + /** + * Returns a writer that removes the current file + * This is a syntaxic sugar for makeWriterRemoveFiles(new File_Archive_Predicate_Current()); + */ + function makeWriterRemove() + { + require_once "File/Archive/Predicate/Current.php"; + return $this->makeWriterRemoveFiles(new File_Archive_Predicate_Current()); + } + + /** + * Removes the current file from the reader + */ + function remove() + { + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + $writer->close(); + } + + /** + * Return a writer that has the same properties as the one returned by makeWriter, but after + * having removed a block of data from the current file. The writer will append data to the current file + * no data (other than the block) will be removed + * + * @param array Lengths of the blocks. The first one will be discarded, the second one kept, the third + * one discarded... If the sum of the blocks is less than the size of the file, the comportment is the + * same as if a last block was set in the array to reach the size of the file + * if $length is -1, the file is truncated from the specified pos + * It is possible to specify blocks of size 0 + * @param int $seek relative pos of the block + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + return PEAR::raiseError("Reader abstract function call (makeWriterRemoveBlocks)"); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Ar.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Ar.php new file mode 100644 index 0000000..60cb557 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Ar.php @@ -0,0 +1,387 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; + +/** + * Read an Ar archive + */ +class File_Archive_Reader_Ar extends File_Archive_Reader_Archive +{ + /** + * @var int The number of files to read to reach the end of the + * current ar file + * + * @access private + */ + var $_nbBytesLeft = 0; + + /** + * @var int The size of the header in number of bytes + * The header is not always 60 bytes since it sometimes + * contains a long filename + * @access private + */ + var $_header = 0; + + /** + * @var boolean Flag set if their is a 1 byte footer after the data + * of the current ar file + * + * @access private + */ + var $_footer = false; + + /** + * @var boolean Flag that has tell us if we have read the header of the + * current file + * @access private + */ + var $_alreadyRead = false; + + /** + * @var string Name of the file being read + * @access private + */ + var $_currentFilename = null; + + /** + * @var string Stat properties of the file being read + * It has: name, utime, uid, gid, mode, size and data + * @access private + */ + var $_currentStat = null; + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + return $this->_currentFilename; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->_currentFilename = null; + $this->_currentStat = null; + $this->_nbBytesLeft = 0; + $this->_header = 0; + $this->_footer = false; + $this->_alreadyRead = false; + return parent::close(); + } + + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() + { + return $this->_currentStat; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + $error = parent::next(); + if ($error !== true) { + return $error; + } + + $this->source->skip( + $this->_nbBytesLeft + ($this->_footer ? 1 : 0) + ); + + $filename = $this->source->getDataFilename(); + + if (!$this->_alreadyRead) { + $header = $this->source->getData(8); + if ($header != "!\n") { + return PEAR::raiseError("File {$filename} is not a valid Ar file format (starts with $header)"); + } + $this->_alreadyRead = true; + } + + + $name = $this->source->getData(16); + $mtime = $this->source->getData(12); + $uid = $this->source->getData(6); + $gid = $this->source->getData(6); + $mode = $this->source->getData(8); + $size = $this->source->getData(10); + $delim = $this->source->getData(2); + + if ($delim === null) { + return false; + } + + // All files inside should have more than 0 bytes of size + if ($size < 0) { + return PEAR::raiseError("Files must be at least one byte long"); + } + + $this->_footer = ($size % 2 == 1); + + // if the filename starts with a length, then just read the bytes of it + if (preg_match("/\#1\/(\d+)/", $name, $matches)) { + $this->_header = 60 + $matches[1]; + $name = $this->source->getData($matches[1]); + $size -= $matches[1]; + } else { + // strip trailing spaces in name, so we can distinguish spaces in a filename with padding + $this->_header = 60; + $name = preg_replace ("/\s+$/", "", $name); + } + + $this->_nbBytesLeft = $size; + if (empty($name) || empty($mtime) || empty($uid) || + empty($gid) || empty($mode) || empty($size)) { + return PEAR::raiseError("An ar field is empty"); + } + + $this->_currentFilename = $this->getStandardURL($name); + $this->_currentStat = array( + 2 => $mode, + 'mode' => $mode, + 4 => $uid, + 'uid' => $uid, + 5 => $gid, + 'gid' => $gid, + 7 => $size, + 'size' => $size, + 9 => $mtime, + 'mtime' => $mtime + ); + + return true; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $length = $this->_nbBytesLeft; + } else { + $length = min($length, $this->_nbBytesLeft); + } + if ($length == 0) { + return null; + } else { + $this->_nbBytesLeft -= $length; + $data = $this->source->getData($length); + if (PEAR::isError($data)) { + return $data; + } + if (strlen($data) != $length) { + return PEAR::raiseError('Unexpected end of Ar archive'); + } + return $data; + } + } + + /** + * @see File_Archive_Reader::skip + */ + function skip($length = -1) + { + if ($length == -1) { + $length = $this->_nbBytesLeft; + } else { + $length = min($length, $this->_nbBytesLeft); + } + if ($length == 0) { + return 0; + } else { + $this->_nbBytesLeft -= $length; + $skipped = $this->source->skip($length); + if (PEAR::isError($skipped)) { + return $skipped; + } + if ($skipped != $length) { + return PEAR::raiseError('Unexpected end of Ar archive'); + } + return $skipped; + } + } + + /** + * @see File_Archive_Reader::rewind + */ + function rewind($length = -1) + { + if ($length == -1) { + $length = $this->_currentStat[7] - $this->_nbBytesLeft; + } else { + $length = min($length, $this->_currentStat[7] - $this->_nbBytesLeft); + } + if ($length == 0) { + return 0; + } else { + $rewinded = $this->source->rewind($length); + if (!PEAR::isError($rewinded)) { + $this->_nbBytesLeft += $rewinded; + } + return $rewinded; + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->_currentStat[7] - $this->_nbBytesLeft; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + require_once "File/Archive/Writer/Ar.php"; + + $blocks = array(); + $seek = null; + $gap = 0; + if ($this->_currentFilename !== null && $pred->isTrue($this)) { + $seek = $this->_header + $this->_currentStat[7] + ($this->_footer ? 1 : 0); + $blocks[] = $seek; //Remove this file + } + + while (($error = $this->next()) === true) { + $size = $this->_header + $this->_currentStat[7] + ($this->_footer ? 1 : 0); + if ($pred->isTrue($this)) { + if ($seek === null) { + $seek = $size; + $blocks[] = $size; + } else if ($gap > 0) { + $blocks[] = $gap; //Don't remove the files between the gap + $blocks[] = $size; + $seek += $size; + } else { + $blocks[count($blocks)-1] += $size; //Also remove this file + $seek += $size; + } + $gap = 0; + } else { + if ($seek !== null) { + $seek += $size; + $gap += $size; + } + } + } + if ($seek === null) { + $seek = 0; + } else { + if ($gap == 0) { + array_pop($blocks); + } else { + $blocks[] = $gap; + } + } + + $writer = new File_Archive_Writer_Ar(null, + $this->source->makeWriterRemoveBlocks($blocks, -$seek) + ); + $this->close(); + return $writer; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + if ($this->_currentStat === null) { + return PEAR::raiseError('No file selected'); + } + + $blockPos = $this->_currentStat[7] - $this->_nbBytesLeft + $seek; + + $this->rewind(); + $keep = false; + + $data = $this->getData($blockPos); + foreach ($blocks as $length) { + if ($keep) { + $data .= $this->getData($length); + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + $data .= $this->getData(); + } + + $filename = $this->_currentFilename; + $stat = $this->_currentStat; + + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + + unset($stat[7]); + $writer->newFile($filename, $stat); + $writer->writeData($data); + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Ar.php"; + + while (($error = $this->next()) === true) { } + if (PEAR::isError($error)) { + $this->close(); + return $error; + } + + $innerWriter = $this->source->makeWriterRemoveBlocks(array()); + if (PEAR::isError($innerWriter)) { + return $innerWriter; + } + + unset($this->source); + $this->close(); + + return new File_Archive_Writer_Ar(null, $innerWriter); + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Archive.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Archive.php new file mode 100644 index 0000000..71050b6 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Archive.php @@ -0,0 +1,98 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Archive.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * Base class for all the archive readers (that read from a single file) + */ +class File_Archive_Reader_Archive extends File_Archive_Reader +{ + /** + * @var File_Archive_Reader Single file source that contains the archive + * to uncompress + * @access protected + */ + var $source = null; + + /** + * @var bool Indicate whether the $source is currently opened + * @access private + */ + var $sourceOpened = false; + + /** + * The source was let in this state at the end + * + * @var bool Indicate whether the $source was given opened + * @access private + */ + var $sourceInitiallyOpened; + +//ABSTRACT + /** + * @see File_Archive_Reader::next() + * + * Open the source if necessary + */ + function next() + { + if (!$this->sourceOpened && ($error = $this->source->next()) !== true) { + return $error; + } + + $this->sourceOpened = true; + return true; + } + +//PUBLIC + function File_Archive_Reader_Archive(&$source, $sourceOpened = false) + { + $this->source =& $source; + $this->sourceOpened = $this->sourceInitiallyOpened = $sourceOpened; + } + /** + * Close the source if it was given closed in the constructor + * + * @see File_Archive_Reader::close() + */ + function close() + { + if (!$this->sourceInitiallyOpened && $this->sourceOpened) { + $this->sourceOpened = false; + if ($this->source !== null) { + return $this->source->close(); + } + } + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Bzip2.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Bzip2.php new file mode 100644 index 0000000..80b0cfa --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Bzip2.php @@ -0,0 +1,254 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Bzip2.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; +require_once "File/Archive/Writer/Files.php"; + +/** + * Uncompress a file that was compressed in the Bzip2 format + */ +class File_Archive_Reader_Bzip2 extends File_Archive_Reader_Archive +{ + var $nbRead = 0; + var $bzfile = null; + var $tmpName = null; + var $filePos = 0; + + /** + * @see File_Archive_Reader::close() + */ + function close($innerClose = true) + { + if ($this->bzfile !== null) + bzclose($this->bzfile); + if ($this->tmpName !== null) + unlink($this->tmpName); + + $this->bzfile = null; + $this->tmpName = null; + $this->nbRead = 0; + $this->filePos = 0; + return parent::close($innerClose); + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + if (!parent::next()) { + return false; + } + + $this->nbRead++; + if ($this->nbRead > 1) { + return false; + } + + $dataFilename = $this->source->getDataFilename(); + if ($dataFilename !== null) + { + $this->tmpName = null; + $this->bzfile = @bzopen($dataFilename, 'r'); + if ($this->bzfile === false) { + return PEAR::raiseError("bzopen failed to open $dataFilename"); + } + } else { + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + + //Generate the tmp data + $dest = new File_Archive_Writer_Files(); + $dest->newFile($this->tmpName); + $this->source->sendData($dest); + $dest->close(); + + $this->bzfile = bzopen($this->tmpName, 'r'); + } + + return true; + } + /** + * Return the name of the single file contained in the archive + * deduced from the name of the archive (the extension is removed) + * + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + $name = $this->source->getFilename(); + $pos = strrpos($name, "."); + if ($pos === false || $pos === 0) { + return $name; + } else { + return substr($name, 0, $pos); + } + } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $data = ''; + do { + $newData = bzread($this->bzfile); + $data .= $newData; + } while ($newData != ''); + $this->filePos += strlen($data); + } else if ($length == 0) { + return ''; + } else { + $data = ''; + + //The loop is here to correct what appears to be a bzread bug + while (strlen($data) < $length) { + $newData = bzread($this->bzfile, $length - strlen($data)); + if ($newData == '') { + break; + } + $data .= $newData; + } + $this->filePos += strlen($data); + } + + return $data == '' ? null : $data; + } + + /** + * @see File_Archive_Reader::rewind + */ + function rewind($length = -1) + { + $before = $this->filePos; + + bzclose($this->bzfile); + if ($this->tmpName === null) { + $this->bzfile = bzopen($this->source->getDataFilename(), 'r'); + } else { + $this->bzfile = bzopen($this->tmpName, 'r'); + } + $this->filePos = 0; + + if ($length != -1) { + $this->skip($before - $length); + } + return $before - $this->filePos; + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->filePos; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + return PEAR::raiseError('Unable to append files to a bzip2 archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError('Unable to remove files from a bzip2 archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Bzip2.php"; + + if ($this->nbRead == 0) { + return PEAR::raiseError('No file selected'); + } + + //Uncompress data to a temporary file + $tmp = tmpfile(); + $expectedPos = $this->filePos + $seek; + + $this->rewind(); + + //Read the begining of the file + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + + $keep = false; + foreach ($blocks as $length) { + if ($keep) { + $expectedPos = $this->filePos + $length; + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + //Read the end of the file + while(($data = $this->getData(8192)) !== null) { + fwrite($tmp, $data); + } + } + fseek($tmp, 0); + + //Create the writer + $this->source->rewind(); + $innerWriter = $this->source->makeWriterRemoveBlocks(array()); //Truncate the source + unset($this->source); + $writer = new File_Archive_Writer_Bzip2(null, $innerWriter); + + //And compress data from the temporary file + while (!feof($tmp)) { + $data = fread($tmp, 8192); + $writer->writeData($data); + } + fclose($tmp); + + //Do not close inner writer since makeWriter was called + $this->close(); + + return $writer; + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Cache.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Cache.php new file mode 100644 index 0000000..5d676a1 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Cache.php @@ -0,0 +1,262 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Cache.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * This reader caches the files of another reader + * It allow fast access to files. This is usefull if the access to the reader + * is slow (HTTP, FTP...), but will need more IO if the file is only extracted + */ +class File_Archive_Reader_Cache extends File_Archive_Reader +{ + var $tmpFile; + var $files = array(); + var $pos = 0; + var $fromSource = true; + var $endOfSource = false; + var $source; + + /** + * $source is the reader to filter + */ + function File_Archive_Reader_Cache(&$source) + { + $this->source =& $source; + $this->tmpFile = tmpfile(); + } + + function _writeEndOfFile() + { + $bufferSize = File_Archive::getOption('blockSize'); + while (($data = $this->source->getData($bufferSize))!=null) { + fwrite($this->tmpFile, $data); + } + } + /** + * @see File_Archive_Reader::next() + */ + function next() + { + //Write the end of the current file to the temp file + if ($this->fromSource && !empty($this->files)) { + $this->_writeEndOfFile(); + } + + if ($this->pos+1 < count($this->files) && !$this->fromSource) { + $this->pos++; + fseek($this->tmpFile, $this->files[$this->pos]['pos'], SEEK_SET); + return true; + } else { + $this->fromSource = true; + if ($this->endOfSource) { + return false; + } + + $ret = $this->source->next(); + if ($ret !== true) { + $this->endOfSource = true; + $this->source->close(); + return $ret; + } + + $this->endOfSource = false; + fseek($this->tmpFile, 0, SEEK_END); + $this->files[] = array( + 'name' => $this->source->getFilename(), + 'stat' => $this->source->getStat(), + 'mime' => $this->source->getMime(), + 'pos' => ftell($this->tmpFile) + ); + $this->pos = count($this->files)-1; + + return true; + } + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->files[$this->pos]['name']; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->files[$this->pos]['stat']; } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() { return $this->files[$this->pos]['mime']; } + /** + * @see File_Archive_Reader::getDataFilename() + */ + function getDataFilename() { return null; } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->fromSource) { + $data = $this->source->getData($length); + if (PEAR::isError($data)) { + return $data; + } + + fwrite($this->tmpFile, $data); + return $data; + } else { + if ($length == 0) { + return ''; + } + + if ($length > 0 && $this->pos+1 < count($this->files)) { + $maxSize = $this->files[$this->pos+1]['pos'] - ftell($this->tmpFile); + if ($maxSize == 0) { + return null; + } + if ($length > $maxSize) { + $length = $maxSize; + } + return fread($this->tmpFile, $length); + } else { + $contents = ''; + $blockSize = File_Archive::getOption('blockSize'); + while (!feof($this->tmpFile)) { + $contents .= fread($this->tmpFile, $blockSize); + } + return $contents == '' ? null : $contents; + } + } + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($this->fromSource) { + return strlen($this->getData($length)); + } else { + if ($length >= 0 && $this->pos+1 < count($this->files)) { + $maxSize = $this->files[$this->pos+1]['pos'] - ftell($this->tmpFile); + if ($maxSize == 0) { + return null; + } + if ($length > $maxSize) { + $length = $maxSize; + } + fseek($this->tmpFile, $length, SEEK_CUR); + return $length; + } else { + $before = ftell($this->tmpFile); + fseek($this->tmpFile, 0, SEEK_SET); + $after = fteel($this->tmpFile); + return $after - $before; + } + } + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($this->fromSource) { + $this->_writeEndOfFile(); + $this->fromSource = false; + } + $before = ftell($this->tmpFile); + $pos = $this->files[$this->pos]['pos']; + fseek($this->tmpFile, $pos, SEEK_SET); + return $pos - $before; + } + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return ftell($this->tmpFile) - $this->files[$this->pos]['pos']; + } + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->fromSource = false; + $this->pos = 0; + fseek($this->tmpFile, 0, SEEK_SET); + } + function _closeAndReset() + { + $this->close(); + + fclose($this->tmpFile); + $this->tmpFile = tmpfile(); + $this->endOfSource = false; + $this->files = array(); + $this->source->close(); + } + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + $writer = $this->source->makeAppendWriter(); + if (!PEAR::isError($writer)) { + $this->_closeAndReset(); + } + + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + $writer = $this->source->makeWriterRemoveFiles($pred); + if (!PEAR::isError($writer)) { + $this->_closeAndReset(); + } + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + $writer = $this->source->makeWriterRemoveBlocks($blocks, $seek); + if (!PEAR::isError($writer)) { + $this->_closeAndReset(); + } + return $writer; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName.php new file mode 100644 index 0000000..985145e --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName.php @@ -0,0 +1,136 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: ChangeName.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Base class for readers that need to modify the name of files + */ +class File_Archive_Reader_ChangeName extends File_Archive_Reader_Relay +{ + /** + * Modify the name + * + * @param string $name Name as in the inner reader + * @return string New name as shown by this reader or false is the + * file or directory has to be skipped + */ + function modifyName($name) + { + } + + /** + * Modify the name back to the inner reader naming style + * If implemented, unmodifyName(modifyName($name)) should be true + * + * unmodifyName can be left unimplemented, this may only impact the + * efficiency of the select function (a full look up will be done when + * something more efficient with an index for example could be used on + * the inner reader of the original name is known). + * + * unmodifyName may be provided some names that where not in the inner reader + * and that cannot possibly be the result of modifyName. In this case + * unmodifyName must return false. + * + * @param string $name Name as shown by this reader + * @return string Name as in the inner reader, or false if there is no + * input such that modifyName would return $name or a file in + * a directory called $name + */ + function unmodifyName($name) + { + return null; + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + return $this->getStandardURL($this->modifyName(parent::getFilename())); + } + /** + * @see File_Archive_Reader::getFileList() + */ + function getFileList() + { + $list = parent::getFileList(); + $result = array(); + foreach ($list as $name) { + $result[] = $this->modifyName($name); + } + return $result; + } + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + $name = $this->unmodifyName($filename); + if ($name === false) { + return false; + } else if($name === null) { + $std = $this->getStandardURL($filename); + if (substr($std, -1)=='/') { + $std = substr($std, 0, -1); + } + + if ($close) { + $error = $this->close(); + if (PEAR::isError($error)) { + return $error; + } + } + while (($error = $this->next()) === true) { + $sourceName = $this->getFilename(); + $sourceName = $this->modifyName($sourceName, $this->isDirectory()); + $sourceName = $this->getStandardURL($sourceName); + if ( + empty($std) || + + //$std is a file + $std == $sourceName || + + //$std is a directory + (strncmp($std.'/', $sourceName, strlen($std)+1) == 0 && + strlen($sourceName) > strlen($std)+1) + ) { + return true; + } + } + return $error; + } else { + return $this->source->select($name, $close); + } + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/AddDirectory.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/AddDirectory.php new file mode 100644 index 0000000..42541c7 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/AddDirectory.php @@ -0,0 +1,89 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: AddDirectory.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/ChangeName.php"; + +/** + * Add a directory to the public name of all the files of a reader + * + * Example: + * If archive.tar is a file archive containing files a.txt and foo/b.txt + * new File_Archive_Reader_ChangeName_AddDirectory('bar', + * new File_Archive_Reader_Tar( + * new File_Archive_Reader_File('archive.tar') + * ) + * ) is a reader containing files bar/a.txt and bar/foo/b.txt + */ +class File_Archive_Reader_ChangeName_AddDirectory extends File_Archive_Reader_ChangeName +{ + var $baseName; + function File_Archive_Reader_ChangeName_AddDirectory($baseName, &$source) + { + // see http://pear.php.net/bugs/bug.php?id=17046&edit=12&patch=AddDirectory.php.patch&revision=1264868437 +// parent::File_Archive_Reader_ChangeName($source); + parent::__construct($source); + $this->baseName = $this->getStandardURL($baseName); + } + + /** + * Modify the name by adding baseName to it + */ + function modifyName($name) + { + return $this->baseName. + (empty($this->baseName) || empty($name) ? '': '/'). + $name; + } + + /** + * Remove baseName from the name + * Return false if the name doesn't start with baseName + */ + function unmodifyName($name) + { + if (strncmp($name, $this->baseName.'/', strlen($this->baseName)+1) == 0) { + $res = substr($name, strlen($this->baseName)+1); + if ($res === false) { + return ''; + } else { + return $res; + } + } else if (empty($this->baseName)) { + return $name; + } else if ($name == $this->baseName) { + return ''; + } else { + return false; + } + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/Callback.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/Callback.php new file mode 100644 index 0000000..32616a7 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/Callback.php @@ -0,0 +1,52 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Callback.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/ChangeName.php"; + +/** + * Discard the directory structure in a reader + */ +class File_Archive_Reader_ChangeName_Callback extends File_Archive_Reader_ChangeName +{ + var $function; + function File_Archive_Reader_ChangeName_Callback($function, &$source) + { + parent::File_Archive_Reader_ChangeName($source); + $this->function = $function; + } + + function modifyName($name) + { + return call_user_func($function, $name); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/Directory.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/Directory.php new file mode 100644 index 0000000..70e9550 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/ChangeName/Directory.php @@ -0,0 +1,100 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Directory.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/ChangeName.php"; + +/** + * Change a directory name to another + * + * Example: + * If archive.tar is a file archive containing files a.txt and foo/b.txt + * new File_Archive_Reader_ChangeName_Directory('foo', 'bar' + * new File_Archive_Reader_Tar( + * new File_Archive_Reader_File('archive.tar') + * ) + * ) is a reader containing files a.txt and bar/b.txt + */ +class File_Archive_Reader_ChangeName_Directory extends File_Archive_Reader_ChangeName +{ + var $oldBaseName; + var $newBaseName; + + function File_Archive_Reader_ChangeName_Directory + ($oldBaseName, $newBaseName, &$source) + { +// parent::File_Archive_Reader_ChangeName($source); + parent::__construct($source); + $this->oldBaseName = $this->getStandardURL($oldBaseName); + if (substr($this->oldBaseName, -1) == '/') { + $this->oldBaseName = substr($this->oldBaseName, 0, -1); + } + + $this->newBaseName = $this->getStandardURL($newBaseName); + if (substr($this->newBaseName, -1) == '/') { + $this->newBaseName = substr($this->newBaseName, 0, -1); + } + } + + function modifyName($name) + { + if (empty($this->oldBaseName) || + !strncmp($name, $this->oldBaseName.'/', strlen($this->oldBaseName)+1) || + strcmp($name, $this->oldBaseName) == 0) { + return $this->newBaseName. + ( + empty($this->newBaseName) || + strlen($name)<=strlen($this->oldBaseName)+1 ? + '' : '/' + ). + substr($name, strlen($this->oldBaseName)+1); + } else { + return $name; + } + } + function unmodifyName($name) + { + if (empty($this->newBaseName) || + !strncmp($name, $this->newBaseName.'/', strlen($this->newBaseName)+1) || + strcmp($name, $this->newBaseName) == 0) { + return $this->oldBaseName. + ( + empty($this->oldBaseName) || + strlen($name)<=strlen($this->newBaseName)+1 ? + '' : '/' + ). + substr($name, strlen($this->newBaseName)+1); + } else { + return $name; + } + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Concat.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Concat.php new file mode 100644 index 0000000..2997126 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Concat.php @@ -0,0 +1,195 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Concat.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * This reader provides one single file that is the concatenation of the data of + * all the files of another reader + */ +class File_Archive_Reader_Concat extends File_Archive_Reader +{ + var $source; + var $filename; + var $stat; + var $mime; + var $opened = false; + var $filePos = 0; + + function File_Archive_Reader_Concat(&$source, $filename, + $stat=array(), $mime=null) + { + $this->source =& $source; + $this->filename = $filename; + $this->stat = $stat; + $this->mime = $mime; + + //Compute the total length + $this->stat[7] = 0; + while (($error = $source->next()) === true) { + $sourceStat = $source->getStat(); + if (isset($sourceStat[7])) { + $this->stat[7] += $sourceStat[7]; + } else { + unset($this->stat[7]); + break; + } + } + if (isset($this->stat[7])) { + $this->stat['size'] = $this->stat[7]; + } + if (PEAR::isError($error) || PEAR::isError($source->close())) { + die("Error in File_Archive_Reader_Concat constructor ". + '('.$error->getMessage().'), cannot continue'); + } + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + if (!$this->opened) { + return $this->opened = $this->source->next(); + } else { + return false; + } + } + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->filename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->stat; } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() + { + return $this->mime==null ? parent::getMime() : $this->mime; + } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == 0) { + return ''; + } + + $result = ''; + while ($length == -1 || strlen($result)<$length) { + $sourceData = $this->source->getData( + $length==-1 ? -1 : $length - strlen($result) + ); + if (PEAR::isError($sourceData)) { + return $sourceData; + } + + if ($sourceData === null) { + $error = $this->source->next(); + if (PEAR::isError($error)) { + return $error; + } + if (!$error) { + break; + } + } else { + $result .= $sourceData; + } + } + $this->filePos += strlen($result); + return $result == '' ? null : $result; + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + $skipped = 0; + while ($skipped < $length) { + $sourceSkipped = $this->source->skip($length); + if (PEAR::isError($sourceSkipped)) { + return $skipped; + } + $skipped += $sourceSkipped; + $filePos += $sourceSkipped; + if ($sourceSkipped < $length) { + $error = $this->source->next(); + if (PEAR::isError($error)) { + return $error; + } + if (!$error) { + return $skipped; + } + } + } + return $skipped; + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + //TODO: implement rewind + return parent::rewind($length); + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->filePos; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->opened = false; + $this->filePos = 0; + return $this->source->close(); + } + + /** + * @see File_Archive_Reader::makeWriter + */ + function makeWriter($fileModif = true, $seek = 0) + { + return $this->source->makeWriter($fileModif, $seek); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Directory.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Directory.php new file mode 100644 index 0000000..e59daed --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Directory.php @@ -0,0 +1,309 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Directory.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; +require_once "File/Archive/Reader/File.php"; + +/** + * Recursively reads a directory + */ +class File_Archive_Reader_Directory extends File_Archive_Reader_Relay +{ + /** + * @var String URL of the directory that must be read + * @access private + */ + var $directory; + /** + * @var Int The subdirectories will be read up to a depth of maxRecurs + * If maxRecurs == 0, the subdirectories will not be read + * If maxRecurs == -1, the depth is considered infinite + * @access private + */ + var $maxRecurs; + /** + * @var Object Handle returned by the openedDirectory function + * @access private + */ + var $directoryHandle = null; + + /** + * $directory is the path of the directory that must be read + * If $maxRecurs is specified, the subdirectories will be read up to a depth + * of $maxRecurs. In particular, if $maxRecurs == 0, the subdirectories + * won't be read. + */ + function File_Archive_Reader_Directory($directory, $symbolic='', + $maxRecurs=-1) + { + parent::File_Archive_Reader_Relay($tmp = null); + $this->directory = empty($directory) ? '.' : $directory; + $this->symbolic = $this->getStandardURL($symbolic); + $this->maxRecurs = $maxRecurs; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $error = parent::close(); + + if ($this->directoryHandle !== null) { + closedir($this->directoryHandle); + $this->directoryHandle = null; + } + + return $error; + } + + /** + * @see File_Archive_Reader::next() + * + * The files are returned in the same order as readdir + */ + function next() + { + if ($this->directoryHandle === null) { + $this->directoryHandle = opendir($this->directory); + if (!is_resource($this->directoryHandle)) { + return PEAR::raiseError( + "Directory {$this->directory} not found" + ); + } + $this->source = null; + + if (!empty($this->symbolic)) + return true; + } + + while ($this->source === null || + ($error = $this->source->next()) !== true) { + + if ($this->source !== null) { + $this->source->close(); + } + + $file = readdir($this->directoryHandle); + if ($file == '.' || $file == '..') { + continue; + } + if ($file === false) { + return false; + } + + $current = $this->directory.'/'.$file; + if (is_dir($current)) { + if ($this->maxRecurs != 0) { + $this->source = new File_Archive_Reader_Directory( + $current, $file.'/', $this->maxRecurs-1 + ); + } + + } else { + $this->source = new File_Archive_Reader_File($current, $file); + } + } + + return $error; + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + if ($this->source === null) { + return $this->symbolic; + } else { + return $this->symbolic . parent::getFilename(); + } + } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() + { + if ($this->source === null) { + return stat($this->directory); + } else { + return parent::getStat(); + } + } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() + { + if ($this->source === null) { + return ''; + } else { + return parent::getMime(); + } + } + /** + * @see File_Archive_Reader::getDataFilename() + */ + function getDataFilename() + { + if ($this->source === null) { + return null; + } else { + return parent::getDataFilename(); + } + } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->source === null) { + return null; + } else { + return parent::getData($length); + } + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($this->source === null) { + return 0; + } else { + return parent::skip($length); + } + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($this->source === null) { + return 0; + } else { + return parent::rewind($length); + } + } + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + if ($this->source === null) { + return 0; + } else { + return parent::tell(); + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + if ($source !== null && $pred->isTrue($this)) { + $toUnlink = $this->getDataFilename(); + } else { + $toUnlink = null; + } + + while ($this->next()) { + if ($toUnlink !== null && + !@unlink($toUnlink)) { + return PEAR::raiseError("Unable to unlink $toUnlink"); + } + $toUnlink = ($pred->isTrue($this) ? $this->getDataFilename() : null); + } + if ($toUnlink !== null && + !@unlink("Unable to unlink $toUnlink")) { + return PEAR::raiseError($pred); + } + + require_once "File/Archive/Writer/Files.php"; + + $writer = new File_Archive_Writer_Files($this->directory); + $this->close(); + return $writer; + } + + function &getLastSource() + { + if ($this->source === null || + is_a($this->source, 'File_Archive_Reader_File')) { + return $this->source; + } else { + return $this->source->getLastSource(); + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + $lastSource = &$this->getLastSource(); + if ($lastSource === null) { + return PEAR::raiseError('No file selected'); + } + + require_once "File/Archive/Writer/Files.php"; + + $writer = $lastSource->makeWriterRemoveBlocks($blocks, $seek); + if (!PEAR::isError($writer)) { + $writer->basePath = $this->directory; + $this->close(); + } + + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Files.php"; + + if ($this->source === null || + is_a($this->source, 'File_Archive_Reader_File') ) { + $writer = new File_Archive_Writer_Files($this->directory); + } else { + $writer = $this->source->makeAppendWriter($seek); + } + + $this->close(); + + return $writer; + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/File.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/File.php new file mode 100644 index 0000000..2b7694c --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/File.php @@ -0,0 +1,296 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: File.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; +require_once "MIME/Type.php"; + +/** + * Reader that represents a single file + */ +class File_Archive_Reader_File extends File_Archive_Reader +{ + /** + * @var object Handle to the file being read + * @access private + */ + var $handle = null; + /** + * @var string Name of the physical file being read + * @access private + */ + var $filename; + /** + * @var string Name of the file returned by the reader + * @access private + */ + var $symbolic; + /** + * @var array Stats of the file + * Will only be set after a call to $this->getStat() + * @access private + */ + var $stat = null; + /** + * @var string Mime type of the file + * Will only be set after a call to $this->getMime() + */ + var $mime = null; + /** + * @var boolean Has the file already been read + * @access private + */ + var $alreadyRead = false; + + /** + * $filename is the physical file to read + * $symbolic is the name declared by the reader + * If $symbolic is not specified, $filename is assumed + */ + function File_Archive_Reader_File($filename, $symbolic = null, $mime = null) + { + $this->filename = $filename; + $this->mime = $mime; + if ($symbolic === null) { + $this->symbolic = $this->getStandardURL($filename); + } else { + $this->symbolic = $this->getStandardURL($symbolic); + } + } + /** + * @see File_Archive_Reader::close() + * + * Close the file handle + */ + function close() + { + $this->alreadyRead = false; + if ($this->handle !== null) { + fclose($this->handle); + $this->handle = null; + } + } + /** + * @see File_Archive_Reader::next() + * + * The first time next is called, it will open the file handle and return + * true. Then it will return false + * Raise an error if the file does not exist + */ + function next() + { + if ($this->alreadyRead) { + return false; + } else { + $this->alreadyRead = true; + return true; + } + } + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->symbolic; } + /** + * @see File_Archive_Reader::getDataFilename() + * + * Return the name of the file + */ + function getDataFilename() { return $this->filename; } + /** + * @see File_Archive_Reader::getStat() stat() + */ + function getStat() + { + if ($this->stat === null) { + $this->stat = @stat($this->filename); + + //If we can't use the stat function + if ($this->stat === false) { + $this->stat = array(); + } + } + return $this->stat; + } + + /** + * @see File_Archive_Reader::getMime + */ + function getMime() + { + if ($this->mime === null) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $this->mime = MIME_Type::autoDetect($this->getDataFilename()); + PEAR::popErrorHandling(); + + if (PEAR::isError($this->mime)) { + $this->mime = parent::getMime(); + } + } + return $this->mime; + } + + /** + * Opens the file if it was not already opened + */ + function _ensureFileOpened() + { + if ($this->handle === null) { + $this->handle = @fopen($this->filename, "r"); + + if (!is_resource($this->handle)) { + $this->handle = null; + return PEAR::raiseError("Can't open {$this->filename} for reading"); + } + if ($this->handle === false) { + $this->handle = null; + return PEAR::raiseError("File {$this->filename} not found"); + } + } + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + $error = $this->_ensureFileOpened(); + if (PEAR::isError($error)) { + return $error; + } + + if (feof($this->handle)) { + return null; + } + if ($length == -1) { + $contents = ''; + $blockSize = File_Archive::getOption('blockSize'); + while (!feof($this->handle)) { + $contents .= fread($this->handle, $blockSize); + } + return $contents; + } else { + if ($length == 0) { + return ""; + } else { + return fread($this->handle, $length); + } + } + } + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + $error = $this->_ensureFileOpened(); + if (PEAR::isError($error)) { + return $error; + } + + $before = ftell($this->handle); + if (($length == -1 && @fseek($this->handle, 0, SEEK_END) === -1) || + ($length >= 0 && @fseek($this->handle, $length, SEEK_CUR) === -1)) { + return parent::skip($length); + } else { + return ftell($this->handle) - $before; + } + } + + /** + * @see File_Archive_Reader::rewind + */ + function rewind($length = -1) + { + if ($this->handle === null) { + return 0; + } + + $before = ftell($this->handle); + if (($length == -1 && @fseek($this->handle, 0, SEEK_SET) === -1) || + ($length >= 0 && @fseek($this->handle, -$length, SEEK_CUR) === -1)) { + return parent::rewind($length); + } else { + return $before - ftell($this->handle); + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + if ($this->handle === null) { + return 0; + } else { + return ftell($this->handle); + } + } + + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError( + 'File_Archive_Reader_File represents a single file, you cant remove it'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Files.php"; + + $writer = new File_Archive_Writer_Files(); + + $file = $this->getDataFilename(); + $pos = $this->tell(); + $this->close(); + + $writer->openFileRemoveBlock($file, $pos + $seek, $blocks); + + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + return PEAR::raiseError( + 'File_Archive_Reader_File represents a single file.'. + ' makeAppendWriter cant be executed on it' + ); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Filter.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Filter.php new file mode 100644 index 0000000..3422414 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Filter.php @@ -0,0 +1,90 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Filter.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Filter out the files that do not respect a given predicat + */ +class File_Archive_Reader_Filter extends File_Archive_Reader_Relay +{ + /** + * @var File_Archive_Reader_Predicat + * @access private + */ + var $predicate; + + /** + * $source is the reader to filter + */ + function File_Archive_Reader_Filter($predicate, &$source) + { + parent::File_Archive_Reader_Relay($source); + $this->predicate = $predicate; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + do { + $error = $this->source->next(); + if ($error !== true) { + return $error; + } + } while (!$this->predicate->isTrue($this->source)); + return true; + } + + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + if ($close) { + $error = $this->close(); + if (PEAR::isError($error)) { + return $error; + } + } + + do { + $error = $this->source->select($filename, false); + if ($error !== true) { + return $error; + } + } while (!$this->predicate->isTrue($this->source)); + return true; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Gzip.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Gzip.php new file mode 100644 index 0000000..82d190f --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Gzip.php @@ -0,0 +1,276 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Gzip.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; +require_once "File/Archive/Writer/Files.php"; + +/** + * Uncompress a file that was compressed in the Gzip format + */ +class File_Archive_Reader_Gzip extends File_Archive_Reader_Archive +{ + var $nbRead = 0; + var $filePos = 0; + var $gzfile = null; + var $tmpName = null; + + /** + * @see File_Archive_Reader::close() + */ + function close($innerClose = true) + { + if ($this->gzfile !== null) { + gzclose($this->gzfile); + } + if ($this->tmpName !== null) { + unlink($this->tmpName); + } + + $this->nbRead = 0; + $this->filePos = 0; + $this->gzfile = null; + $this->tmpName = null; + + return parent::close($innerClose); + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + if (!parent::next()) { + return false; + } + + $this->nbRead++; + $this->filePos = 0; + if ($this->nbRead > 1) { + return false; + } + + $dataFilename = $this->source->getDataFilename(); + if ($dataFilename !== null) + { + $this->tmpName = null; + $this->gzfile = gzopen($dataFilename, 'r'); + } else { + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + + //Generate the tmp data + $dest = new File_Archive_Writer_Files(); + $dest->newFile($this->tmpName); + $this->source->sendData($dest); + $dest->close(); + + $this->gzfile = gzopen($this->tmpName, 'r'); + } + + return true; + } + + /** + * Return the name of the single file contained in the archive + * deduced from the name of the archive (the extension is removed) + * + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + $name = $this->source->getFilename(); + $slashPos = strrpos($name, '/'); + if ($slashPos !== false) { + $name = substr($name, $slashPos+1); + } + $dotPos = strrpos($name, '.'); + if ($dotPos !== false && $dotPos > 0) { + $name = substr($name, 0, $dotPos); + } + + return $name; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $data = ''; + do + { + $newData = gzread($this->gzfile, 8192); + $data .= $newData; + } while ($newData != ''); + } else if ($length == 0) { + return ''; + } else { + $data = gzread($this->gzfile, $length); + } + + $this->filePos += strlen($data); + return $data == '' ? null : $data; + } + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if($length == -1) { + do + { + $tmp = gzread($this->gzfile, 8192); + $this->filePos += strlen($tmp); + } while ($tmp != ''); + } else { + if (@gzseek($this->gzfile, $this->filePos + $length) === -1) { + return parent::skip($length); + } else { + $this->filePos += $length; + return $length; + } + } + } + + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($length == -1) { + if (@gzseek($this->gzfile, 0) === -1) { + return parent::rewind($length); + } else { + $tmp = $this->filePos; + $this->filePos = 0; + return $tmp; + } + } else { + $length = min($length, $this->filePos); + if (@gzseek($this->gzfile, $this->filePos - $length) === -1) { + return parent::rewind($length); + } else { + $this->filePos -= $length; + return $length; + } + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->filePos; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + return PEAR::raiseError('Unable to append files to a gzip archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError('Unable to remove files from a gzip archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Gzip.php"; + + if ($this->nbRead == 0) { + return PEAR::raiseError('No file selected'); + } + + //Uncompress data to a temporary file + $tmp = tmpfile(); + $expectedPos = $this->filePos + $seek; + $this->rewind(); + + //Read the begining of the file + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + + $keep = false; + foreach ($blocks as $length) { + if ($keep) { + $expectedPos = $this->filePos + $length; + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + //Read the end of the file + while(($data = $this->getData(8192)) !== null) { + fwrite($tmp, $data); + } + } + fseek($tmp, 0); + + //Create the writer + $this->source->rewind(); + $innerWriter = $this->source->makeWriterRemoveBlocks(array()); //Truncate the source + unset($this->source); + $writer = new File_Archive_Writer_Gzip(null, $innerWriter); + + //And compress data from the temporary file + while (!feof($tmp)) { + $data = fread($tmp, 8192); + $writer->writeData($data); + } + fclose($tmp); + + //Do not close inner writer since makeWriter was called + $this->close(); + + return $writer; + } + +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Memory.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Memory.php new file mode 100644 index 0000000..3caa2b5 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Memory.php @@ -0,0 +1,227 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Memory.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * A reader that takes its input from a memory buffer + */ +class File_Archive_Reader_Memory extends File_Archive_Reader +{ + /** + * @var String Name of the file exported by this reader + * @access private + */ + var $filename; + /** + * @var Array Stat of the file exported by this reader + * @access private + */ + var $stat; + /** + * @var String MIME type of the file exported by this reader + * @access private + */ + var $mime; + /** + * @var String Memory buffer that contains the data of the file + * @access private + */ + var $memory; + /** + * @var Int Current position in the file + * @access private + */ + var $offset = 0; + /** + * @var Boolean Has the file already been read + * @access private + */ + var $alreadyRead = false; + + /** + * @param string $memory is the content of the file. + * This parameter is passed as a reference for performance + * reasons. The content should not be changer after the constructor + * @param string $filename is the name of the file + * @param array $stat are the statistics of the file. The size will be + * recomputed from $memory + * @param string $mime is the mime type of the file + */ + function File_Archive_Reader_Memory(&$memory, $filename, + $stat=array(), $mime=null) + { + $this->memory = &$memory; + $this->filename = $this->getStandardURL($filename); + $this->stat = $stat; + $this->stat[7] = $this->stat['size'] = strlen($this->memory); + $this->mime = $mime; + } + + /** + * The subclass should overwrite this function to change the filename, stat + * and memory + */ + function next() + { + if ($this->alreadyRead) { + return false; + } else { + $this->alreadyRead = true; + return true; + } + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->filename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->stat; } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() + { + return $this->mime==null ? parent::getMime() : $this->mime; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->offset == strlen($this->memory)) { + return null; + } + if ($length == -1) { + $actualLength = strlen($this->memory) - $this->offset; + } else { + $actualLength = min($length, strlen($this->memory) - $this->offset); + } + $result = substr($this->memory, $this->offset, $actualLength); + $this->offset += $actualLength; + return $result; + } + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($length == -1) { + $length = strlen($this->memory) - $this->offset; + } else { + $length = min($length, strlen($this->memory) - $this->offset); + } + $this->offset += $length; + return $length; + } + + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($length == -1) { + $tmp = $this->offset; + $this->offset = 0; + return $tmp; + } else { + $length = min($length, $this->offset); + $this->offset -= $length; + return $length; + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->offset; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->offset = 0; + $this->alreadyRead = false; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + return PEAR::raiseError('Unable to append files to a memory archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError('Unable to remove files from a memory archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Memory.php"; + $data = substr($this->memory, 0, $this->offset + $seek); + $this->memory = substr($this->memory, $this->offset + $seek); + + $keep = false; + foreach ($blocks as $length) { + if ($keep) { + $data .= substr($this->memory, 0, $length); + } + $this->memory = substr($this->memory, $length); + $keep = !$keep; + } + if ($keep) { + $this->memory = $data . $this->memory; + } else { + $this->memory = $data; + } + $this->close(); + return new File_Archive_Writer_Memory($this->memory, strlen($this->memory)); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/MimeList.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/MimeList.php new file mode 100644 index 0000000..cc203ef --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/MimeList.php @@ -0,0 +1,939 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MimeList.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +/** + * Returns the MIME of the filename, deducted from its extension + * If the extension is unknown, returns "application/octet-stream" + */ +function File_Archive_Reader_GetMime($filename) +{ + $pos = strrpos($filename, '.'); + $extension = ""; + if ($pos !== false) { + $extension = strtolower(substr($filename, $pos+1)); + } + + switch($extension) { + case '3dmf': + return 'x-world/x-3dmf'; + case 'a': + return 'application/octet-stream'; + case 'aab': + return 'application/x-authorware-bin'; + case 'aam': + return 'application/x-authorware-map'; + case 'aas': + return 'application/x-authorware-seg'; + case 'abc': + return 'text/vnd.abc'; + case 'acgi': + return 'text/html'; + case 'afl': + return 'video/animaflex'; + case 'ai': + return 'application/postscript'; + case 'aif': + return 'audio/aiff'; + case 'aifc': + return 'audio/aiff'; + case 'aiff': + return 'audio/aiff'; + case 'aim': + return 'application/x-aim'; + case 'aip': + return 'text/x-audiosoft-intra'; + case 'ani': + return 'application/x-navi-animation'; + case 'aos': + return 'application/x-nokia-9000-communicator-add-on-software'; + case 'aps': + return 'application/mime'; + case 'arc': + return 'application/octet-stream'; + case 'arj': + return 'application/arj'; + case 'art': + return 'image/x-jg'; + case 'asf': + return 'video/x-ms-asf'; + case 'asm': + return 'text/x-asm'; + case 'asp': + return 'text/asp'; + case 'asx': + return 'application/x-mplayer2'; + case 'au': + return 'audio/basic'; + case 'avi': + return 'application/x-troff-msvideo'; + case 'avs': + return 'video/avs-video'; + case 'bcpio': + return 'application/x-bcpio'; + case 'bin': + return 'application/x-binary'; + case 'bm': + return 'image/bmp'; + case 'bmp': + return 'image/bmp'; + case 'boo': + return 'application/book'; + case 'book': + return 'application/book'; + case 'boz': + return 'application/x-bzip2'; + case 'bsh': + return 'application/x-bsh'; + case 'bz': + return 'application/x-bzip'; + case 'bz2': + return 'application/x-bzip2'; + case 'c': + return 'text/plain'; + case 'c++': + return 'text/plain'; + case 'cat': + return 'application/vnd.ms-pki.seccat'; + case 'cc': + return 'text/plain'; + case 'ccad': + return 'application/clariscad'; + case 'cco': + return 'application/x-cocoa'; + case 'cdf': + return 'application/cdf'; + case 'cer': + return 'application/pkix-cert'; + case 'cha': + return 'application/x-chat'; + case 'chat': + return 'application/x-chat'; + case 'class': + return 'application/java'; + case 'com': + return 'application/octet-stream'; + case 'conf': + return 'text/plain'; + case 'cpio': + return 'application/x-cpio'; + case 'cpp': + return 'text/x-c'; + case 'cpt': + return 'application/mac-compactpro'; + case 'crl': + return 'application/pkcs-crl'; + case 'csh': + return 'application/x-csh'; + case 'css': + return 'text/css'; + case 'cxx': + return 'text/plain'; + case 'dcr': + return 'application/x-director'; + case 'deepv': + return 'application/x-deepv'; + case 'def': + return 'text/plain'; + case 'der': + return 'application/x-x509-ca-cert'; + case 'dif': + return 'video/x-dv'; + case 'dir': + return 'application/x-director'; + case 'dl': + return 'video/dl'; + case 'doc': + return 'application/msword'; + case 'dot': + return 'application/msword'; + case 'dp': + return 'application/commonground'; + case 'drw': + return 'application/drafting'; + case 'dump': + return 'application/octet-stream'; + case 'dv': + return 'video/x-dv'; + case 'dvi': + return 'application/x-dvi'; + case 'dwf': + return 'drawing/x-dwf (old)'; + case 'dwg': + return 'application/acad'; + case 'dxf': + return 'application/dxf'; + case 'dxr': + return 'application/x-director'; + case 'el': + return 'text/x-script.elisp'; + case 'elc': + return 'application/x-bytecode.elisp (compiled elisp)'; + case 'env': + return 'application/x-envoy'; + case 'eps': + return 'application/postscript'; + case 'es': + return 'application/x-esrehber'; + case 'etx': + return 'text/x-setext'; + case 'evy': + return 'application/envoy'; + case 'exe': + return 'application/octet-stream'; + case 'f': + return 'text/plain'; + case 'f77': + return 'text/x-fortran'; + case 'f90': + return 'text/plain'; + case 'fdf': + return 'application/vnd.fdf'; + case 'fif': + return 'application/fractals'; + case 'fli': + return 'video/fli'; + case 'flo': + return 'image/florian'; + case 'flx': + return 'text/vnd.fmi.flexstor'; + case 'fmf': + return 'video/x-atomic3d-feature'; + case 'for': + return 'text/plain'; + case 'fpx': + return 'image/vnd.fpx'; + case 'frl': + return 'application/freeloader'; + case 'funk': + return 'audio/make'; + case 'g': + return 'text/plain'; + case 'g3': + return 'image/g3fax'; + case 'gif': + return 'image/gif'; + case 'gl': + return 'video/gl'; + case 'gsd': + return 'audio/x-gsm'; + case 'gsm': + return 'audio/x-gsm'; + case 'gsp': + return 'application/x-gsp'; + case 'gss': + return 'application/x-gss'; + case 'gtar': + return 'application/x-gtar'; + case 'gz': + return 'application/x-compressed'; + case 'gzip': + return 'application/x-gzip'; + case 'h': + return 'text/plain'; + case 'hdf': + return 'application/x-hdf'; + case 'help': + return 'application/x-helpfile'; + case 'hgl': + return 'application/vnd.hp-hpgl'; + case 'hh': + return 'text/plain'; + case 'hlb': + return 'text/x-script'; + case 'hlp': + return 'application/hlp'; + case 'hpg': + return 'application/vnd.hp-hpgl'; + case 'hpgl': + return 'application/vnd.hp-hpgl'; + case 'hqx': + return 'application/binhex'; + case 'hta': + return 'application/hta'; + case 'htc': + return 'text/x-component'; + case 'htm': + return 'text/html'; + case 'html': + return 'text/html'; + case 'htmls': + return 'text/html'; + case 'htt': + return 'text/webviewhtml'; + case 'htx': + return 'text/html'; + case 'ice': + return 'x-conference/x-cooltalk'; + case 'ico': + return 'image/x-icon'; + case 'idc': + return 'text/plain'; + case 'ief': + return 'image/ief'; + case 'iefs': + return 'image/ief'; + case 'iges': + return 'application/iges'; + case 'igs': + return 'application/iges'; + case 'ima': + return 'application/x-ima'; + case 'imap': + return 'application/x-httpd-imap'; + case 'inf': + return 'application/inf'; + case 'ins': + return 'application/x-internett-signup'; + case 'ip': + return 'application/x-ip2'; + case 'isu': + return 'video/x-isvideo'; + case 'it': + return 'audio/it'; + case 'iv': + return 'application/x-inventor'; + case 'ivr': + return 'i-world/i-vrml'; + case 'ivy': + return 'application/x-livescreen'; + case 'jam': + return 'audio/x-jam'; + case 'jav': + return 'text/plain'; + case 'java': + return 'text/plain'; + case 'jcm': + return 'application/x-java-commerce'; + case 'jfif': + return 'image/jpeg'; + case 'jfif-tbnl': + return 'image/jpeg'; + case 'jpe': + return 'image/jpeg'; + case 'jpeg': + return 'image/jpeg'; + case 'jpg': + return 'image/jpeg'; + case 'jps': + return 'image/x-jps'; + case 'js': + return 'application/x-javascript'; + case 'jut': + return 'image/jutvision'; + case 'kar': + return 'audio/midi'; + case 'ksh': + return 'application/x-ksh'; + case 'la': + return 'audio/nspaudio'; + case 'lam': + return 'audio/x-liveaudio'; + case 'latex': + return 'application/x-latex'; + case 'lha': + return 'application/lha'; + case 'lhx': + return 'application/octet-stream'; + case 'list': + return 'text/plain'; + case 'lma': + return 'audio/nspaudio'; + case 'log': + return 'text/plain'; + case 'lsp': + return 'application/x-lisp'; + case 'lst': + return 'text/plain'; + case 'lsx': + return 'text/x-la-asf'; + case 'ltx': + return 'application/x-latex'; + case 'lzh': + return 'application/octet-stream'; + case 'lzx': + return 'application/lzx'; + case 'm': + return 'text/plain'; + case 'm1v': + return 'video/mpeg'; + case 'm2a': + return 'audio/mpeg'; + case 'm2v': + return 'video/mpeg'; + case 'm3u': + return 'audio/x-mpequrl'; + case 'man': + return 'application/x-troff-man'; + case 'map': + return 'application/x-navimap'; + case 'mar': + return 'text/plain'; + case 'mbd': + return 'application/mbedlet'; + case 'mc$': + return 'application/x-magic-cap-package-1.0'; + case 'mcd': + return 'application/mcad'; + case 'mcf': + return 'image/vasa'; + case 'mcp': + return 'application/netmc'; + case 'me': + return 'application/x-troff-me'; + case 'mht': + return 'message/rfc822'; + case 'mhtml': + return 'message/rfc822'; + case 'mid': + return 'application/x-midi'; + case 'midi': + return 'audio/midi'; + case 'mif': + return 'application/x-frame'; + case 'mime': + return 'message/rfc822'; + case 'mjf': + return 'audio/x-vnd.audioexplosion.mjuicemediafile'; + case 'mjpg': + return 'video/x-motion-jpeg'; + case 'mm': + return 'application/base64'; + case 'mme': + return 'application/base64'; + case 'mod': + return 'audio/mod'; + case 'moov': + return 'video/quicktime'; + case 'mov': + return 'video/quicktime'; + case 'movie': + return 'video/x-sgi-movie'; + case 'mp2': + return 'video/mpeg'; + case 'mp3': + return 'video/mpeg'; + case 'mpa': + return 'audio/mpeg'; + case 'mpc': + return 'application/x-project'; + case 'mpe': + return 'video/mpeg'; + case 'mpeg': + return 'video/mpeg'; + case 'mpg': + return 'video/mpeg'; + case 'mpga': + return 'audio/mpeg'; + case 'mpp': + return 'application/vnd.ms-project'; + case 'mpt': + return 'application/x-project'; + case 'mpv': + return 'application/x-project'; + case 'mpx': + return 'application/x-project'; + case 'mrc': + return 'application/marc'; + case 'ms': + return 'application/x-troff-ms'; + case 'mv': + return 'video/x-sgi-movie'; + case 'my': + return 'audio/make'; + case 'mzz': + return 'application/x-vnd.audioexplosion.mzz'; + case 'nap': + return 'image/naplps'; + case 'naplps': + return 'image/naplps'; + case 'nc': + return 'application/x-netcdf'; + case 'ncm': + return 'application/vnd.nokia.configuration-message'; + case 'nif': + return 'image/x-niff'; + case 'niff': + return 'image/x-niff'; + case 'nix': + return 'application/x-mix-transfer'; + case 'nsc': + return 'application/x-conference'; + case 'nvd': + return 'application/x-navidoc'; + case 'o': + return 'application/octet-stream'; + case 'oda': + return 'application/oda'; + case 'omc': + return 'application/x-omc'; + case 'omcd': + return 'application/x-omcdatamaker'; + case 'omcr': + return 'application/x-omcregerator'; + case 'p': + return 'text/x-pascal'; + case 'p10': + return 'application/pkcs10'; + case 'p12': + return 'application/pkcs-12'; + case 'p7a': + return 'application/x-pkcs7-signature'; + case 'p7c': + return 'application/pkcs7-mime'; + case 'p7m': + return 'application/pkcs7-mime'; + case 'p7r': + return 'application/x-pkcs7-certreqresp'; + case 'p7s': + return 'application/pkcs7-signature'; + case 'part': + return 'application/pro_eng'; + case 'pas': + return 'text/pascal'; + case 'pbm': + return 'image/x-portable-bitmap'; + case 'pcl': + return 'application/vnd.hp-pcl'; + case 'pct': + return 'image/x-pict'; + case 'pcx': + return 'image/x-pcx'; + case 'pdb': + return 'chemical/x-pdb'; + case 'pdf': + return 'application/pdf'; + case 'pfunk': + return 'audio/make'; + case 'pgm': + return 'image/x-portable-graymap'; + case 'pic': + return 'image/pict'; + case 'pict': + return 'image/pict'; + case 'pkg': + return 'application/x-newton-compatible-pkg'; + case 'pko': + return 'application/vnd.ms-pki.pko'; + case 'pl': + return 'text/plain'; + case 'plx': + return 'application/x-pixclscript'; + case 'pm': + return 'image/x-xpixmap'; + case 'pm4': + return 'application/x-pagemaker'; + case 'pm5': + return 'application/x-pagemaker'; + case 'png': + return 'image/png'; + case 'pnm': + return 'application/x-portable-anymap'; + case 'pot': + return 'application/mspowerpoint'; + case 'pov': + return 'model/x-pov'; + case 'ppa': + return 'application/vnd.ms-powerpoint'; + case 'ppm': + return 'image/x-portable-pixmap'; + case 'pps': + return 'application/mspowerpoint'; + case 'ppt': + return 'application/mspowerpoint'; + case 'ppz': + return 'application/mspowerpoint'; + case 'pre': + return 'application/x-freelance'; + case 'prt': + return 'application/pro_eng'; + case 'ps': + return 'application/postscript'; + case 'psd': + return 'application/octet-stream'; + case 'pvu': + return 'paleovu/x-pv'; + case 'pwz': + return 'application/vnd.ms-powerpoint'; + case 'py': + return 'text/x-script.phyton'; + case 'pyc': + return 'applicaiton/x-bytecode.python'; + case 'qcp': + return 'audio/vnd.qcelp'; + case 'qd3': + return 'x-world/x-3dmf'; + case 'qd3d': + return 'x-world/x-3dmf'; + case 'qif': + return 'image/x-quicktime'; + case 'qt': + return 'video/quicktime'; + case 'qtc': + return 'video/x-qtc'; + case 'qti': + return 'image/x-quicktime'; + case 'qtif': + return 'image/x-quicktime'; + case 'ra': + return 'audio/x-pn-realaudio'; + case 'ram': + return 'audio/x-pn-realaudio'; + case 'ras': + return 'application/x-cmu-raster'; + case 'rast': + return 'image/cmu-raster'; + case 'rexx': + return 'text/x-script.rexx'; + case 'rf': + return 'image/vnd.rn-realflash'; + case 'rgb': + return 'image/x-rgb'; + case 'rm': + return 'application/vnd.rn-realmedia'; + case 'rmi': + return 'audio/mid'; + case 'rmm': + return 'audio/x-pn-realaudio'; + case 'rmp': + return 'audio/x-pn-realaudio'; + case 'rng': + return 'application/ringing-tones'; + case 'rnx': + return 'application/vnd.rn-realplayer'; + case 'roff': + return 'application/x-troff'; + case 'rp': + return 'image/vnd.rn-realpix'; + case 'rpm': + return 'audio/x-pn-realaudio-plugin'; + case 'rt': + return 'text/richtext'; + case 'rtf': + return 'application/rtf'; + case 'rtx': + return 'text/richtext'; + case 'rv': + return 'video/vnd.rn-realvideo'; + case 's': + return 'text/x-asm'; + case 's3m': + return 'audio/s3m'; + case 'saveme': + return 'application/octet-stream'; + case 'sbk': + return 'application/x-tbook'; + case 'scm': + return 'application/x-lotusscreencam'; + case 'sdml': + return 'text/plain'; + case 'sdp': + return 'application/sdp'; + case 'sdr': + return 'application/sounder'; + case 'sea': + return 'application/sea'; + case 'set': + return 'application/set'; + case 'sgm': + return 'text/sgml'; + case 'sgml': + return 'text/sgml'; + case 'sh': + return 'application/x-bsh'; + case 'shar': + return 'application/x-bsh'; + case 'shtml': + return 'text/html'; + case 'sid': + return 'audio/x-psid'; + case 'sit': + return 'application/x-sit'; + case 'skd': + return 'application/x-koan'; + case 'skm': + return 'application/x-koan'; + case 'skp': + return 'application/x-koan'; + case 'skt': + return 'application/x-koan'; + case 'sl': + return 'application/x-seelogo'; + case 'smi': + return 'application/smil'; + case 'smil': + return 'application/smil'; + case 'snd': + return 'audio/basic'; + case 'sol': + return 'application/solids'; + case 'spc': + return 'application/x-pkcs7-certificates'; + case 'spl': + return 'application/futuresplash'; + case 'spr': + return 'application/x-sprite'; + case 'sprite': + return 'application/x-sprite'; + case 'src': + return 'application/x-wais-source'; + case 'ssi': + return 'text/x-server-parsed-html'; + case 'ssm': + return 'application/streamingmedia'; + case 'sst': + return 'application/vnd.ms-pki.certstore'; + case 'step': + return 'application/step'; + case 'stl': + return 'application/sla'; + case 'stp': + return 'application/step'; + case 'sv4cpio': + return 'application/x-sv4cpio'; + case 'sv4crc': + return 'application/x-sv4crc'; + case 'svf': + return 'image/vnd.dwg'; + case 'svr': + return 'application/x-world'; + case 'swf': + return 'application/x-shockwave-flash'; + case 't': + return 'application/x-troff'; + case 'talk': + return 'text/x-speech'; + case 'tar': + return 'application/x-tar'; + case 'tbk': + return 'application/toolbook'; + case 'tcl': + return 'application/x-tcl'; + case 'tcsh': + return 'text/x-script.tcsh'; + case 'tex': + return 'application/x-tex'; + case 'texi': + return 'application/x-texinfo'; + case 'texinfo': + return 'application/x-texinfo'; + case 'text': + return 'text/plain'; + case 'tgz': + return 'application/x-compressed'; + case 'tif': + return 'image/tiff'; + case 'tiff': + return 'image/tiff'; + case 'tr': + return 'application/x-troff'; + case 'tsi': + return 'audio/tsp-audio'; + case 'tsp': + return 'application/dsptype'; + case 'tsv': + return 'text/tab-separated-values'; + case 'turbot': + return 'image/florian'; + case 'txt': + return 'text/plain'; + case 'uil': + return 'text/x-uil'; + case 'uni': + return 'text/uri-list'; + case 'unis': + return 'text/uri-list'; + case 'unv': + return 'application/i-deas'; + case 'uri': + return 'text/uri-list'; + case 'uris': + return 'text/uri-list'; + case 'ustar': + return 'multipart/x-ustar'; + case 'uu': + return 'application/octet-stream'; + case 'uue': + return 'text/x-uuencode'; + case 'vcd': + return 'application/x-cdlink'; + case 'vcs': + return 'text/x-vcalendar'; + case 'vda': + return 'application/vda'; + case 'vdo': + return 'video/vdo'; + case 'vew': + return 'application/groupwise'; + case 'viv': + return 'video/vivo'; + case 'vivo': + return 'video/vivo'; + case 'vmd': + return 'application/vocaltec-media-desc'; + case 'vmf': + return 'application/vocaltec-media-file'; + case 'voc': + return 'audio/voc'; + case 'vos': + return 'video/vosaic'; + case 'vox': + return 'audio/voxware'; + case 'vqe': + return 'audio/x-twinvq-plugin'; + case 'vqf': + return 'audio/x-twinvq'; + case 'vql': + return 'audio/x-twinvq-plugin'; + case 'vrml': + return 'application/x-vrml'; + case 'vrt': + return 'x-world/x-vrt'; + case 'vsd': + return 'application/x-visio'; + case 'vst': + return 'application/x-visio'; + case 'vsw': + return 'application/x-visio'; + case 'w60': + return 'application/wordperfect6.0'; + case 'w61': + return 'application/wordperfect6.1'; + case 'w6w': + return 'application/msword'; + case 'wav': + return 'audio/wav'; + case 'wb1': + return 'application/x-qpro'; + case 'wbmp': + return 'image/vnd.wap.wbmp'; + case 'web': + return 'application/vnd.xara'; + case 'wiz': + return 'application/msword'; + case 'wk1': + return 'application/x-123'; + case 'wmf': + return 'windows/metafile'; + case 'wml': + return 'text/vnd.wap.wml'; + case 'wmlc': + return 'application/vnd.wap.wmlc'; + case 'wmls': + return 'text/vnd.wap.wmlscript'; + case 'wmlsc': + return 'application/vnd.wap.wmlscriptc'; + case 'word': + return 'application/msword'; + case 'wp': + return 'application/wordperfect'; + case 'wp5': + return 'application/wordperfect6.0'; + case 'wp6': + return 'application/wordperfect'; + case 'wpd': + return 'application/x-wpwin'; + case 'wq1': + return 'application/x-lotus'; + case 'wri': + return 'application/mswrite'; + case 'wrl': + return 'model/vrml'; + case 'wrz': + return 'model/vrml'; + case 'wsc': + return 'text/scriplet'; + case 'wsrc': + return 'application/x-wais-source'; + case 'wtk': + return 'application/x-wintalk'; + case 'xbm': + return 'image/x-xbitmap'; + case 'xdr': + return 'video/x-amt-demorun'; + case 'xgz': + return 'xgl/drawing'; + case 'xif': + return 'image/vnd.xiff'; + case 'xl': + return 'application/excel'; + case 'xla': + return 'application/excel'; + case 'xlb': + return 'application/excel'; + case 'xlc': + return 'application/excel'; + case 'xld': + return 'application/excel'; + case 'xlk': + return 'application/excel'; + case 'xll': + return 'application/excel'; + case 'xlm': + return 'application/excel'; + case 'xls': + return 'application/excel'; + case 'xlt': + return 'application/excel'; + case 'xlv': + return 'application/excel'; + case 'xlw': + return 'application/excel'; + case 'xm': + return 'audio/xm'; + case 'xml': + return 'application/xml'; + case 'xmz': + return 'xgl/movie'; + case 'xpix': + return 'application/x-vnd.ls-xpix'; + case 'xpm': + return 'image/xpm'; + case 'x-png': + return 'image/png'; + case 'xsr': + return 'video/x-amt-showrun'; + case 'xwd': + return 'image/x-xwd'; + case 'xyz': + return 'chemical/x-pdb'; + case 'z': + return 'application/x-compress'; + case 'zip': + return 'application/x-compressed'; + case 'zoo': + return 'application/octet-stream'; + case 'zsh': + return 'text/x-script.zsh'; + default: + return 'application/octet-stream'; + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Multi.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Multi.php new file mode 100644 index 0000000..1445867 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Multi.php @@ -0,0 +1,95 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Multi.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Regroups several readers to make them appear as a single one + */ +class File_Archive_Reader_Multi extends File_Archive_Reader_Relay +{ + /** + * @var Array All the sources regrouped in this reader + * @access private + */ + var $sources = array(); + /** + * @var Int Index of the source being read currently + * @access private + */ + var $currentIndex = 0; + + function File_Archive_Reader_Multi() + { + parent::File_Archive_Reader_Relay($tmp = null); + } + + /** + * Add a new reader to the list of readers + * @param File_Archive_Reader $source The source to add + */ + function addSource(&$source) + { + $this->sources[] =& $source; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + while (array_key_exists($this->currentIndex, $this->sources)) { + $this->source =& $this->sources[$this->currentIndex]; + + if (($error = $this->source->next()) === false) { + $error = $this->source->close(); + if (PEAR::isError($error)) { + return $error; + } + $this->currentIndex++; + } else { + return $error; + } + } + return false; + } + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $error = parent::close(); + $this->currentIndex = 0; + return $error; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Relay.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Relay.php new file mode 100644 index 0000000..216a1f0 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Relay.php @@ -0,0 +1,134 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Relay.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * This reader appear exactly as $source does + * This is usefull if you want to dynamically change $source or change + * its behaviour + */ +class File_Archive_Reader_Relay extends File_Archive_Reader +{ + /** + * @var File_Archive_Reader This reader will have the same comportment as + * $source + * @access protected + */ + var $source; + + function File_Archive_Reader_Relay(&$source) + { + $this->source =& $source; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() { return $this->source->next(); } + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->source->getFilename(); } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->source->getStat(); } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() { return $this->source->getMime(); } + /** + * @see File_Archive_Reader::getDataFilename() + */ + function getDataFilename() { return $this->source->getDataFilename(); } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) { return $this->source->getData($length); } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) { return $this->source->skip($length); } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) { return $this->source->rewind($length); } + /** + * @see File_Archive_Reader::tell() + */ + function tell() { return $this->source->tell(); } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + if ($this->source !== null) { + return $this->source->close(); + } + } + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + $writer = $this->source->makeAppendWriter(); + if (!PEAR::isError($writer)) { + $this->close(); + } + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + $writer = $this->source->makeWriterRemoveFiles($pred); + if (!PEAR::isError($writer)) { + $this->close(); + } + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + $writer = $this->source->makeWriterRemoveBlocks($blocks, $seek); + if (!PEAR::isError($writer)) { + $this->close(); + } + return $writer; + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Select.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Select.php new file mode 100644 index 0000000..952a589 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Select.php @@ -0,0 +1,63 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Select.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Reader that keeps the files selected by File_Archive::select function + */ +class File_Archive_Reader_Select extends File_Archive_Reader_Relay +{ + /** + * @var File_Archive_Reader_Predicat + * @access private + */ + var $filename; + + /** + * $source is the reader to filter + */ + function File_Archive_Reader_Select($filename, &$source) + { + parent::File_Archive_Reader_Relay($source); + $this->filename = $filename; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + return $this->source->select($this->filename, false); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Tar.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Tar.php new file mode 100644 index 0000000..b7c7f8d --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Tar.php @@ -0,0 +1,412 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Tar.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; + +/** + * Read a tar archive + */ +class File_Archive_Reader_Tar extends File_Archive_Reader_Archive +{ + /** + * @var String Name of the file being read + * @access private + */ + var $currentFilename = null; + /** + * @var Array Stats of the file being read + * In TAR reader, indexes 2, 4, 5, 7, 9 are set + * @access private + */ + var $currentStat = null; + /** + * @var int Number of bytes that still have to be read before the end of + * file + * @access private + */ + var $leftLength = 0; + /** + * @var int Size of the footer + * A TAR file is made of chunks of 512 bytes. If 512 does not + * divide the file size a footer is added + * @access private + */ + var $footerLength = 0; + /** + * @var int nb bytes to seek back in order to reach the end of the archive + * or null if the end of the archive has not been reached + */ + var $seekToEnd = null; + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($length == -1) { + $length = $this->leftLength; + } else { + $length = min($this->leftLength, $length); + } + $skipped = $this->source->skip($length); + if (!PEAR::isError($skipped)) { + $this->leftLength -= $skipped; + } + return $skipped; + } + + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($length == -1) { + $length = $this->currentStat[7] - $this->leftLength; + } else { + $length = min($length, $this->currentStat[7] - $this->leftLength); + } + $rewinded = $this->source->rewind($length); + if (!PEAR::isError($rewinded)) { + $this->leftLength += $rewinded; + } + return $rewinded; + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->currentStat[7] - $this->leftLength; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->leftLength = 0; + $this->currentFilename = null; + $this->currentStat = null; + $this->seekToEnd = null; + return parent::close(); + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->currentFilename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->currentStat; } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + $error = parent::next(); + if ($error !== true) { + return $error; + } + + if ($this->seekToEnd !== null) { + return false; + } + + while (true) { + //Advance $this + $header = $this->_nextAdvance(); + if ((!$header) || PEAR::isError($header)) { + return $header; + } + + //Are we looking at a Long Link? + if ($header['type'] == 'L') { + //This is a filepath too long for the tar format. + //So the tar specification puts the name in a special entry just before the real data + //This means the filename is the current piece of data. Grab it. + $filename = ''; + while (($str = $this->getData(256)) !== null) { + if (PEAR::isError($str)) { + return $str; + } + $filename .= $str; + } + + //The actual file data is the next item. Advance there and set the filename to what we just made. + //Everything about the "next" item is correct except the file name. + $header = $this->_nextAdvance(); + if ((!$header) || PEAR::isError($header)) { + return $header; + } + $this->currentFilename = $filename; + } + /** + * Note that actions taken above to handle LongLink may have advanced $this and reset some vars. + * But that just leaves us in a state to actually handle the thing as if it were a normal file. + * So continue as if this never happened... + */ + + //Other than the above we only care about regular files. + //NOTE: Any non-numeric type codes will == 0 + //We handle 'L' above, I don't know what others are out there. + //5 == directory + if ($header['type'] == 0 || $header['type'] == 5) { + break; + } + } + return true; + } + + /** + * Performs the actual advancement to the next item in the underlying structure + * We encapsulate it in a separate function because ot things like @LongLink, where the + * next item is part of the current one. + * + * @access private + * @author Josh Vermette (josh@calydonian.com) + */ + function _nextAdvance() + { + $error = $this->source->skip($this->leftLength + $this->footerLength); + if (PEAR::isError($error)) { + return $error; + } + + $rawHeader = $this->source->getData(512); + if (PEAR::isError($rawHeader)) { + return $rawHeader; + } + + if (strlen($rawHeader)<512 || $rawHeader == pack("a512", "")) { + $this->seekToEnd = strlen($rawHeader); + $this->currentFilename = null; + return false; + } + + $header = unpack( + "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/". + "a8checksum/a1type/a100linkname/a6magic/a2version/". + "a32uname/a32gname/a8devmajor/a8devminor/a155prefix", + $rawHeader); + + $this->currentStat = array( + 2 => octdec($header['mode']), + 4 => octdec($header['uid']), + 5 => octdec($header['gid']), + 7 => octdec($header['size']), + 9 => octdec($header['mtime']) + ); + $this->currentStat['mode'] = $this->currentStat[2]; + $this->currentStat['uid'] = $this->currentStat[4]; + $this->currentStat['gid'] = $this->currentStat[5]; + $this->currentStat['size'] = $this->currentStat[7]; + $this->currentStat['mtime'] = $this->currentStat[9]; + + if ($header['magic'] == 'ustar') { + $this->currentFilename = $this->getStandardURL( + $header['prefix'] . $header['filename'] + ); + } else { + $this->currentFilename = $this->getStandardURL( + $header['filename'] + ); + } + + $this->leftLength = $this->currentStat[7]; + if ($this->leftLength % 512 == 0) { + $this->footerLength = 0; + } else { + $this->footerLength = 512 - $this->leftLength%512; + } + + $checksum = 8*ord(" "); + for ($i = 0; $i < 148; $i++) { + $checksum += ord($rawHeader{$i}); + } + + for ($i = 156; $i < 512; $i++) { + $checksum += ord($rawHeader{$i}); + } + + if (octdec($header['checksum']) != $checksum) { + die('Checksum error on entry '.$this->currentFilename); + } + + return $header; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $actualLength = $this->leftLength; + } else { + $actualLength = min($this->leftLength, $length); + } + + if ($this->leftLength == 0) { + return null; + } else { + $data = $this->source->getData($actualLength); + if (strlen($data) != $actualLength) { + return PEAR::raiseError('Unexpected end of tar archive'); + } + $this->leftLength -= $actualLength; + return $data; + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + require_once "File/Archive/Writer/Tar.php"; + + $blocks = array(); + $seek = null; + $gap = 0; + if ($this->currentFilename !== null && $pred->isTrue($this)) { + $seek = 512 + $this->currentStat[7] + $this->footerLength; + $blocks[] = $seek; //Remove this file + } + + while (($error = $this->next()) === true) { + $size = 512 + $this->currentStat[7] + $this->footerLength; + if ($pred->isTrue($this)) { + if ($seek === null) { + $seek = $size; + $blocks[] = $size; + } else if ($gap > 0) { + $blocks[] = $gap; //Don't remove the files between the gap + $blocks[] = $size; + $seek += $size; + } else { + $blocks[count($blocks)-1] += $size; //Also remove this file + $seek += $size; + } + $gap = 0; + } else { + if ($seek !== null) { + $seek += $size; + $gap += $size; + } + } + } + if ($seek === null) { + $seek = $this->seekToEnd; + } else { + $seek += $this->seekToEnd; + if ($gap == 0) { + array_pop($blocks); + } else { + $blocks[] = $gap; + } + } + + $writer = new File_Archive_Writer_Tar(null, + $this->source->makeWriterRemoveBlocks($blocks, -$seek) + ); + $this->close(); + return $writer; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + if ($this->seekToEnd !== null || $this->currentStat === null) { + return PEAR::raiseError('No file selected'); + } + + $blockPos = $this->currentStat[7] - $this->leftLength + $seek; + + $this->rewind(); + $keep = false; + + $data = $this->getData($blockPos); + foreach ($blocks as $length) { + if ($keep) { + $data .= $this->getData($length); + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + $data .= $this->getData(); + } + + $filename = $this->currentFilename; + $stat = $this->currentStat; + + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + + unset($stat[7]); + $stat[9] = $stat['mtime'] = time(); + $writer->newFile($filename, $stat); + $writer->writeData($data); + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Tar.php"; + + while (($error = $this->next()) === true) { } + if (PEAR::isError($error)) { + $this->close(); + return $error; + } + + $innerWriter = $this->source->makeWriterRemoveBlocks(array(), -$this->seekToEnd); + if (PEAR::isError($innerWriter)) { + return $innerWriter; + } + + $this->close(); + return new File_Archive_Writer_Tar(null, $innerWriter); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Uncompress.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Uncompress.php new file mode 100644 index 0000000..096e5e9 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Uncompress.php @@ -0,0 +1,317 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Uncompress.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; +require_once "File/Archive/Reader/ChangeName/AddDirectory.php"; + +/** + * Recursively uncompress every file it finds + */ +class File_Archive_Reader_Uncompress extends File_Archive_Reader_Relay +{ + /** + * @var Array Stack of readers + * @access private + */ + var $readers = array(); + + /** + * @var array of readers to close when closing $this + * @access private + */ + var $toClose = array(); + + /** + * @var File_Archive_Reader Reader from which all started (usefull to be + * able to close) + * @access private + */ + var $startReader; + + /** + * @var Int Maximum depth of uncompression after the basicDir + * (that may contain some uncompression also) + * -1 means no limit + * @access private + */ + var $uncompressionLevel; + + /** + * @var array Only files starting with $baseDir will be reported + * This array contains explode('/', $directoryName) + * @access private + */ + var $baseDir = ''; + + /** + * @var int Compression level required to go to reach the baseDir + * or null if it is currently being computed + * @access private + */ + var $baseDirCompressionLevel = null; + + /** + * @var int We are selecting substr($baseDir, 0, $baseDirProgression) + */ + var $baseDirProgression = 0; + + /** + * @var boolean Flag set to indicate that the current file has not been + * displayed + */ + var $currentFileNotDisplayed = false; + + function File_Archive_Reader_Uncompress( + &$innerReader, $uncompressionLevel = -1) + { + parent::File_Archive_Reader_Relay($innerReader); + $this->startReader =& $innerReader; + $this->uncompressionLevel = $uncompressionLevel; + } + + /** + * Attempt to change the current source (if the current file is an archive) + * If this is the case, push the current source onto the stack and make the + * good archive reader the current source. A file is considered as an + * archive if its extension is one of tar, gz, zip, tgz + * + * @return bool whether the source has been pushed or not + * @access private + */ + function push() + { + $filename = $this->source->getFilename(); + + if (substr($filename, -1) == '/') { //it's a directory + return false; + } + + + if ($this->uncompressionLevel >= 0 && + $this->baseDirCompressionLevel !== null && + count($this->readers) >= $this->uncompressionLevel + ) { + return false; + } + + // Check the extension of the file (maybe we need to uncompress it?) + $extensions = explode('.', strtolower($filename)); + + $reader =& $this->source; + $nbUncompressions = 0; + + while (($extension = array_pop($extensions)) !== null) { + $nbUncompressions++; + unset($next); + $next = File_Archive::readArchive($extension, $reader, $nbUncompressions == 1); + if ($next === false) { + $extensions = array(); + } else { + unset($reader); + $reader =& $next; + } + } + if ($nbUncompressions == 1) { + return false; + } else { + $this->readers[count($this->readers)] =& $this->source; + unset($this->source); + $this->source = new File_Archive_Reader_ChangeName_AddDirectory( + $filename, $reader + ); + return true; + } + } + /** + * @see File_Archive_Reader::close() + */ + function next() + { + if ($this->currentFileNotDisplayed) { + $this->currentFileNotDisplayed = false; + return true; + } + + do { + do { + $selection = substr($this->baseDir, 0, $this->baseDirProgression); + if ($selection === false) { + $selection = ''; + } + + $error = $this->source->select($selection, false); + if (PEAR::isError($error)) { + return $error; + } + if (!$error) { + if (empty($this->readers)) { + return false; + } + $this->source->close(); + unset($this->source); + $this->source =& $this->readers[count($this->readers)-1]; + unset($this->readers[count($this->readers)-1]); + } + } while (!$error); + + $filename = $this->source->getFilename(); + if (strlen($filename) < strlen($this->baseDir)) { + $goodFile = (strncmp($filename, $this->baseDir, strlen($filename)) == 0 && + $this->baseDir{strlen($filename)} == '/'); + if ($goodFile) { + if (strlen($filename) + 2 < strlen($this->baseDirProgression)) { + $this->baseDirProgression = strpos($this->baseDir, '/', strlen($filename)+2); + if ($this->baseDirProgression === false) { + $this->baseDirProgression = strlen($this->baseDir); + } + } else { + $this->baseDirProgression = strlen($this->baseDir); + } + } + } else { + $goodFile = (strncmp($filename, $this->baseDir, strlen($this->baseDir)) == 0); + if ($goodFile) { + $this->baseDirProgression = strlen($this->baseDir); + } + } + } while (($goodFile && $this->push()) || !$goodFile); + + return true; + } + + /** + * Efficiently filter out the files which URL does not start with $baseDir + * Throws an error if the $baseDir can't be found + * @return bool Whether baseDir was a directory or a file + */ + function setBaseDir($baseDir) + { + $this->baseDir = $baseDir; + $this->baseDirProgression = strpos($baseDir, '/'); + if ($this->baseDirProgression === false) { + $this->baseDirProgression = strlen($baseDir); + } + + $error = $this->next(); + if ($error === false) { + return PEAR::raiseError("No directory $baseDir in inner reader"); + } else if (PEAR::isError($error)) { + return $error; + } + + $this->currentFileNotDisplayed = true; + return strlen($this->getFilename())>strlen($baseDir); + } + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + if ($close) { + $error = $this->close(); + if (PEAR::isError($close)) { + return $error; + } + } + + $oldBaseDir = $this->baseDir; + $oldProgression = $this->baseDirProgression; + + $this->baseDir = $filename; + $this->baseDirProgression = 0; + + $res = $this->next(); + + $this->baseDir = $oldBaseDir; + $this->baseDirProgression = $oldProgression; + + return $res; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + for ($i=0; $ireaders); ++$i) { + $this->readers[$i]->close(); + } + //var_dump($this->toClose); + for ($i=0; $itoClose); ++$i) { + if ($this->toClose[$i] !== null) { + $this->toClose[$i]->close(); + } + } + + $this->readers = array(); + $this->toClose = array(); + $error = parent::close(); + $this->baseDirCompressionLevel = null; + $this->baseDirProgression = 0; + + unset($this->source); + $this->source =& $this->startReader; + $this->source->close(); + $this->currentFileNotDisplayed = false; + + return $error; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + //The reader needs to be open so that the base dir is found + $error = $this->next(); + if (PEAR::isError($error)) { + return $error; + } + + return parent::makeAppendWriter(); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + //The reader needs to be open so that the base dir is found + $error = $this->next(); + if (PEAR::isError($error)) { + return $error; + } + + return parent::makeWriterRemoveFiles($pred); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Zip.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Zip.php new file mode 100644 index 0000000..a9df6ba --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Reader/Zip.php @@ -0,0 +1,482 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Zip.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; + +/** + * ZIP archive reader + * Currently only allows to browse the archive (getData is not available) + */ +class File_Archive_Reader_Zip extends File_Archive_Reader_Archive +{ + var $currentFilename = null; + var $currentStat = null; + var $header = null; + var $offset = 0; + var $data = null; + var $files = array(); + var $seekToEnd = 0; + + var $centralDirectory = null; + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->currentFilename = null; + $this->currentStat = null; + $this->compLength = 0; + $this->data = null; + $this->seekToEnd = 0; + $this->files = array(); + $this->centralDirectory = null; + + return parent::close(); + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->currentFilename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->currentStat; } + + /** + * Go to next entry in ZIP archive + * + * @see File_Archive_Reader::next() + */ + function next() + { + if ($this->seekToEnd > 0) { + return false; + } + + //Skip the data and the footer if they haven't been uncompressed + if ($this->header !== null && $this->data === null) { + $toSkip = $this->header['CLen']; + $error = $this->source->skip($toSkip); + if (PEAR::isError($error)) { + return $error; + } + } + + $this->offset = 0; + $this->data = null; + + //Read the header + $header = $this->source->getData(4); + // Handle PK00PK archives + if ($header == "\x50\x4b\x30\x30") { //PK00 + $header = $this->source->getData(4); + } + // Sometimes this header is used to tag the data descriptor section + if($header == "\x50\x4b\x07\x08") { + // Read out the data descriptor (always 12 bytes) + $this->source->getData(12); + + // Get a new header from the file + $header = $this->source->getData(4); + } + if (PEAR::isError($header)) { + return $header; + } + if ($header == "\x50\x4b\x03\x04") { + //New entry + $header = $this->source->getData(26); + if (PEAR::isError($header)) { + return $header; + } + $this->header = unpack( + "vVersion/vFlag/vMethod/vTime/vDate/VCRC/VCLen/VNLen/vFile/vExtra", + $header); + + //Check the compression method + if ($this->header['Method'] != 0 && + $this->header['Method'] != 8 && + $this->header['Method'] != 12) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle compression method {$this->header['Method']}"); + } + if ($this->header['Flag'] & 1) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle encrypted files"); + } + if ($this->header['Flag'] & 8) { + if ($this->centralDirectory === null) { + $this->readCentralDirectory(); + } + $centralDirEntry = $this->centralDirectory[count($this->files)]; + + $this->header['CRC'] = $centralDirEntry['CRC']; + $this->header['CLen'] = $centralDirEntry['CLen']; + $this->header['NLen'] = $centralDirEntry['NLen']; + } + if ($this->header['Flag'] & 32) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle compressed patched data"); + } + if ($this->header['Flag'] & 64) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle strong encrypted files"); + } + + $this->currentStat = array( + 7=>$this->header['NLen'], + 9=>mktime( + ($this->header['Time'] & 0xF800) >> 11, //hour + ($this->header['Time'] & 0x07E0) >> 5, //minute + ($this->header['Time'] & 0x001F) >> 1, //second + ($this->header['Date'] & 0x01E0) >> 5, //month + ($this->header['Date'] & 0x001F) , //day + (($this->header['Date'] & 0xFE00) >> 9) + 1980 //year + ) + ); + $this->currentStat['size'] = $this->currentStat[7]; + $this->currentStat['mtime'] = $this->currentStat[9]; + + $this->currentFilename = $this->source->getData($this->header['File']); + + $error = $this->source->skip($this->header['Extra']); + if (PEAR::isError($error)) { + return $error; + } + + $this->files[] = array('name' => $this->currentFilename, + 'stat' => $this->currentStat, + 'CRC' => $this->header['CRC'], + 'CLen' => $this->header['CLen'] + ); + return true; + } else { + //Begining of central area + $this->seekToEnd = 4; + $this->currentFilename = null; + return false; + } + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->offset >= $this->currentStat[7]) { + return null; + } + + if ($length>=0) { + $actualLength = min($length, $this->currentStat[7]-$this->offset); + } else { + $actualLength = $this->currentStat[7]-$this->offset; + } + + $error = $this->uncompressData(); + if (PEAR::isError($error)) { + return $error; + } + $result = substr($this->data, $this->offset, $actualLength); + $this->offset += $actualLength; + return $result; + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + $before = $this->offset; + if ($length == -1) { + $this->offset = $this->currentStat[7]; + } else { + $this->offset = min($this->offset + $length, $this->currentStat[7]); + } + return $this->offset - $before; + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + $before = $this->offset; + if ($length == -1) { + $this->offset = 0; + } else { + $this->offset = min(0, $this->offset - $length); + } + return $before - $this->offset; + } + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->offset; + } + + function uncompressData() + { + if ($this->data !== null) + return; + + $this->data = $this->source->getData($this->header['CLen']); + if (PEAR::isError($this->data)) { + return $this->data; + } + if ($this->header['Method'] == 8) { + $this->data = gzinflate($this->data); + } + if ($this->header['Method'] == 12) { + $this->data = bzdecompress($this->data); + } + + if (crc32($this->data) != ($this->header['CRC'] & 0xFFFFFFFF)) { + return PEAR::raiseError("Zip archive: CRC fails on entry ". + $this->currentFilename); + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + require_once "File/Archive/Writer/Zip.php"; + + $blocks = array(); + $seek = null; + $gap = 0; + if ($this->currentFilename !== null && $pred->isTrue($this)) { + $seek = 30 + $this->header['File'] + $this->header['Extra'] + $this->header['CLen']; + $blocks[] = $seek; //Remove this file + array_pop($this->files); + } + + while (($error = $this->next()) === true) { + $size = 30 + $this->header['File'] + $this->header['Extra'] + $this->header['CLen']; + if (substr($this->getFilename(), -1) == '/' || $pred->isTrue($this)) { + array_pop($this->files); + if ($seek === null) { + $seek = $size; + $blocks[] = $size; + } else if ($gap > 0) { + $blocks[] = $gap; //Don't remove the files between the gap + $blocks[] = $size; + $seek += $size; + } else { + $blocks[count($blocks)-1] += $size; //Also remove this file + $seek += $size; + } + $gap = 0; + } else { + if ($seek !== null) { + $seek += $size; + $gap += $size; + } + } + } + if (PEAR::isError($error)) { + return $error; + } + + if ($seek === null) { + $seek = 4; + } else { + $seek += 4; + if ($gap == 0) { + array_pop($blocks); + } else { + $blocks[] = $gap; + } + } + + $writer = new File_Archive_Writer_Zip(null, + $this->source->makeWriterRemoveBlocks($blocks, -$seek) + ); + if (PEAR::isError($writer)) { + return $writer; + } + + foreach ($this->files as $file) { + $writer->alreadyWrittenFile($file['name'], $file['stat'], $file['CRC'], $file['CLen']); + } + + $this->close(); + return $writer; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + if ($this->currentFilename === null) { + return PEAR::raiseError('No file selected'); + } + + $keep = false; + + $this->uncompressData(); + $newData = substr($this->data, 0, $this->offset + $seek); + $this->data = substr($this->data, $this->offset + $seek); + foreach ($blocks as $length) { + if ($keep) { + $newData .= substr($this->data, 0, $length); + } + $this->data = substr($this->data, $length); + $keep = !$keep; + } + if ($keep) { + $newData .= $this->data; + } + + $filename = $this->currentFilename; + $stat = $this->currentStat; + + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + + unset($stat[7]); + $stat[9] = $stat['mtime'] = time(); + $writer->newFile($filename, $stat); + $writer->writeData($newData); + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Zip.php"; + + while (($error = $this->next()) === true) { } + if (PEAR::isError($error)) { + $this->close(); + return $error; + } + + $writer = new File_Archive_Writer_Zip(null, + $this->source->makeWriterRemoveBlocks(array(), -4) + ); + + foreach ($this->files as $file) { + $writer->alreadyWrittenFile($file['name'], $file['stat'], $file['CRC'], $file['CLen']); + } + + $this->close(); + return $writer; + } + + /** + * This function seeks to the start of the [end of central directory] field, + * just after the \x50\x4b\x05\x06 signature and returns the number of bytes + * skipped + * + * The stream must initially be positioned before the end of central directory + */ + function seekToEndOfCentralDirectory() + { + $nbSkipped = $this->source->skip(); + + $nbSkipped -= $this->source->rewind(22) - 4; + if ($this->source->getData(4) == "\x50\x4b\x05\x06") { + return $nbSkipped; + } + + while ($nbSkipped > 0) { + + $nbRewind = $this->source->rewind(min(100, $nbSkipped)); + while ($nbRewind >= -4) { + if ($nbRewind-- && $this->source->getData(1) == "\x50" && + $nbRewind-- && $this->source->getData(1) == "\x4b" && + $nbRewind-- && $this->source->getData(1) == "\x05" && + $nbRewind-- && $this->source->getData(1) == "\x06") { + //We finally found it! + return $nbSkipped - $nbRewind; + } + } + $nbSkipped -= $nbRewind; + } + + return PEAR::raiseError('End of central directory not found. The file is probably not a zip archive'); + } + + /** + * This function will fill the central directory variable + * and seek back to where it was called + */ + function readCentralDirectory() + { + $nbSkipped = $this->seekToEndOfCentralDirectory(); + if (PEAR::isError($nbSkipped)) { + return $nbSkipped; + } + + $this->source->skip(12); + $offset = $this->source->getData(4); + $nbSkipped += 16; + if (PEAR::isError($offset)) { + return $offset; + } + + $offset = unpack("Vvalue", $offset); + $offset = $offset['value']; + + $current = $this->source->tell(); + $nbSkipped -= $this->source->rewind($current - $offset); + + //Now we are the right pos to read the central directory + $this->centralDirectory = array(); + while ($this->source->getData(4) == "\x50\x4b\x01\x02") { + $this->source->skip(12); + $header = $this->source->getData(16); + $nbSkipped += 32; + + if (PEAR::isError($header)) { + return $header; + } + + $header = unpack('VCRC/VCLen/VNLen/vFileLength/vExtraLength', $header); + $this->centralDirectory[] = array('CRC' => $header['CRC'], + 'CLen' => $header['CLen'], + 'NLen' => $header['NLen']); + $nbSkipped += $this->source->skip(14 + $header['FileLength'] + $header['ExtraLength']); + } + + $this->source->rewind($nbSkipped+4); + } +} +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer.php new file mode 100644 index 0000000..c349b32 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer.php @@ -0,0 +1,119 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Writer.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "PEAR.php"; + +/** + * Base class for any writer + */ +class File_Archive_Writer +{ + /** + * Create a new file in the writer + * + * @param string $filename Name of the file, eventually including a path + * @param array $stat Its Statistics. None of the indexes are required + * @param string $mime MIME type of the file + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + } + + /** + * Create a new file in the writer with the content of the physical file $filename + * and then unlink $filename. + * newFromTempFile($tmpfile, $filename, $stat, $mime) is equivalent to + * newFile($filename, $stat, $mime); writeFile($tmpfile); unlink($tmpfile); + * but can be more efficient. + * A typical use is for File_Archive_Writer_Files: it renames the temporary + * file instead of copy/delete + * + * @param string $tmpfile Name of the physical file that contains data and will be unlinked + * @param string $filename Name of the file, eventually including a path + * @param array $stat Its Statistics. None of the indexes are required + * @param string $mime MIME type of the file + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + $this->newFile($filename, $stat, $mime); + $this->writeFile($tmpfile); + unlink($tmpfile); + } + + /** + * Returns whether the writer newFile function needs the $mime parameter + * Default is false + */ + function newFileNeedsMIME() + { + return false; + } + + /** + * Append the specified data to the writer + * + * @param String $data the data to append to the writer + */ + function writeData($data) + { + } + + /** + * Append the content of the physical file $filename to the writer + * writeFile($filename) must be equivalent to + * writeData(file_get_contents($filename)) but can be more efficient + * + * @param string $filename Name of the file which content must be appended + * to the writer + */ + function writeFile($filename) + { + $handle = fopen($filename, "r"); + if (!is_resource($handle)) { + return PEAR::raiseError("Unable to write to $filename"); + } + while (!feof($handle)) { + $error = $this->writeData(fread($handle, 102400)); + if (PEAR::isError($error)) { + return $error; + } + } + fclose($handle); + } + + /** + * Close the writer, eventually flush the data, write the footer... + * This function must be called before the end of the script + */ + function close() { } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/AddBaseName.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/AddBaseName.php new file mode 100644 index 0000000..1d8d2ae --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/AddBaseName.php @@ -0,0 +1,102 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: AddBaseName.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Writer wrapper that adds a directory to the written file + */ +class File_Archive_Writer_AddBaseName +{ + var $writer; + var $baseName; + + function File_Archive_Writer_AddBaseName($baseName, &$writer) + { + if (substr($baseName, -1) == '/') { + $this->baseName = $baseName; + } else { + $this->baseName = $baseName.'/'; + } + + $this->writer =& $writer; + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + $this->writer->newFile($this->baseName.$filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFromTempFile() + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + $this->writer->newFromTempFile($tmpfile, $this->baseName.$filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + return $this->writer->newFileNeedsMIME(); + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + $this->writer->writeData($data); + } + + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + $this->writer->writeFile($filename); + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $this->writer->close(); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Ar.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Ar.php new file mode 100644 index 0000000..113ea24 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Ar.php @@ -0,0 +1,209 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/Archive.php"; + +/** + * Write the files as an AR archive + */ +class File_Archive_Writer_Ar extends File_Archive_Writer_Archive +{ + + /** + * @var string Current data of the file. + * @access private + */ + var $_buffer = ""; + + /** + * @var string Filename of the current filename + * @access private + */ + var $_currentFilename = null; + + /** + * @var boolean Flag: use buffer or not. + * @access private + */ + var $_useBuffer; + + /** + * @var array Stats of the current filename + * @access private + */ + var $_currentStat = array (); + + /** + * @var boolean Flag: beginning of the archive or not + * @access private + */ + var $_atStart = true; + + /** + * Returns the header of the current file. + * + * More Info: + * http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/files/aixfiles/ar_IA64.htm + * + * @access private + * @param string $filename Name of the current file + * @param array $stat Stat array of the current file + * @return string The built header struct + */ + function arHeader ($filename, $stat) + { + $mode = isset($stat[2]) ? $stat[2] : 0x8000; + $uid = isset($stat[4]) ? $stat[4] : 0; + $gid = isset($stat[5]) ? $stat[5] : 0; + $size = $stat[7]; + $time = isset($stat[9]) ? $stat[9] : time(); + + $struct = ""; + $currentSize = $size; + //if file length is > than 16.. + if (strlen($filename) > 16) { + $currentSize += strlen($filename); + $struct .= sprintf("#1/%-13d", strlen($filename)); + $struct .= sprintf("%-12d%-6d%-6d%-8s%-10d", + $time, $uid, $gid, $mode, $currentSize); + $struct .= "`\n".$filename; + } else { + $struct .= sprintf("%-16s", $filename); + $struct .= sprintf("%-12d%-6d%-6d%-8s%-10d`\n", + $time, $uid, $gid, $mode, $size); + } + return $struct; + } + + /** + * Returns the footer of the current file, the footer depends + * of the size of the file + * + * @access private + * @param string $filename Name of the file, the footer depends on its length + * @param int $size Size of the current file, here the size does matters! + * @return string The footer struct + */ + function arFooter($filename, $size) + { + $size = (strlen ($filename) > 16) ? $size + strlen($filename) : $size; + + return ($size % 2 == 1) ? "\n" : ""; + } + + + /** + * Flush the memory we have in the ar. + * + * Build the buffer if its called at the end or initialize + * it if we are just creating it from the start. + */ + function flush() + { + if ($this->_atStart) { + $this->innerWriter->writeData("!\n"); + $this->_atStart = false; + } + if ($this->_currentFilename !== null) { + $this->_currentStat[7] = strlen($this->_buffer); + if ($this->_useBuffer) { + $this->innerWriter->writeData( + $this->arHeader($this->_currentFilename, $this->_currentStat) + ); + $this->innerWriter->writeData($this->_buffer); + } + $this->innerWriter->writeData($this->arFooter($this->_currentFilename, $this->_currentStat[7])); + } + $this->_buffer = ""; + } + + /** + * @see File_Archive_Writer::newFile() + * + */ + function newFile($filename, $stat = array (), + $mime = "application/octet-stream") + { + // ar file format doesn't support folders + if (substr($filename, -1) == '/') { + return; + } + + $this->flush(); + /* + * If the file is empty, there's no reason to have a buffer + * or use memory + */ + $this->_useBuffer = !isset($stats[7]); + /* + * Becaue ar fileformats doesn't support files in directories, + * then we need to just save with the filename an ommit the + * directory + */ + $this->_currentFilename = basename($filename); + $this->_currentStat = $stat; + + if(!$this->_useBuffer) { + return $this->innerWriter->writeData($this->arHeader($filename, $stat)); + } + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $this->flush(); + parent::close(); + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + if ($this->_useBuffer) { + $this->_buffer .= $data; + } else { + $this->innerWriter->writeData($data); + } + + } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + if ($this->_useBuffer) { + $this->_buffer .= file_get_contents($filename); + } else { + $this->innerWriter->writeFile($filename); + } + } +} \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Archive.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Archive.php new file mode 100644 index 0000000..12bb2c0 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Archive.php @@ -0,0 +1,129 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Archive.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Base class for all the transformation writers that will generate one single + * file + */ +class File_Archive_Writer_Archive extends File_Archive_Writer +{ + /** + * @var File_Archive_Writer The compressed data will be written to this + * writer + * @access protected + */ + var $innerWriter; + + /** + * @var bool If true, the innerWriter will be closed when closing this + * @access private + */ + var $autoClose; + + /** + * @var Array List of empty folders that will be added when closing the archive + */ + var $emptyFolders = array(); + + /** + * @param String $filename Name to give to the archive (the name will + * be used by the inner writer) + * If $filename is null, the innerWriter is considered already + * opened (and thus newFile will not be called) + * @param File_Archive_Writer $innerWriter The inner writer to which the + * compressed data will be written + * @param array $stat The stat of the archive (see the PHP stat() function). + * No element are required in this array + * @param bool $autoClose Indicate if the inner writer must be closed when + * closing this + */ + function File_Archive_Writer_Archive($filename, &$innerWriter, + $stat = array(), $autoClose = true) + { + $this->innerWriter =& $innerWriter; + $this->autoClose = $autoClose; + if ($filename !== null) { + $this->innerWriter->newFile($filename, $stat, $this->getMime()); + } + } + + function newFile($filename, $stat = array(), + $mime = 'application/octet-stream') + { + if (substr($filename, -1) == '/') { + $this->emptyFolders[$filename] = array($stat, $mime); + } else { + // Remove the folders that may no longer be empty + $current = ''; + foreach (explode('/', $filename) as $folder) { + $current .= $folder.'/'; + unset($this->emptyFolders[$current]); + } + $err = $this->_newFile($filename, $stat, $mime); + if (PEAR::isError($err)) { + return $err; + } + } + } +//MUST REWRITE FUNCTIONS + function _newFile($filename, $stat, $mime) {} + + /** + * @return the MIME extension of the files generated by this writer + */ + function getMime() { return "application/octet-stream"; } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + foreach ($this->emptyFolders as $folder => $info) { + $err = $this->_newFile($folder, $info[0], $info[1]); + if (PEAR::isError($err)) { + return $err; + } + } + + if ($this->autoClose) { + return $this->innerWriter->close(); + } + } +// function writeData($data) + +//SHOULD REWRITE FUNCTIONS +// function writeFile($filename) +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Bzip2.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Bzip2.php new file mode 100644 index 0000000..f436688 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Bzip2.php @@ -0,0 +1,147 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Bzip2.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Compress a single file to Bzip2 format + */ +class File_Archive_Writer_Bzip2 extends File_Archive_Writer +{ + + /** + * compressionLevel + * + * @var integer + * @access public + * @deprecated + */ + var $compressionLevel=9; + var $bzfile; + var $tmpName; + var $nbFiles = 0; + + var $innerWriter; + var $autoClose; + var $filename; + var $stat; + + /** + * @param string $filename Name to give to the archive + * @param File_Archive_Writer $innerWriter The inner writer to which the + * compressed data will be written + * @param array $stat The stat of the archive (see the PHP stat() function). + * No element are required in this array + * @param bool $autoClose Indicate if the inner writer must be closed when + * closing this + */ + function File_Archive_Writer_Bzip2($filename, &$innerWriter, + $stat = array(), $autoClose = true) + { + $this->innerWriter =& $innerWriter; + $this->autoClose = $autoClose; + + $this->filename = $filename; + $this->stat = $stat; + + if ($this->filename === null) { + $this->newFile(null); + } + } + + /** + * Set the compression level. Do nothing because PHP bz2 ext doesn't + * support this. + * + * @param int $compressionLevel From 0 (no compression) to 9 (best + * compression) + * @deprecated + */ + function setCompressionLevel($compressionLevel) + { + $this->compressionLevel = $compressionLevel; + } + + /** + * @see File_Archive_Writer::newFile() + * + * Check that one single file is written in the BZip2 archive + */ + function newFile($filename, $stat = array(), + $mime = "application/octet-stream") + { + if ($this->nbFiles > 1) { + return PEAR::raiseError("A Bzip2 archive can only contain one single file.". + "Use Tbz archive to be able to write several files"); + } + $this->nbFiles++; + + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + $this->bzfile = bzopen($this->tmpName, 'w'); + + return true; + } + + /** + * Actually write the tmp file to the inner writer + * Close and delete temporary file + * + * @see File_Archive_Writer::close() + */ + function close() + { + bzclose($this->bzfile); + + if ($this->filename === null) { + //Assume innerWriter is already opened on a file... + $this->innerWriter->writeFile($this->tmpName); + unlink($this->tmpName); + } else { + $this->innerWriter->newFromTempFile( + $this->tmpName, $this->filename, $this->stat, 'application/x-compressed' + ); + } + + if ($this->autoClose) { + return $this->innerWriter->close(); + } + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + bzwrite($this->bzfile, $data); + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Files.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Files.php new file mode 100644 index 0000000..a58cf92 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Files.php @@ -0,0 +1,259 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Files.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Writer to files + */ +class File_Archive_Writer_Files extends File_Archive_Writer +{ + /** + * @var Object Handle to the file where the data are currently written + * @access private + */ + var $handle = null; + var $basePath; + var $stat = array(); + var $filename; + + function File_Archive_Writer_Files($base = '') + { + if ($base === null || $base == '') { + $this->basePath = ''; + } else { + if (substr($base, -1) == '/') { + $this->basePath = $base; + } else { + $this->basePath = $base.'/'; + } + } + } + + function getFilename($filename) + { + return $this->basePath.$filename; + } + + /** + * Ensure that $pathname exists, or create it if it does not + * @access private + */ + function mkdirr($pathname) + { + // Check if directory already exists + if (is_dir($pathname) || empty($pathname)) { + return; + } + + // Ensure a file does not already exist with the same name + if (is_file($pathname)) { + return PEAR::raiseError( + "File $pathname exists, unable to create directory" + ); + } + + // Crawl up the directory tree + $next_pathname = substr( + $pathname, + 0, strrpos($pathname, "/")); + $error = $this->mkdirr($next_pathname); + if (PEAR::isError($error)) { + return $error; + } + if (!@mkdir($pathname)) { + return PEAR::raiseError("Unable to create directory $pathname"); + } + } + + /** + * Open a file for writing from a given position + * + * @param string $filename The name of the file to open + * @param int $pos the initial position in the file + * @param $stat the stats of the file + */ + function openFile($filename, $pos = 0) + { + $this->close(); + + $this->handle = fopen($filename, 'r+'); + $this->stat = array(); + $this->filename = $filename; + + if (!is_resource($this->handle)) { + return PEAR::raiseError("Unable to open file $filename"); + } + + if ($pos > 0) { + if (fseek($this->handle, $pos) == -1) { + fread($this->handle, $pos); + } + } + } + + /** + * Open a file for appending after having removed a block of data from it + * See File_Archive_Reader::makeWriterRemoveBlocks + */ + function openFileRemoveBlock($filename, $pos, $blocks) + { + $error = $this->openFile($filename, $pos); + if (PEAR::isError($error)) { + return $error; + } + + if (!empty($blocks)) { + //This will be used to read the initial file + //The data, with the unusefull block removed will be written to $this->handle + $read = fopen($filename, 'r'); + if ($pos > 0) { + if (fseek($this->handle, $pos) == -1) { + fread($this->handle, $pos); + } + } + + $keep = false; + $data = ''; + foreach ($blocks as $length) { + if ($keep) { + while ($length > 0 && + ($data = fread($read, min($length, 8192))) != '') { + $length -= strlen($data); + fwrite($this->handle, $data); + } + } else { + fseek($read, $length, SEEK_CUR); + } + $keep = !$keep; + } + if ($keep) { + while(!feof($this->handle)) { + fwrite($this->handle, fread($read, 8196)); + } + } + + fclose($read); + } + + ftruncate($this->handle, ftell($this->handle)); + } + + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + $this->close(); + $this->stat = $stat; + $this->filename = $this->getFilename($filename); + + if (substr($this->filename, -1) == '/') { + $error = $this->mkdirr(substr($this->filename, 0, -1)); + if (PEAR::isError($error)) { + return $error; + } + } else { + $pos = strrpos($this->filename, "/"); + if ($pos !== false) { + $error = $this->mkdirr(substr($this->filename, 0, $pos)); + if (PEAR::isError($error)) { + return $error; + } + } + $this->handle = @fopen($this->filename, "w"); + if (!is_resource($this->handle)) { + return PEAR::raiseError("Unable to write to file $filename"); + } + } + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) { fwrite($this->handle, $data); } + /** + * @see File_Archive_Writer::newFromTempFile() + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + $this->filename = $filename; + $complete = $this->getFilename($filename); + $pos = strrpos($complete, "/"); + if ($pos !== false) { + $error = $this->mkdirr(substr($complete, 0, $pos)); + if (PEAR::isError($error)) { + return $error; + } + } + + if ((file_exists($complete) && !@unlink($complete)) || + !@rename($tmpfile, $complete)) { + return parent::newFromTempFile($tmpfile, $filename, $stat, $mime); + } + } + + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + if (is_resource($this->handle)) { + fclose($this->handle); + $this->handle = null; + + if (isset($this->stat[9])) { + if (isset($this->stat[8])) { + touch($this->filename, $this->stat[9], $this->stat[8]); + } else { + touch($this->filename, $this->stat[9]); + } + } else if (isset($this->stat[8])) { + touch($this->filename, time(), $this->stat[8]); + } + + if (isset($this->stat[2])) { + chmod($this->filename, $this->stat[2]); + } + if (isset($this->stat[5])) { + // I will try, but if I dont have permissions, it will fail + @chgrp($this->filename, $this->stat[5]); + } + if (isset($this->stat[4])) { + // I will try, but if I dont have permissions, it will fail + @chown($this->filename, $this->stat[4]); + } + } + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Gzip.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Gzip.php new file mode 100644 index 0000000..be7132f --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Gzip.php @@ -0,0 +1,139 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Gzip.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Compress a single file to Gzip format + */ +class File_Archive_Writer_Gzip extends File_Archive_Writer +{ + var $compressionLevel=9; + var $gzfile; + var $tmpName; + var $nbFiles = 0; + + var $innerWriter; + var $autoClose; + var $filename; + var $stat; + + /** + * @param string $filename Name to give to the archive + * @param File_Archive_Writer $innerWriter The inner writer to which the + * compressed data will be written + * @param array $stat The stat of the archive (see the PHP stat() function). + * No element are required in this array + * @param bool $autoClose Indicate if the inner writer must be closed when + * closing this + */ + function File_Archive_Writer_Gzip($filename, &$innerWriter, + $stat = array(), $autoClose = true) + { + $this->innerWriter =& $innerWriter; + $this->autoClose = $autoClose; + + $this->filename = $filename; + $this->stat = $stat; + + if ($this->filename === null) { + $this->newFile(null); + } + + $compressionLevel = File_Archive::getOption('gzCompressionLevel', 9); + } + + /** + * Set the compression level + * + * @param int $compressionLevel From 0 (no compression) to 9 (best + * compression) + */ + function setCompressionLevel($compressionLevel) + { + $this->compressionLevel = $compressionLevel; + } + + /** + * @see File_Archive_Writer::newFile() + * + * Check that one single file is written in the GZip archive + */ + function newFile($filename, $stat = array(), + $mime = "application/octet-stream") + { + if ($this->nbFiles > 1) { + return PEAR::raiseError("A Gz archive can only contain one single file.". + "Use Tgz archive to be able to write several files"); + } + $this->nbFiles++; + + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + $this->gzfile = gzopen($this->tmpName, 'w'.$this->compressionLevel); + + return true; + } + + + /** + * Actually write the tmp file to the inner writer + * Close and delete temporary file + * + * @see File_Archive_Writer::close() + */ + function close() + { + gzclose($this->gzfile); + if ($this->filename === null) { + //Assume innerWriter is already opened on a file... + $this->innerWriter->writeFile($this->tmpName); + unlink($this->tmpName); + } else { + $this->innerWriter->newFromTempFile( + $this->tmpName, $this->filename, $this->stat, 'application/x-compressed' + ); + } + + if ($this->autoClose) { + return $this->innerWriter->close(); + } + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + gzwrite($this->gzfile, $data); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Mail.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Mail.php new file mode 100644 index 0000000..eda6f60 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Mail.php @@ -0,0 +1,204 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Mail.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; +require_once "Mail.php"; +require_once "Mail/mime.php"; + +/** + * Send the files attached to a mail. + */ +class File_Archive_Writer_Mail extends File_Archive_Writer +{ + /** + * @var Mail_mime object + * @access private + */ + var $mime; + + /** + * @var Mail object used to send email (built thanks to the factory) + * @access private + */ + var $mail; + + /** + * @var Array or String An array or a string with comma separated recipients + * @access private + */ + var $to; + + /** + * @var Array The headers that will be passed to the Mail_mime object + * @access private + */ + var $headers; + + /** + * @var String Data read from the current file so far + * @access private + */ + var $currentData = null; + + /** + * @var String Name of the file being attached + * @access private + */ + var $currentFilename = null; + + /** + * @var String MIME of the file being attached + * @access private + */ + var $currentMime = null; + + /** + * @param Mail $mail Object used to send mail (see Mail::factory) + * @param array or string $to An array or a string with comma separated + * recipients + * @param array $headers The headers that will be passed to the Mail_mime + * object + * @param string $message Text body of the mail + */ + function File_Archive_Writer_Mail($to, $headers, $message, &$mail) + { + $this->mime = new Mail_mime(); + $this->mime->setTXTBody($message); + if (!empty($htmlMessage)) { + $this->mime->setHTMLBody($htmlMessage); + } + + if ($mail === null) + $this->mail = Mail::factory("mail"); + else + $this->mail =& $mail; + + $this->to = $to; + $this->headers = $headers; + } + + /** + * @see Mail_Mime::setHTMLBody() + */ + function setHTMLBody($data, $isfile = false) + { + return $this->mime->setHTMLBody($data, $isfile); + } + /** + * @see Mail_Mime::addHTMLImage() + */ + function addHTMLImage($file, $c_type = 'application/octet-stream', + $name = '', $isfile = true) + { + return $this->mime->addHTMLImage($file, $c_type, $name, $isfile); + } + + /** + * @see File_Archive_Writer::writeData() + * + * This function just put the data in $currentData until the end of file + * At that time, addCurrentData is called to attach $currentData to the mail + * and to clear $currentData for a new file + */ + function writeData($data) + { + $this->currentData .= $data; + } + /** + * Called when a file is finished and must be added as attachment to the mail + */ + function addCurrentData() + { + if ($this->currentFilename === null) { + return; + } + + $error = $this->mime->addAttachment( + $this->currentData, + $this->currentMime, + $this->currentFilename, + false); + $this->currentData = ''; + return $error; + } + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat, $mime = "application/octet-stream") + { + $error = $this->addCurrentData(); + if (PEAR::isError($error)) { + return $error; + } + + if (substr($filename, -1) == '/') { + $this->currentFilename = null; + } else { + $this->currentFilename = $filename; + $this->currentMime = $mime; + } + } + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + return true; + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $error = parent::close(); + if (PEAR::isError($error)) { + return $error; + } + $error = $this->addCurrentData(); + if (PEAR::isError($error)) { + return $error; + } + + $body = $this->mime->get(); + $headers = $this->mime->headers($this->headers); + + if (!$this->mail->send( + $this->to, + $headers, + $body) + ) { + return PEAR::raiseError("Error sending mail"); + } + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Memory.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Memory.php new file mode 100644 index 0000000..0b54788 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Memory.php @@ -0,0 +1,127 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Memory.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Write the concatenation of the files in a buffer + */ +class File_Archive_Writer_Memory extends File_Archive_Writer +{ + /** + * @var string $data The buffer + * @access private + */ + var $data = ""; + /** + * Information about the file being written into this writer + * @access private + */ + var $filename; + var $stat; + var $mime; + + /** + * @param reference $data If provided, the data will be output in this + * variable. Any existent data in $data will be overwritten by the + * actual data of the writer. You should not modify manually this + * variable while using this writer (you can safely use all the + * functions of the archive, like clear for example) + * @param int keptData is the offset from where to start writing in $data + * Any data located after $seek will be erased + * The default value is 0 + */ + function File_Archive_Writer_Memory(&$data, $seek = 0) + { + $this->data =& $data; + $this->data = substr($data, 0, $seek); + } + + function writeData($d) { $this->data .= $d; } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat, $mime = "application/octet-stream") + { + $this->filename = $filename; + $this->stat = $stat; + $this->mime = $mime; + } + /** + * @see File_Archive_Writer::newFileNeedsMIME + */ + function newFileNeedsMIME() + { + return true; + } + + /** + * Retrieve the concatenated data + * The value is returned by reference for performance problems, but you + * should not manually modify it + * + * @return string buffer + */ + function &getData() { return $this->data; } + + /** + * Clear the buffer + */ + function clear() { $this->data = ""; } + + /** + * Returns true iif the buffer is empty + */ + function isEmpty() { return empty($this->data); } + + /** + * Create a reader from this writer + * + * @param string $filename Name of the file provided by the reader + * @param array $stat Statistics of the file provided by the reader + * @param string $mime Mime type of the file provided by the reader + * + * Any unspecified parameter will be set to the value of the last file + * written in this writer + */ + function makeReader($filename = null, $stat = null, $mime = null) + { + require_once "File/Archive/Reader/Memory.php"; + return new File_Archive_Reader_Memory( + $this->data, + $filename === null ? $this->filename : $filename, + $stat === null ? $this->stat : $stat, + $mime === null ? $this->mime : $mime); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/MemoryArchive.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/MemoryArchive.php new file mode 100644 index 0000000..b668c0a --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/MemoryArchive.php @@ -0,0 +1,213 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MemoryArchive.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/Archive.php"; +require_once "File/Archive/Writer/Memory.php"; + +/** + * Base class for all the archiveWriters that can only work on complete files + * (the write data function may be called with small chunks of data) + */ +class File_Archive_Writer_MemoryArchive extends File_Archive_Writer_Archive +{ + /** + * @var File_Archive_Writer_Memory A buffer where the data will be put + * waiting for the file to be complete + * @access private + */ + var $buffer = ''; + /** + * @var string Name of the file which data are coming + * @access private + */ + var $currentFilename = null; + /** + * @var array Stats of the file which data are coming + * @access private + */ + var $currentStat = null; + /** + * @var string URL of the file being treated if it is a physical file + * @access private + */ + var $currentDataFile = null; + /** + * @var int Number of times newFile function has been called + * @access protected + */ + var $nbFiles = 0; + + /** + * @see File_Archive_Writer::File_Archive_Writer() + */ + function File_Archive_Writer_MemoryArchive + ($filename, &$t, $stat = array(), $autoClose = true) + { + parent::File_Archive_Writer_Archive($filename, $t, $stat, $autoClose); + } + + /** + * @see File_Archive_Writer::newFile() + */ + function _newFile($filename, $stat = array(), + $mime = "application/octet-stream") + { + if ($this->nbFiles == 0) { + $error = $this->sendHeader(); + if (PEAR::isError($error)) { + return $error; + } + } else { + $error = $this->flush(); + if (PEAR::isError($error)) { + return $error; + } + } + + $this->nbFiles++; + + $this->currentFilename = $filename; + $this->currentStat = $stat; + + return true; + } + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $error = $this->flush(); + if (PEAR::isError($error)) { + return $error; + } + $error = $this->sendFooter(); + if (PEAR::isError($error)) { + return $error; + } + + return parent::close(); + } + /** + * Indicate that all the data have been read from the current file + * and send it to appendFileData + * Send the current data to the appendFileData function + * + * @access private + */ + function flush() + { + if ($this->currentFilename !== null) { + if ($this->currentDataFile !== null) { + $error = $this->appendFile($this->currentFilename, + $this->currentDataFile); + } else { + $error = $this->appendFileData($this->currentFilename, + $this->currentStat, + $this->buffer); + } + if (PEAR::isError($error)) { + return $error; + } + + $this->currentFilename = null; + $this->currentDataFile = null; + $this->buffer = ''; + } + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + if ($this->currentDataFile !== null) { + $this->buffer .= file_get_contents($this->currentDataFile); + $this->currentDataFile = null; + } + $this->buffer .= $data; + } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + if ($this->currentDataFile === null && empty($this->buffer)) { + $this->currentDataFile = $filename; + } else { + if ($this->currentDataFile !== null) { + $this->buffer .= file_get_contents($this->currentDataFile); + $this->currentDataFile = null; + } + $this->buffer .= file_get_contents($filename); + } + } + +//MUST REWRITE FUNCTIONS + /** + * The subclass must treat the data $data + * $data is the entire data of the filename $filename + * $stat is the stat of the file + * + * @access protected + */ + function appendFileData($filename, $stat, &$data) { } + +//SHOULD REWRITE FUNCTIONS + /** + * The subclass may rewrite the sendHeader function if it needs to execute + * code before the first file + * + * @access protected + */ + function sendHeader() { } + /** + * The subclass may rewrite the sendFooter function if it needs to execute + * code before closing the archive + * + * @access protected + */ + function sendFooter() { } + /** + * The subclass may rewrite this class if it knows an efficient way to treat + * a physical file. + * + * @access protected + */ + function appendFile($filename, $dataFilename) + { + return $this->appendFileData( + $filename, + stat($dataFilename), + file_get_contents($dataFilename)); + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Multi.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Multi.php new file mode 100644 index 0000000..55fc25b --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Multi.php @@ -0,0 +1,130 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Multi.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Write to several writers + */ +class File_Archive_Writer_Multi extends File_Archive_Writer +{ + /** + * @var File_Archive_Writer_Writer Data will be copied to these two writers + * @access private + */ + var $writers; + + function addWriter(&$writer) + { + $this->writers[] =& $writer; + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->newFile($filename, $stat, $mime); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + foreach($this->writers as $key => $foo) { + if ($this->writers[$key]->newFileNeedsMIME()) { + return true; + } + } + return false; + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->writeData($data); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } + + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->writeFile($filename); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->close(); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Output.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Output.php new file mode 100644 index 0000000..67ede45 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Output.php @@ -0,0 +1,93 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Output.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Writer to the standard output + * It will concatenate the files that it receive + * It may send some headers, but will do so only for the first file + */ +class File_Archive_Writer_Output extends File_Archive_Writer +{ + /** + * @var bool If true, the Content-type and Content-disposition headers + * will be sent. The file will be considered as an attachment and + * the MIME will be deduced from its extension + * @access private + */ + var $sendHeaders; + + /** + * @param $sendHeaders see the variable + */ + function File_Archive_Writer_Output($sendHeaders = true) + { + $this->sendHeaders = $sendHeaders; + } + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + if ($this->sendHeaders) { + if(headers_sent()) { + return PEAR::raiseError( + 'The headers have already been sent. '. + 'Use File_Archive::toOutput(false) to write '. + 'to output without sending headers'); + } + + header("Content-type: $mime"); + header("Content-disposition: attachment; filename=\"$filename\""); + $this->sendHeaders = false; + } + } + /** + * @see File_Archive_Writer::newFileNeedsMIME + */ + function newFileNeedsMIME() + { + return $this->sendHeaders; + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) { echo $data; } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) { readfile($filename); } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Tar.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Tar.php new file mode 100644 index 0000000..69c0d61 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Tar.php @@ -0,0 +1,244 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Tar.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/Archive.php"; + +/** + * Write the files as a TAR archive + */ +class File_Archive_Writer_Tar extends File_Archive_Writer_Archive +{ + var $buffer; + var $useBuffer; + + var $filename = null; + var $stats = null; + + + /** + * Creates the TAR header for a file + * + * @param string $filename name of the file + * @param array $stat statistics of the file + * @return string A 512 byte header for the file + * @access private + */ + function tarHeader($filename, $stat) + { + $mode = isset($stat[2]) ? $stat[2] : 0x8000; + $uid = isset($stat[4]) ? $stat[4] : 0; + $gid = isset($stat[5]) ? $stat[5] : 0; + $size = $stat[7]; + $time = isset($stat[9]) ? $stat[9] : time(); + $link = ""; + + if ($mode & 0x4000) { + $type = 5; // Directory + } else if ($mode & 0x8000) { + $type = 0; // Regular + } else if ($mode & 0xA000) { + $type = 1; // Link + $link = @readlink($current); + } else { + $type = 9; // Unknown + } + + $filePrefix = ''; + if (strlen($filename) > 255) { + return PEAR::raiseError( + "$filename is too long to be put in a tar archive" + ); + } else if (strlen($filename) > 100) { + // need a path component of max 155 bytes + $pos = strrpos(substr($filename, 0, 155), '/'); + if(strlen($filename) - $pos > 100) { + // filename-component may not exceed 100 bytes + return PEAR::raiseError( + "$filename is too long to be put in a tar archive"); + } + $filePrefix = substr($filename, 0, $pos); + $filename = substr($filename, $pos+1); + } + + $blockbeg = pack("a100a8a8a8a12a12", + $filename, + decoct($mode), + sprintf("%6s ",decoct($uid)), + sprintf("%6s ",decoct($gid)), + sprintf("%11s ",decoct($size)), + sprintf("%11s ",decoct($time)) + ); + + $blockend = pack("a1a100a6a2a32a32a8a8a155a12", + $type, + $link, + "ustar", + "00", + "Unknown", + "Unknown", + "", + "", + $filePrefix, + ""); + + $checksum = 8*ord(" "); + for ($i = 0; $i < 148; $i++) { + $checksum += ord($blockbeg{$i}); + } + for ($i = 0; $i < 356; $i++) { + $checksum += ord($blockend{$i}); + } + + $checksum = pack("a8",sprintf("%6s ",decoct($checksum))); + + return $blockbeg . $checksum . $blockend; + } + /** + * Creates the TAR footer for a file + * + * @param int $size the size of the data that has been written to the TAR + * @return string A string made of less than 512 characteres to fill the + * last 512 byte long block + * @access private + */ + function tarFooter($size) + { + if ($size % 512 > 0) { + return pack("a".(512 - $size%512), ""); + } else { + return ""; + } + } + + function flush() + { + if ($this->filename !== null) { + if ($this->useBuffer) { + $this->stats[7] = strlen($this->buffer); + + $header = $this->tarHeader($this->filename, $this->stats); + if (PEAR::isError($header)) { + return $header; + } + $this->innerWriter->writeData($header); + $this->innerWriter->writeData( + $this->buffer + ); + } + $this->innerWriter->writeData( + $this->tarFooter($this->stats[7]) + ); + } + $this->buffer = ""; + } + + function _newFile($filename, $stats = array(), + $mime = "application/octet-stream") + { + $err = $this->flush(); + if (PEAR::isError($err)) { + return $err; + } + + $this->useBuffer = !isset($stats[7]); + $this->filename = $filename; + $this->stats = $stats; + + if (!$this->useBuffer) { + $header = $this->tarHeader($filename, $stats); + if (PEAR::isError($header)) { + return $header; + } + return $this->innerWriter->writeData($header); + } + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $err = $this->flush(); + if (PEAR::isError($err)) { + return $err; + } + $this->innerWriter->writeData(pack("a1024", "")); + parent::close(); + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + if ($this->useBuffer) { + $this->buffer .= $data; + } else { + $this->innerWriter->writeData($data); + } + + } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + if ($this->useBuffer) { + if (!file_exists($filename)) { + return PEAR::raiseError("File not found: $filename."); + } + $this->buffer .= file_get_contents($filename); + } else { + $this->innerWriter->writeFile($filename); + } + } + /** + * @see File_Archive_Writer::getMime() + */ + function getMime() { return "application/x-tar"; } +} + + +/** + * A tar archive cannot contain files with name of folders longer than 255 chars + * This filter removes them + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +require_once "File/Archive/Predicate.php"; +class File_Archive_Predicate_TARCompatible extends File_Archive_Predicate +{ + function isTrue($source) + { + return strlen($source->getFilename()) <= 255; + } +} + +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/UniqueAppender.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/UniqueAppender.php new file mode 100644 index 0000000..6f70489 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/UniqueAppender.php @@ -0,0 +1,143 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: UniqueAppender.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; +require_once "File/Archive/Reader.php"; +require_once "File/Archive/Predicate/Index.php"; + +/** + * A writer wrapper that will remove the files the eventual duplicate + * files from the reader to keep only the new ones + * If there were already some duplications in the provided reader, not + * all duplication will be removed + * If you use newFile with the same filename several file, only the latest + * write will be kept (no time comparision is done) + */ +class File_Archive_Writer_UniqueAppender extends File_Archive_Writer +{ + var $reader; + var $writer; + var $fileList = array(); + var $toDelete = array(); + + /** + * Construct a unique writer that will write to the specified writer + * and remove duplicate files from the reader on close + */ + function File_Archive_Writer_UniqueAppender(&$reader) + { + $reader->close(); + $pos = 0; + while ($reader->next()) { + $this->fileList[$reader->getFilename()] = $pos++; + } + + $this->reader =& $reader; + $this->writer = $reader->makeAppendWriter(); + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + if (isset($this->fileList[$filename])) { + $this->toDelete[$this->fileList[$filename]] = true; + } + + return $this->writer->newFile($filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFromTempFile() + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + if (isset($this->fileList[$filename])) { + $this->toDelete[$this->fileList[$filename]] = true; + } + + return $this->writer->newFromTempFile($tmpfile, $filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + return $this->writer->newFileNeedsMIME(); + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + return $this->writer->writeData($data); + } + + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + return $this->writer->writeFile($filename); + } + + /** + * Close the writer, eventually flush the data, write the footer... + * This function must be called before the end of the script + */ + function close() + { + $error = $this->writer->close(); + if (PEAR::isError($error)) { + return $error; + } + + if (!empty($this->toDelete)) { + $tmp = $this->reader->makeWriterRemoveFiles( + new File_Archive_Predicate_Index($this->toDelete) + ); + if (PEAR::isError($tmp)) { + return $tmp; + } + + return $tmp->close(); + } + } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Zip.php b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Zip.php new file mode 100644 index 0000000..af72d3a --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Archive/Writer/Zip.php @@ -0,0 +1,260 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Zip.php 2 2010-11-23 14:32:26Z oldperl $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/MemoryArchive.php"; + +/** + * ZIP archive writer + */ +class File_Archive_Writer_Zip extends File_Archive_Writer_MemoryArchive +{ + /** + * @var int Compression level + * @access private + */ + var $compressionLevel; + + /** + * @var int Current position in the writer + * @access private + */ + var $offset = 0; + + /** + * @var string Optionnal comment to add to the zip + * @access private + */ + var $comment = ""; + + /** + * @var string Data written at the end of the ZIP file + * @access private + */ + var $central = ""; + + function File_Archive_Writer_Zip($filename, &$innerWriter, + $stat=array(), $autoClose = true) + { + global $_File_Archive_Options; + parent::File_Archive_Writer_MemoryArchive( + $filename, $innerWriter, $stat, $autoClose + ); + + $this->compressionLevel = File_Archive::getOption('zipCompressionLevel', 9); + } + + /** + * Change the level of the compression. This may be done between two files + * + * @param Int $compressionLevel New compression level from 0 to 9 + */ + function setCompressionLevel($compressionLevel) + { + $this->compressionLevel = $compressionLevel; + } + + /** + * Set a comment on the ZIP file + */ + function setComment($comment) { $this->comment = $comment; } + + /** + * @param int $time Unix timestamp of the date to convert + * @return the date formated as a ZIP date + */ + function getMTime($time) + { + $mtime = ($time !== null ? getdate($time) : getdate()); + $mtime = preg_replace( + "/(..){1}(..){1}(..){1}(..){1}/", + "\\x\\4\\x\\3\\x\\2\\x\\1", + dechex(($mtime['year']-1980<<25)| + ($mtime['mon' ]<<21)| + ($mtime['mday' ]<<16)| + ($mtime['hours' ]<<11)| + ($mtime['minutes']<<5)| + ($mtime['seconds']>>1))); + eval('$mtime = "'.$mtime.'";'); + return $mtime; + } + + /** + * Inform the archive that $filename is present. + * Consequences are the same as appendFileData, but no data is output + * to the inner writer. + * This is used by File_Archive_Reader_Zip::makeWriter() + * + * @param string $filename name of the file + * @param array $stat stats of the file, indexes 9 and 7 must be present + * @param int $crc32 checksum of the file + * @param int $compLength length of the compressed data + */ + function alreadyWrittenFile($filename, $stat, $crc32, $complength) + { + $filename = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$filename); + + $mtime = $this->getMTime(isset($stat[9]) ? $stat[9] : null); + $normlength = $stat[7]; + + $this->nbFiles++; + + $this->central .= "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00". + $mtime. + pack("VVVvvvvvVV", + $crc32, $complength, $normlength, + strlen($filename), 0x00,0x00,0x00,0x00, + 0x0000,$this->offset). + $filename; + + $this->offset += 30 + strlen($filename) + $complength; + } + + /** + * @see File_Archive_Writer_MemoryArchive::appendFileData() + * @access protected + */ + function appendFileData($filename, $stat, $data) + { + $crc32 = crc32($data); + $normlength = strlen($data); + $data = gzcompress($data,$this->compressionLevel); + $data = substr($data,2,strlen($data)-6); + + return $this->appendCompressedData($filename, $stat, $data, $crc32, $normlength); + } + + function appendCompressedData($filename, $stat, $data, $crc32, $normlength) + { + $filename = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$filename); + $mtime = $this->getMTime(isset($stat[9]) ? $stat[9] : null); + + $complength = strlen($data); + + $zipData = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00". + $mtime. + pack("VVVvv", + $crc32, + $complength, + $normlength, + strlen($filename), + 0x00). + $filename. + $data; + + $error = $this->innerWriter->writeData($zipData); + if (PEAR::isError($error)) { + return $error; + } + + $this->central .= "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00". + $mtime. + pack("VVVvvvvvVV", + $crc32, $complength, $normlength, + strlen($filename), 0x00,0x00,0x00,0x00, + 0x0000,$this->offset). + $filename; + + $this->offset += strlen($zipData); + } + + function appendFile($filename, $dataFilename) + { + //Try to read from the cache + $cache = File_Archive::getOption('cache', null); + if ($cache !== null && $this->compressionLevel > 0) { + $id = realpath($dataFilename); + $id = urlencode($id); + $id = str_replace('_', '%5F', $id); + + $group = 'FileArchiveZip'.$this->compressionLevel; + $mtime = filemtime($dataFilename); + + //Tries to read from cache + if (($data = $cache->get($id, $group)) !== false) { + $info = unpack('Vmtime/Vcrc/Vnlength', substr($data, 0, 12)); + $data = substr($data, 12); + } + + //If cache failed or file modified since then + if ($data === false || + $info['mtime'] != $mtime) { + + $data = file_get_contents($dataFilename); + + $info = array( + 'crc' => crc32($data), + 'nlength' => strlen($data), + 'mtime' => $mtime + ); + + $data = gzcompress($data,$this->compressionLevel); + $data = substr($data,2,strlen($data)-6); + $data = pack('VVV', $info['mtime'], $info['crc'], $info['nlength']).$data; + $cache->save($data, $id, $group); + } + + return $this->appendCompressedData( + $filename, + stat($dataFilename), + $data, + $info['crc'], + $info['nlength'] + ); + + } + + //If no cache system, use the standard way + return parent::appendFile($filename, $dataFilename); + } + + /** + * @see File_Archive_Writer_MemoryArchive::sendFooter() + * @access protected + */ + function sendFooter() + { + return $this->innerWriter->writeData( + $this->central. + "\x50\x4b\x05\x06\x00\x00\x00\x00". + pack("vvVVv", + $this->nbFiles,$this->nbFiles, + strlen($this->central),$this->offset, + strlen($this->comment)). + $this->comment + ); + } + /** + * @see File_Archive_Writer::getMime() + */ + function getMime() { return "application/zip"; } +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Iterator.php b/conlite/plugins/pluginmanager/docs/pear/File/Iterator.php new file mode 100644 index 0000000..e4db9f6 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Iterator.php @@ -0,0 +1,197 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package File + * @author Sebastian Bergmann + * @copyright 2009-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @since File available since Release 1.0.0 + */ + +/** + * FilterIterator implementation that filters files based on prefix(es) and/or + * suffix(es). Hidden files and files from hidden directories are also filtered. + * + * @author Sebastian Bergmann + * @copyright 2009-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 1.2.3 + * @link http://github.com/sebastianbergmann/php-file-iterator/tree + * @since Class available since Release 1.0.0 + */ +class File_Iterator extends FilterIterator +{ + const PREFIX = 0; + const SUFFIX = 1; + + /** + * @var array + */ + protected $suffixes = array(); + + /** + * @var array + */ + protected $prefixes = array(); + + /** + * @var array + */ + protected $exclude = array(); + + /** + * @var string + */ + protected $basepath; + + /** + * @param Iterator $iterator + * @param array $suffixes + * @param array $prefixes + * @param array $exclude + * @param string $basepath + */ + public function __construct(Iterator $iterator, array $suffixes = array(), array $prefixes = array(), array $exclude = array(), $basepath = NULL) + { + $exclude = array_map('realpath', $exclude); + + if ($basepath !== NULL) { + $basepath = realpath($basepath); + } + + if ($basepath === FALSE) { + $basepath = NULL; + } else { + foreach ($exclude as &$_exclude) { + $_exclude = str_replace($basepath, '', $_exclude); + } + } + + $this->prefixes = $prefixes; + $this->suffixes = $suffixes; + $this->exclude = $exclude; + $this->basepath = $basepath; + + parent::__construct($iterator); + } + + /** + * @return boolean + */ + public function accept() + { + $current = $this->getInnerIterator()->current(); + $filename = $current->getFilename(); + $realpath = $current->getRealPath(); + + if ($this->basepath !== NULL) { + $realpath = str_replace($this->basepath, '', $realpath); + } + + // Filter files in hidden directories. + if (preg_match('=/\.[^/]*/=', $realpath)) { + return FALSE; + } + + return $this->acceptPath($realpath) && + $this->acceptPrefix($filename) && + $this->acceptSuffix($filename); + } + + /** + * @param string $path + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptPath($path) + { + foreach ($this->exclude as $exclude) { + if (strpos($path, $exclude) === 0) { + return FALSE; + } + } + + return TRUE; + } + + /** + * @param string $filename + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptPrefix($filename) + { + return $this->acceptSubString($filename, $this->prefixes, self::PREFIX); + } + + /** + * @param string $filename + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptSuffix($filename) + { + return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX); + } + + /** + * @param string $filename + * @param array $subString + * @param integer $type + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptSubString($filename, array $subStrings, $type) + { + if (empty($subStrings)) { + return TRUE; + } + + $matched = FALSE; + + foreach ($subStrings as $string) { + if (($type == self::PREFIX && strpos($filename, $string) === 0) || + ($type == self::SUFFIX && + substr($filename, -1 * strlen($string)) == $string)) { + $matched = TRUE; + break; + } + } + + return $matched; + } +} +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/File/Iterator/Factory.php b/conlite/plugins/pluginmanager/docs/pear/File/Iterator/Factory.php new file mode 100644 index 0000000..34f7bf5 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/File/Iterator/Factory.php @@ -0,0 +1,155 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package File + * @author Sebastian Bergmann + * @copyright 2009-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @since File available since Release 1.1.0 + */ + +require_once 'File/Iterator.php'; + +/** + * Factory Method implementation that creates a File_Iterator that operates on + * an AppendIterator that contains an RecursiveDirectoryIterator for each given + * path. + * + * @author Sebastian Bergmann + * @copyright 2009-2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/bsd-license.php BSD License + * @version Release: 1.2.3 + * @link http://github.com/sebastianbergmann/php-file-iterator/tree + * @since Class available since Release 1.1.0 + */ +class File_Iterator_Factory +{ + /** + * @param array|string $paths + * @param array|string $suffixes + * @param array|string $prefixes + * @param array $exclude + * @return AppendIterator + */ + public static function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = array()) + { + if (is_string($paths)) { + $paths = array($paths); + } + + $_paths = array(); + + foreach ($paths as $path) { + if ($locals = glob($path, GLOB_ONLYDIR)) { + $_paths = array_merge($_paths, $locals); + } else { + $_paths[] = $path; + } + } + + $paths = $_paths; + unset($_paths); + + if (is_string($prefixes)) { + if ($prefixes != '') { + $prefixes = array($prefixes); + } else { + $prefixes = array(); + } + } + + if (is_string($suffixes)) { + if ($suffixes != '') { + $suffixes = array($suffixes); + } else { + $suffixes = array(); + } + } + + $iterator = new AppendIterator; + + foreach ($paths as $path) { + if (is_dir($path)) { + $iterator->append( + new File_Iterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path) + ), + $suffixes, + $prefixes, + $exclude, + $path + ) + ); + } + } + + return $iterator; + } + + /** + * @param array|string $paths + * @param array|string $suffixes + * @param array|string $prefixes + * @param array $exclude + * @return array + */ + public static function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = array()) + { + if (is_string($paths)) { + $paths = array($paths); + } + + $result = array(); + + $iterator = self::getFileIterator( + $paths, $suffixes, $prefixes, $exclude + ); + + foreach ($iterator as $file) { + $result[] = $file->getRealPath(); + } + + foreach ($paths as $path) { + if (is_file($path)) { + $result[] = realpath($path); + } + } + + return $result; + } +} +?> diff --git a/conlite/plugins/pluginmanager/docs/pear/MIME/Type.php b/conlite/plugins/pluginmanager/docs/pear/MIME/Type.php new file mode 100644 index 0000000..51fde09 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/MIME/Type.php @@ -0,0 +1,523 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Type.php 6 2010-11-23 17:57:24Z oldperl $ + +require_once 'PEAR.php'; + +$_fileCmd = &PEAR::getStaticProperty('MIME_Type', 'fileCmd'); +$_fileCmd = 'file'; + +/** + * Class for working with MIME types + * + * @category MIME + * @package MIME_Type + * @license PHP License 3.0 + * @version @version@ + * @link http://pear.php.net/package/MIME_Type + * @author Ian Eure + */ +class MIME_Type +{ + /** + * The MIME media type + * + * @var string + */ + var $media = ''; + + /** + * The MIME media sub-type + * + * @var string + */ + var $subType = ''; + + /** + * Optional MIME parameters + * + * @var array + */ + var $parameters = array(); + + /** + * List of valid media types. + * A media type is the string in front of the slash. + * The media type of "text/xml" would be "text". + * + * @var array + */ + var $validMediaTypes = array( + 'text', + 'image', + 'audio', + 'video', + 'application', + 'multipart', + 'message' + ); + + + /** + * Constructor. + * + * If $type is set, if will be parsed and the appropriate class vars set. + * If not, you get an empty class. + * This is useful, but not quite as useful as parsing a type. + * + * @param string $type MIME type + * + * @return void + */ + function MIME_Type($type = false) + { + if ($type) { + $this->parse($type); + } + } + + + /** + * Parse a mime-type and set the class variables. + * + * @param string $type MIME type to parse + * + * @return void + */ + function parse($type) + { + $this->media = $this->getMedia($type); + $this->subType = $this->getSubType($type); + $this->parameters = array(); + if (MIME_Type::hasParameters($type)) { + require_once 'MIME/Type/Parameter.php'; + foreach (MIME_Type::getParameters($type) as $param) { + $param = new MIME_Type_Parameter($param); + $this->parameters[$param->name] = $param; + } + } + } + + + /** + * Does this type have any parameters? + * + * @param string $type MIME type to check + * + * @return boolean true if $type has parameters, false otherwise + * @static + */ + function hasParameters($type) + { + if (strstr($type, ';')) { + return true; + } + return false; + } + + + /** + * Get a MIME type's parameters + * + * @param string $type MIME type to get parameters of + * + * @return array $type's parameters + * @static + */ + function getParameters($type) + { + $params = array(); + $tmp = explode(';', $type); + for ($i = 1; $i < count($tmp); $i++) { + $params[] = trim($tmp[$i]); + } + return $params; + } + + + /** + * Strip parameters from a MIME type string. + * + * @param string $type MIME type string + * + * @return string MIME type with parameters removed + * @static + */ + function stripParameters($type) + { + if (strstr($type, ';')) { + return substr($type, 0, strpos($type, ';')); + } + return $type; + } + + + /** + * Removes comments from a media type, subtype or parameter. + * + * @param string $string String to strip comments from + * @param string &$comment Comment is stored in there. + * + * @return string String without comments + * @static + */ + function stripComments($string, &$comment) + { + if (strpos($string, '(') === false) { + return $string; + } + + $inquote = false; + $quoting = false; + $incomment = 0; + $newstring = ''; + + for ($n = 0; $n < strlen($string); $n++) { + if ($quoting) { + if ($incomment == 0) { + $newstring .= $string[$n]; + } else if ($comment !== null) { + $comment .= $string[$n]; + } + $quoting = false; + } else if ($string[$n] == '\\') { + $quoting = true; + } else if (!$inquote && $incomment > 0 && $string[$n] == ')') { + $incomment--; + if ($incomment == 0 && $comment !== null) { + $comment .= ' '; + } + } else if (!$inquote && $string[$n] == '(') { + $incomment++; + } else if ($string[$n] == '"') { + if ($inquote) { + $inquote = false; + } else { + $inquote = true; + } + } else if ($incomment == 0) { + $newstring .= $string[$n]; + } else if ($comment !== null) { + $comment .= $string[$n]; + } + } + + if ($comment !== null) { + $comment = trim($comment); + } + + return $newstring; + } + + + /** + * Get a MIME type's media + * + * @note 'media' refers to the portion before the first slash + * + * @param string $type MIME type to get media of + * + * @return string $type's media + * @static + */ + function getMedia($type) + { + $tmp = explode('/', $type); + return strtolower(trim(MIME_Type::stripComments($tmp[0], $null))); + } + + + /** + * Get a MIME type's subtype + * + * @param string $type MIME type to get subtype of + * + * @return string $type's subtype, null if invalid mime type + * @static + */ + function getSubType($type) + { + $tmp = explode('/', $type); + if (!isset($tmp[1])) { + return null; + } + $tmp = explode(';', $tmp[1]); + return strtolower(trim(MIME_Type::stripComments($tmp[0], $null))); + } + + + /** + * Create a textual MIME type from object values + * + * This function performs the opposite function of parse(). + * + * @return string MIME type string + */ + function get() + { + $type = strtolower($this->media . '/' . $this->subType); + if (count($this->parameters)) { + foreach ($this->parameters as $key => $null) { + $type .= '; ' . $this->parameters[$key]->get(); + } + } + return $type; + } + + + /** + * Is this type experimental? + * + * @note Experimental types are denoted by a leading 'x-' in the media or + * subtype, e.g. text/x-vcard or x-world/x-vrml. + * + * @param string $type MIME type to check + * + * @return boolean true if $type is experimental, false otherwise + * @static + */ + function isExperimental($type) + { + if (substr(MIME_Type::getMedia($type), 0, 2) == 'x-' || + substr(MIME_Type::getSubType($type), 0, 2) == 'x-') { + return true; + } + return false; + } + + + /** + * Is this a vendor MIME type? + * + * @note Vendor types are denoted with a leading 'vnd. in the subtype. + * + * @param string $type MIME type to check + * + * @return boolean true if $type is a vendor type, false otherwise + * @static + */ + function isVendor($type) + { + if (substr(MIME_Type::getSubType($type), 0, 4) == 'vnd.') { + return true; + } + return false; + } + + + /** + * Is this a wildcard type? + * + * @param string $type MIME type to check + * + * @return boolean true if $type is a wildcard, false otherwise + * @static + */ + function isWildcard($type) + { + if ($type == '*/*' || MIME_Type::getSubtype($type) == '*') { + return true; + } + return false; + } + + + /** + * Perform a wildcard match on a MIME type + * + * Example: + * MIME_Type::wildcardMatch('image/*', 'image/png') + * + * @param string $card Wildcard to check against + * @param string $type MIME type to check + * + * @return boolean true if there was a match, false otherwise + * @static + */ + function wildcardMatch($card, $type) + { + if (!MIME_Type::isWildcard($card)) { + return false; + } + + if ($card == '*/*') { + return true; + } + + if (MIME_Type::getMedia($card) == MIME_Type::getMedia($type)) { + return true; + } + + return false; + } + + + /** + * Add a parameter to this type + * + * @param string $name Attribute name + * @param string $value Attribute value + * @param string $comment Comment for this parameter + * + * @return void + */ + function addParameter($name, $value, $comment = false) + { + $tmp = new MIME_Type_Parameter(); + + $tmp->name = $name; + $tmp->value = $value; + $tmp->comment = $comment; + $this->parameters[$name] = $tmp; + } + + + /** + * Remove a parameter from this type + * + * @param string $name Parameter name + * + * @return void + */ + function removeParameter($name) + { + unset($this->parameters[$name]); + } + + + /** + * Autodetect a file's MIME-type + * + * This function may be called staticly. + * + * @internal Tries to use fileinfo extension at first. If that + * does not work, mime_magic is used. If this is also not available + * or does not succeed, "file" command is tried to be executed with + * System_Command. When that fails, too, then we use our in-built + * extension-to-mimetype-mapping list. + * + * @param string $file Path to the file to get the type of + * @param bool $params Append MIME parameters if true + * + * @return string $file's MIME-type on success, PEAR_Error otherwise + * + * @since 1.0.0beta1 + * @static + */ + function autoDetect($file, $params = false) + { + // Sanity checks + if (!file_exists($file)) { + return PEAR::raiseError("File \"$file\" doesn't exist"); + } + + if (!is_readable($file)) { + return PEAR::raiseError("File \"$file\" is not readable"); + } + + if (function_exists('finfo_file')) { + $finfo = finfo_open(FILEINFO_MIME); + $type = finfo_file($finfo, $file); + finfo_close($finfo); + if ($type !== false && $type !== '') { + return MIME_Type::_handleDetection($type, $params); + } + } + + if (function_exists('mime_content_type')) { + $type = mime_content_type($file); + if ($type !== false && $type !== '') { + return MIME_Type::_handleDetection($type, $params); + } + } + + @include_once 'System/Command.php'; + if (class_exists('System_Command')) { + return MIME_Type::_handleDetection( + MIME_Type::_fileAutoDetect($file), + $params + ); + } + + require_once 'MIME/Type/Extension.php'; + $mte = new MIME_Type_Extension(); + return $mte->getMIMEType($file); + } + + + /** + * Handles a detected MIME type and modifies it if necessary. + * + * @param string $type MIME Type of a file + * @param bool $params Append MIME parameters if true + * + * @return string $file's MIME-type on success, PEAR_Error otherwise + */ + function _handleDetection($type, $params) + { + // _fileAutoDetect() may have returned an error. + if (PEAR::isError($type)) { + return $type; + } + + // Don't return an empty string + if (!$type || !strlen($type)) { + return PEAR::raiseError("Sorry, couldn't determine file type."); + } + + // Strip parameters if present & requested + if (MIME_Type::hasParameters($type) && !$params) { + $type = MIME_Type::stripParameters($type); + } + + return $type; + } + + + /** + * Autodetect a file's MIME-type with 'file' and System_Command + * + * This function may be called staticly. + * + * @param string $file Path to the file to get the type of + * + * @return string $file's MIME-type + * + * @since 1.0.0beta1 + * @static + */ + function _fileAutoDetect($file) + { + $cmd = new System_Command(); + + // Make sure we have the 'file' command. + $fileCmd = PEAR::getStaticProperty('MIME_Type', 'fileCmd'); + if (!$cmd->which($fileCmd)) { + unset($cmd); + return PEAR::raiseError("Can't find file command \"{$fileCmd}\""); + } + + $cmd->pushCommand($fileCmd, "-bi " . escapeshellarg($file)); + $res = $cmd->execute(); + unset($cmd); + + return $res; + } + +} \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/MIME/Type/Extension.php b/conlite/plugins/pluginmanager/docs/pear/MIME/Type/Extension.php new file mode 100644 index 0000000..1fc4f80 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/MIME/Type/Extension.php @@ -0,0 +1,298 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Extension.php 6 2010-11-23 17:57:24Z oldperl $ + +require_once 'PEAR.php'; + +/** + * Class for mapping file extensions to MIME types. + * + * @category MIME + * @package MIME_Type + * @author Christian Schmidt + * @license PHP License 3.0 + * @version @version@ + * @link http://pear.php.net/package/MIME_Type + */ +class MIME_Type_Extension +{ + /** + * Mapping between file extension and MIME type. + * + * @internal The array is sorted alphabetically by value and with primary + * extension first. Be careful about not adding duplicate keys - PHP + * silently ignores duplicates. The following command can be used for + * checking for duplicates: + * grep "=> '" Extension.php | cut -d\' -f2 | sort | uniq -d + * application/octet-stream is generally used as fallback when no other + * MIME-type can be found, but the array does not contain a lot of such + * unknown extension. One entry exists, though, to allow detection of + * file extension for this MIME-type. + * + * @var array + */ + var $extensionToType = array ( + 'ez' => 'application/andrew-inset', + 'atom' => 'application/atom+xml', + 'jar' => 'application/java-archive', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'mathml' => 'application/mathml+xml', + 'doc' => 'application/msword', + 'dat' => 'application/octet-stream', + 'oda' => 'application/oda', + 'ogg' => 'application/ogg', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'rdf' => 'application/rdf+xml', + 'rss' => 'application/rss+xml', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'gram' => 'application/srgs', + 'grxml' => 'application/srgs+xml', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'mif' => 'application/vnd.mif', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xls' => 'application/vnd.ms-excel', + 'xlb' => 'application/vnd.ms-excel', + 'xlt' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', + 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', + 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', + 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', + 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pps' => 'application/vnd.ms-powerpoint', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'vsd' => 'application/vnd.visio', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'vxml' => 'application/voicexml+xml', + 'bcpio' => 'application/x-bcpio', + 'vcd' => 'application/x-cdlink', + 'pgn' => 'application/x-chess-pgn', + 'cpio' => 'application/x-cpio', + 'csh' => 'application/x-csh', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'spl' => 'application/x-futuresplash', + 'tgz' => 'application/x-gtar', + 'gtar' => 'application/x-gtar', + 'hdf' => 'application/x-hdf', + 'js' => 'application/x-javascript', + 'skp' => 'application/x-koan', + 'skd' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'latex' => 'application/x-latex', + 'nc' => 'application/x-netcdf', + 'cdf' => 'application/x-netcdf', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'tar' => 'application/x-tar', + 'tcl' => 'application/x-tcl', + 'tex' => 'application/x-tex', + 'texinfo' => 'application/x-texinfo', + 'texi' => 'application/x-texinfo', + 't' => 'application/x-troff', + 'tr' => 'application/x-troff', + 'roff' => 'application/x-troff', + 'man' => 'application/x-troff-man', + 'me' => 'application/x-troff-me', + 'ms' => 'application/x-troff-ms', + 'ustar' => 'application/x-ustar', + 'src' => 'application/x-wais-source', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'xslt' => 'application/xslt+xml', + 'xml' => 'application/xml', + 'xsl' => 'application/xml', + 'dtd' => 'application/xml-dtd', + 'zip' => 'application/zip', + 'au' => 'audio/basic', + 'snd' => 'audio/basic', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'kar' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'm3u' => 'audio/x-mpegurl', + 'wma' => 'audio/x-ms-wma', + 'wax' => 'audio/x-ms-wax', + 'ram' => 'audio/x-pn-realaudio', + 'ra' => 'audio/x-pn-realaudio', + 'rm' => 'application/vnd.rn-realmedia', + 'wav' => 'audio/x-wav', + 'pdb' => 'chemical/x-pdb', + 'xyz' => 'chemical/x-xyz', + 'bmp' => 'image/bmp', + 'cgm' => 'image/cgm', + 'gif' => 'image/gif', + 'ief' => 'image/ief', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'svg' => 'image/svg+xml', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'djvu' => 'image/vnd.djvu', + 'djv' => 'image/vnd.djvu', + 'wbmp' => 'image/vnd.wap.wbmp', + 'ras' => 'image/x-cmu-raster', + 'ico' => 'image/x-icon', + 'pnm' => 'image/x-portable-anymap', + 'pbm' => 'image/x-portable-bitmap', + 'pgm' => 'image/x-portable-graymap', + 'ppm' => 'image/x-portable-pixmap', + 'rgb' => 'image/x-rgb', + 'xbm' => 'image/x-xbitmap', + 'psd' => 'image/x-photoshop', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'eml' => 'message/rfc822', + 'igs' => 'model/iges', + 'iges' => 'model/iges', + 'msh' => 'model/mesh', + 'mesh' => 'model/mesh', + 'silo' => 'model/mesh', + 'wrl' => 'model/vrml', + 'vrml' => 'model/vrml', + 'ics' => 'text/calendar', + 'ifb' => 'text/calendar', + 'css' => 'text/css', + 'csv' => 'text/csv', + 'html' => 'text/html', + 'htm' => 'text/html', + 'txt' => 'text/plain', + 'asc' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'sgml' => 'text/sgml', + 'sgm' => 'text/sgml', + 'tsv' => 'text/tab-separated-values', + 'wml' => 'text/vnd.wap.wml', + 'wmls' => 'text/vnd.wap.wmlscript', + 'etx' => 'text/x-setext', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'mxu' => 'video/vnd.mpegurl', + 'm4u' => 'video/vnd.mpegurl', + 'flv' => 'video/x-flv', + 'asf' => 'video/x-ms-asf', + 'asx' => 'video/x-ms-asf', + 'wmv' => 'video/x-ms-wmv', + 'wm' => 'video/x-ms-wm', + 'wmx' => 'video/x-ms-wmx', + 'avi' => 'video/x-msvideo', + 'ogv' => 'video/ogg', + 'movie' => 'video/x-sgi-movie', + 'ice' => 'x-conference/x-cooltalk', + ); + + + + /** + * Autodetect a file's MIME-type. + * + * @param string $file Path to the file to get the type of + * + * @return string $file's MIME-type on success, PEAR_Error otherwise + */ + function getMIMEType($file) + { + $extension = substr(strrchr($file, '.'), 1); + if ($extension === false) { + return PEAR::raiseError("File has no extension."); + } + + if (!isset($this->extensionToType[$extension])) { + return PEAR::raiseError("Sorry, couldn't determine file type."); + } + + return $this->extensionToType[$extension]; + } + + + + /** + * Return default MIME-type for the specified extension. + * + * @param string $type MIME-type + * + * @return string A file extension without leading period. + */ + function getExtension($type) + { + require_once 'MIME/Type.php'; + // Strip parameters and comments. + $type = MIME_Type::getMedia($type) . '/' . MIME_Type::getSubType($type); + + $extension = array_search($type, $this->extensionToType); + if ($extension === false) { + return PEAR::raiseError("Sorry, couldn't determine extension."); + } + return $extension; + } + +} + +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/docs/pear/MIME/Type/Parameter.php b/conlite/plugins/pluginmanager/docs/pear/MIME/Type/Parameter.php new file mode 100644 index 0000000..8058371 --- /dev/null +++ b/conlite/plugins/pluginmanager/docs/pear/MIME/Type/Parameter.php @@ -0,0 +1,163 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Parameter.php 6 2010-11-23 17:57:24Z oldperl $ + +/** + * Class for working with MIME type parameters + * + * @version @version@ + * @package MIME_Type + * @author Ian Eure + */ +class MIME_Type_Parameter { + /** + * Parameter name + * + * @var string + */ + var $name; + + /** + * Parameter value + * + * @var string + */ + var $value; + + /** + * Parameter comment + * + * @var string + */ + var $comment; + + + /** + * Constructor. + * + * @param string $param MIME parameter to parse, if set. + * @return void + */ + function MIME_Type_Parameter($param = false) + { + if ($param) { + $this->parse($param); + } + } + + + /** + * Parse a MIME type parameter and set object fields + * + * @param string $param MIME type parameter to parse + * @return void + */ + function parse($param) + { + $comment = ''; + $param = MIME_Type::stripComments($param, $comment); + $this->name = $this->getAttribute($param); + $this->value = $this->getValue($param); + $this->comment = $comment; + } + + + /** + * Get a parameter attribute (e.g. name) + * + * @param string MIME type parameter + * @return string Attribute name + * @static + */ + function getAttribute($param) + { + $tmp = explode('=', $param); + return trim($tmp[0]); + } + + + /** + * Get a parameter value + * + * @param string $param MIME type parameter + * @return string Value + * @static + */ + function getValue($param) + { + $tmp = explode('=', $param, 2); + $value = $tmp[1]; + $value = trim($value); + if ($value[0] == '"' && $value[strlen($value)-1] == '"') { + $value = substr($value, 1, -1); + } + $value = str_replace('\\"', '"', $value); + return $value; + } + + + /** + * Get a parameter comment + * + * @param string $param MIME type parameter + * @return string Parameter comment + * @see getComment() + * @static + */ + function getComment($param) + { + $cs = strpos($param, '('); + $comment = substr($param, $cs); + return trim($comment, '() '); + } + + + /** + * Does this parameter have a comment? + * + * @param string $param MIME type parameter + * @return boolean true if $param has a comment, false otherwise + * @static + */ + function hasComment($param) + { + if (strstr($param, '(')) { + return true; + } + return false; + } + + + /** + * Get a string representation of this parameter + * + * This function performs the oppsite of parse() + * + * @return string String representation of parameter + */ + function get() + { + $val = $this->name . '="' . str_replace('"', '\\"', $this->value) . '"'; + if ($this->comment) { + $val .= ' (' . $this->comment . ')'; + } + return $val; + } +} +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/includes/config.autoloader.php b/conlite/plugins/pluginmanager/includes/config.autoloader.php new file mode 100644 index 0000000..d3dbf7d --- /dev/null +++ b/conlite/plugins/pluginmanager/includes/config.autoloader.php @@ -0,0 +1,30 @@ + $sAutoloadClassPath.'class.pim.plugin.php', + 'pimPlugin' => $sAutoloadClassPath.'class.pim.plugin.php', + 'pimPluginDummy' => $sAutoloadClassPath.'class.pim.plugin.dummy.php', + 'pimPluginRelationCollection' => $sAutoloadClassPath.'class.pim.plugin.relation.php', + 'pimPluginRelation' => $sAutoloadClassPath.'class.pim.plugin.relation.php', + 'pimView' => $sAutoloadClassPath.'class.pim.view.php', + 'pimAjax' => $sAutoloadClassPath.'class.pim.ajax.php', + 'pimSetupBase' => $sAutoloadClassPath.'setup/class.pim.setup.base.php', + 'pimSetupPluginInstall' => $sAutoloadClassPath.'setup/class.pim.setup.plugin.install.php', + 'pimSetupPluginUninstall' => $sAutoloadClassPath.'setup/class.pim.setup.plugin.uninstall.php', + 'PluginmanagerAjax' => $sAutoloadClassPath.'class.pluginmanager.ajax.php', + 'pimPluginHandler' => $sAutoloadClassPath.'class.pim.plugin.handler.php', + 'Plugins' => $sAutoloadClassPath.'plugin/interface.plugins.php', + 'pluginHandlerAbstract' => $sAutoloadClassPath.'plugin/class.plugin.handler.abstract.php', + 'pimExeption' => $sAutoloadClassPath.'exeptions/class.pim.exeption.php', + 'pimXmlStructureException' => $sAutoloadClassPath.'exeptions/class.pim.exeption.php', + 'pimSqlParser' => $sAutoloadClassPath.'Util/class.pim.sql.parser.php' + // the following entries may be deleted after recode of pim + //'Contenido_Plugin_Base' => $sAutoloadClassPath.'Contenido_Plugin_Base.class.php', + //'Contenido_PluginConfig_Settings' => $sAutoloadClassPath.'Config/Contenido_PluginConfig_Settings.class.php', + //'Contenido_PluginSetup' => $sAutoloadClassPath.'Setup/Contenido_PluginSetup.class.php', + //'Contenido_VersionCompare_Exception' => $sAutoloadClassPath.'Exceptions/Contenido_VersionCompare_Exception.php', + //'Contenido_PluginSqlBuilder_Deinstall' => $sAutoloadClassPath.'Sql/Contenido_PluginSqlBuilder_Deinstall.php', + //'Contenido_PluginSqlBuilder_Install' => $sAutoloadClassPath.'Sql/Contenido_PluginSqlBuilder_Install.php', + //'Contenido_ArchiveExtractor' => $sAutoloadClassPath.'Util/Zip/Contenido_ArchiveExtractor.class.php' +); +?> \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/includes/config.plugin.php b/conlite/plugins/pluginmanager/includes/config.plugin.php new file mode 100644 index 0000000..7e48e2f --- /dev/null +++ b/conlite/plugins/pluginmanager/includes/config.plugin.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/includes/functions/simplexml_dump.php b/conlite/plugins/pluginmanager/includes/functions/simplexml_dump.php new file mode 100644 index 0000000..28e51b7 --- /dev/null +++ b/conlite/plugins/pluginmanager/includes/functions/simplexml_dump.php @@ -0,0 +1,200 @@ +getDocNamespaces(false); + + $dump = ''; + // Note that the header is added at the end, so we can add stats + $dump .= '[' . PHP_EOL; + + // SimpleXML objects can be either a single node, or (more commonly) a list of 0 or more nodes + // I haven't found a reliable way of distinguishing between the two cases + // Note that for a single node, foreach($node) acts like foreach($node->children()) + // Numeric array indexes, however, operate consistently: $node[0] just returns the node + $item_index = 0; + while ( isset($sxml[$item_index]) ) + { + $item = $sxml[$item_index]; + $item_index++; + + // It's surprisingly hard to find something which behaves consistently differently for an attribute and an element within SimpleXML + // The below relies on the fact that the DOM makes a much clearer distinction + // Note that this is not an expensive conversion, as we are only swapping PHP wrappers around an existing LibXML resource + if ( dom_import_simplexml($item) instanceOf DOMAttr ) + { + $dump .= $indent . 'Attribute {' . PHP_EOL; + + // To what namespace does this attribute belong? Returns array( alias => URI ) + $ns = $item->getNamespaces(false); + if ( $ns ) + { + $dump .= $indent . $indent . 'Namespace: \'' . reset($ns) . '\'' . PHP_EOL; + if ( key($ns) == '' ) + { + $dump .= $indent . $indent . '(Default Namespace)' . PHP_EOL; + } + else + { + $dump .= $indent . $indent . 'Namespace Alias: \'' . key($ns) . '\'' . PHP_EOL; + } + } + + $dump .= $indent . $indent . 'Name: \'' . $item->getName() . '\'' . PHP_EOL; + $dump .= $indent . $indent . 'Value: \'' . (string)$item . '\'' . PHP_EOL; + + $dump .= $indent . '}' . PHP_EOL; + } + else + { + $dump .= $indent . 'Element {' . PHP_EOL; + + // To what namespace does this element belong? Returns array( alias => URI ) + $ns = $item->getNamespaces(false); + if ( $ns ) + { + $dump .= $indent . $indent . 'Namespace: \'' . reset($ns) . '\'' . PHP_EOL; + if ( key($ns) == '' ) + { + $dump .= $indent . $indent . '(Default Namespace)' . PHP_EOL; + } + else + { + $dump .= $indent . $indent . 'Namespace Alias: \'' . key($ns) . '\'' . PHP_EOL; + } + } + + $dump .= $indent . $indent . 'Name: \'' . $item->getName() . '\'' . PHP_EOL; + // REMEMBER: ALWAYS CAST TO STRING! :) + $dump .= $indent . $indent . 'String Content: \'' . (string)$item . '\'' . PHP_EOL; + + // Now some statistics about attributes and children, by namespace + + // This returns all namespaces used by this node and all its descendants, + // whether declared in this node, in its ancestors, or in its descendants + $all_ns = $item->getNamespaces(true); + // If the default namespace is never declared, it will never show up using the below code + if ( ! array_key_exists('', $all_ns) ) + { + $all_ns[''] = NULL; + } + + foreach ( $all_ns as $ns_alias => $ns_uri ) + { + $children = $item->children($ns_uri); + $attributes = $item->attributes($ns_uri); + + // Somewhat confusingly, in the case where a parent element is missing the xmlns declaration, + // but a descendant adds it, SimpleXML will look ahead and fill $all_ns[''] incorrectly + if ( + $ns_alias == '' + && + ! is_null($ns_uri) + && + count($children) == 0 + && + count($attributes) == 0 + ) + { + // Try looking for a default namespace without a known URI + $ns_uri = NULL; + $children = $item->children($ns_uri); + $attributes = $item->attributes($ns_uri); + } + + // Don't show zero-counts, as they're not that useful + if ( count($children) == 0 && count($attributes) == 0 ) + { + continue; + } + + $ns_label = (($ns_alias == '') ? 'Default Namespace' : "Namespace $ns_alias"); + $dump .= $indent . $indent . 'Content in ' . $ns_label . PHP_EOL; + + if ( ! is_null($ns_uri) ) + { + $dump .= $indent . $indent . $indent . 'Namespace URI: \'' . $ns_uri . '\'' . PHP_EOL; + } + + // Count occurrence of child element names, rather than listing them all out + $child_names = array(); + foreach ( $children as $sx_child ) + { + // Below is a rather clunky way of saying $child_names[ $sx_child->getName() ]++; + // which avoids Notices about unset array keys + $child_node_name = $sx_child->getName(); + if ( array_key_exists($child_node_name, $child_names) ) + { + $child_names[$child_node_name]++; + } + else + { + $child_names[$child_node_name] = 1; + } + } + ksort($child_names); + $child_name_output = array(); + foreach ( $child_names as $name => $count ) + { + $child_name_output[] = "$count '$name'"; + } + + $dump .= $indent . $indent . $indent . 'Children: ' . count($children); + // Don't output a trailing " - " if there are no children + if ( count($children) > 0 ) + { + $dump .= ' - ' . implode(', ', $child_name_output); + } + $dump .= PHP_EOL; + + // Attributes can't be duplicated, but I'm going to put them in alphabetical order + $attribute_names = array(); + foreach ( $attributes as $sx_attribute ) + { + $attribute_names[] = "'" . $sx_attribute->getName() . "'"; + } + ksort($attribute_names); + $dump .= $indent . $indent . $indent . 'Attributes: ' . count($attributes); + // Don't output a trailing " - " if there are no attributes + if ( count($attributes) > 0 ) + { + $dump .= ' - ' . implode(', ', $attribute_names); + } + $dump .= PHP_EOL; + } + + $dump .= $indent . '}' . PHP_EOL; + } + } + $dump .= ']' . PHP_EOL; + + // Add on the header line, with the total number of items output + $dump = 'SimpleXML object (' . $item_index . ' item' . ($item_index > 1 ? 's' : '') . ')' . PHP_EOL . $dump; + + if ( $return ) + { + return $dump; + } + else + { + echo $dump; + } +} diff --git a/conlite/plugins/pluginmanager/includes/functions/simplexml_tree.php b/conlite/plugins/pluginmanager/includes/functions/simplexml_tree.php new file mode 100644 index 0000000..4348d2f --- /dev/null +++ b/conlite/plugins/pluginmanager/includes/functions/simplexml_tree.php @@ -0,0 +1,249 @@ +getDocNamespaces(false); + + $dump = ''; + // Note that the header is added at the end, so we can add stats + + // The initial object passed in may be a single node or a list of nodes, so we need an outer loop first + // Note that for a single node, foreach($node) acts like foreach($node->children()) + // Numeric array indexes, however, operate consistently: $node[0] just returns the node + $root_item_index = 0; + while ( isset($sxml[$root_item_index]) ) + { + $root_item = $sxml[$root_item_index]; + + // Special case if the root is actually an attribute + // It's surprisingly hard to find something which behaves consistently differently for an attribute and an element within SimpleXML + // The below relies on the fact that the DOM makes a much clearer distinction + // Note that this is not an expensive conversion, as we are only swapping PHP wrappers around an existing LibXML resource + if ( dom_import_simplexml($root_item) instanceOf DOMAttr ) + { + // To what namespace does this attribute belong? Returns array( alias => URI ) + $ns = $root_item->getNamespaces(false); + if ( key($ns) ) + { + $dump .= key($ns) . ':'; + } + $dump .= $root_item->getName() . '="' . (string)$root_item . '"' . PHP_EOL; + } + else + { + // Display the root node as a numeric key reference, plus a hint as to its tag name + // e.g. '[42] // ' + + // To what namespace does this attribute belong? Returns array( alias => URI ) + $ns = $root_item->getNamespaces(false); + if ( key($ns) ) + { + $root_node_name = key($ns) . ':' . $root_item->getName(); + } + else + { + $root_node_name = $root_item->getName(); + } + $dump .= "[$root_item_index] // <$root_node_name>" . PHP_EOL; + + // This function is effectively recursing depth-first through the tree, + // but this is managed manually using a stack rather than actual recursion + // Each item on the stack is of the form array(int $depth, SimpleXMLElement $element, string $header_row) + $dump .= _simplexml_tree_recursively_process_node( + $root_item, 1, + $include_string_content, $indent, $content_extract_size + ); + } + + $root_item_index++; + } + + // Add on the header line, with the total number of items output + $dump = 'SimpleXML object (' . $root_item_index . ' item' . ($root_item_index > 1 ? 's' : '') . ')' . PHP_EOL . $dump; + + if ( $return ) + { + return $dump; + } + else + { + echo $dump; + } +} + +/** + * "Private" function to perform the recursive part of simplexml_tree() + * Do not call this function directly or rely on its function signature remaining stable + */ +function _simplexml_tree_recursively_process_node($item, $depth, $include_string_content, $indent, $content_extract_size) +{ + $dump = ''; + + if ( $include_string_content ) + { + // Show a chunk of the beginning of the content string, collapsing whitespace HTML-style + $string_content = (string)$item; + + $string_extract = preg_replace('/\s+/', ' ', trim($string_content)); + if ( strlen($string_extract) > $content_extract_size ) + { + $string_extract = substr($string_extract, 0, $content_extract_size) + . '...'; + } + + if ( strlen($string_content) > 0 ) + { + $dump .= str_repeat($indent, $depth) + . '(string) ' + . "'$string_extract'" + . ' (' . strlen($string_content) . ' chars)' + . PHP_EOL; + } + } + + // To what namespace does this element belong? Returns array( alias => URI ) + $item_ns = $item->getNamespaces(false); + if ( ! $item_ns ) + { + $item_ns = array('' => NULL); + } + + // This returns all namespaces used by this node and all its descendants, + // whether declared in this node, in its ancestors, or in its descendants + $all_ns = $item->getNamespaces(true); + // If the default namespace is never declared, it will never show up using the below code + if ( ! array_key_exists('', $all_ns) ) + { + $all_ns[''] = NULL; + } + + // Prioritise "current" namespace by merging into onto the beginning of the list + // (it will be added to the beginning and the duplicate entry dropped) + $all_ns = array_merge($item_ns, $all_ns); + + foreach ( $all_ns as $ns_alias => $ns_uri ) + { + $children = $item->children($ns_alias, true); + $attributes = $item->attributes($ns_alias, true); + + // If things are in the current namespace, display them a bit differently + $is_current_namespace = ( $ns_uri == reset($item_ns) ); + + if ( count($attributes) > 0 ) + { + if ( ! $is_current_namespace ) + { + $dump .= str_repeat($indent, $depth) + . "->attributes('$ns_alias', true)" . PHP_EOL; + } + + foreach ( $attributes as $sx_attribute ) + { + // Output the attribute + if ( $is_current_namespace ) + { + // In current namespace + // e.g. ['attribName'] + $dump .= str_repeat($indent, $depth) + . "['" . $sx_attribute->getName() . "']" + . PHP_EOL; + $string_display_depth = $depth+1; + } + else + { + // After a call to ->attributes() + // e.g. ->attribName + $dump .= str_repeat($indent, $depth+1) + . '->' . $sx_attribute->getName() + . PHP_EOL; + $string_display_depth = $depth+2; + } + + if ( $include_string_content ) + { + // Show a chunk of the beginning of the content string, collapsing whitespace HTML-style + $string_content = (string)$sx_attribute; + + $string_extract = preg_replace('/\s+/', ' ', trim($string_content)); + if ( strlen($string_extract) > $content_extract_size ) + { + $string_extract = substr($string_extract, 0, $content_extract_size) + . '...'; + } + + $dump .= str_repeat($indent, $string_display_depth) + . '(string) ' + . "'$string_extract'" + . ' (' . strlen($string_content) . ' chars)' + . PHP_EOL; + } + } + } + + if ( count($children) > 0 ) + { + if ( $is_current_namespace ) + { + $display_depth = $depth; + } + else + { + $dump .= str_repeat($indent, $depth) + . "->children('$ns_alias', true)" . PHP_EOL; + $display_depth = $depth + 1; + } + + // Recurse through the children with headers showing how to access them + $child_names = array(); + foreach ( $children as $sx_child ) + { + // Below is a rather clunky way of saying $child_names[ $sx_child->getName() ]++; + // which avoids Notices about unset array keys + $child_node_name = $sx_child->getName(); + if ( array_key_exists($child_node_name, $child_names) ) + { + $child_names[$child_node_name]++; + } + else + { + $child_names[$child_node_name] = 1; + } + + // e.g. ->Foo[0] + $dump .= str_repeat($indent, $display_depth) + . '->' . $sx_child->getName() + . '[' . ($child_names[$child_node_name]-1) . ']' + . PHP_EOL; + + $dump .= _simplexml_tree_recursively_process_node( + $sx_child, $display_depth+1, + $include_string_content, $indent, $content_extract_size + ); + } + } + } + + return $dump; +} diff --git a/conlite/plugins/pluginmanager/includes/include.right_bottom.php b/conlite/plugins/pluginmanager/includes/include.right_bottom.php new file mode 100644 index 0000000..7ac550c --- /dev/null +++ b/conlite/plugins/pluginmanager/includes/include.right_bottom.php @@ -0,0 +1,221 @@ + + * @author Frederic Schneider + * @copyright (c) 2008-2015, ConLite.org + * + * $Id: include.right_bottom.php 41 2018-05-20 21:55:49Z oldperl $ + */ +if (!defined('CON_FRAMEWORK')) { + die('Illegal call'); +} +/* @var $sess Contenido_Session */ +/* @var $perm Contenido_Perm */ +/* @var $auth Contenido_Challenge_Crypt_Auth */ + +$oNoti = new Contenido_Notification(); +$aMessages = array(); +$oPage = new cPage(); +$oPage->sendNoCacheHeaders(); +$oPage->setHtml5(); +$oPage->addCssFile("plugins/pluginmanager/css/pluginmanager.css"); +$oPage->addJsFile("plugins/pluginmanager/scripts/jquery.plainoverlay.js"); +$oPage->addJsFile("plugins/pluginmanager/scripts/jquery.plainmodal.js"); +$oPage->addJsFile("plugins/pluginmanager/scripts/pluginmanager.js"); + +// give permission only to sysadmin +/* @var $perm Contenido_Perm */ +if (!$perm->isSysadmin()) { + $oPage->setContent($oNoti->returnNotification(Contenido_Notification::LEVEL_ERROR, i18n("Permission denied!"))); + $oPage->render(); + die(); +} + +// check disable plugin var +if ($cfg['debug']['disable_plugins'] === true) { + $oPage->setContent($oNoti->returnNotification(Contenido_Notification::LEVEL_WARNING, i18n('Currently the plugin system is disabled via configuration', "pluginmanager"))); + $oPage->render(); +} + +$oPimPluginCollection = new pimPluginCollection(); +$oView = new pimView(); + +$sViewAction = isset($_REQUEST['plugin_action']) ? $_REQUEST['plugin_action'] : 'overview'; + +switch ($sViewAction) { + case 'uninstall_plugin': + $iPluginId = (int) $_POST['plugin_id']; + $oPluginHandler = new pimPluginHandler(); + if($oPluginHandler->loadPluginFromDb($iPluginId)) { + if($oPluginHandler->uninstallPlugin($_POST['delete_sql'])) { + $aMessages[] = "info:".i18n("Plugin uninstalled!", "pluginmanager"); + } else { + $aMessages[] = "error:".i18n("Cannot uninstall Plugin!", "pluginmanager"); + } + } else { + $aMessages[] = "error:".i18n("Cannot uninstall Plugin! Plugin not found in Db.", "pluginmanager"); + } + break; + case 'upload': + $aMessages[] = "info:".i18n("Feature not implemented right now!", "pluginmanager"); + /* + // name of uploaded file + $sTempFile = Contenido_Security::escapeDB($_FILES['package']['name'], null); + + // path to pluginmanager temp-dir + $sTempFilePath = $cfg['path']['contenido'] . $cfg['path']['plugins'] . 'pluginmanager' . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR; + + move_uploaded_file($_FILES['package']['tmp_name'], $sTempFilePath . $sTempFile); + + $oExtractor = new Contenido_ArchiveExtractor($sTempFilePath . $sTempFile); + + // xml file validation + $oSetup->sTempXml = $oExtractor->extractArchiveFileToVariable('plugin.xml'); + $oSetup->checkXml(); + + // load plugin.xml to an xml-string + $oTempXml = simplexml_load_string($oSetup->sTempXml); + + // check min contenido version + if (!empty($oTempXml->general->min_contenido_version) && version_compare($cfg['version'], $oTempXml->general->min_contenido_version, '<')) { + throw new Contenido_VersionCompare_Exception(i18n("You have to installed Contenido ") . $oTempXml->general->min_contenido_version . i18n(" or higher to install this plugin!")); + } + + // build the new plugin dir + $sTempPluginDir = $cfg['path']['contenido'] . $cfg['path']['plugins'] . $oTempXml->general->plugin_foldername . DIRECTORY_SEPARATOR; + + // add sql inserts + $oSql = new Contenido_PluginSqlBuilder_Install($cfg, (int) $client, $oTempXml); + + if ($oSetup->bValid === true) { + $oExtractor->setDestinationPath($sTempPluginDir); + $oExtractor->extractArchive(); + } + + unlink($sTempPluginDir . 'plugin.xml'); + unlink($sTempFilePath . $sTempFile); + */ + break; + default: + break; +} + +// get installed plugins and build view +$aPluginsInstalled = array(); +$sPlugins = ''; +$oPimPluginCollection->select(NULL, NULL, 'executionorder'); +$iNumInstalledPlugins = $oPimPluginCollection->count(); +/* @var $oPimPlugin pimPlugin */ +while ($oPimPlugin = $oPimPluginCollection->next()) { + // initalization new class + $iIdPlugin = $oPimPlugin->get("idplugin"); + $oView2 = new pimView(); + $oPluginHandler = new pimPluginHandler(); + $sPlugins .= $oPluginHandler->getInfoInstalled($iIdPlugin); + $aPluginsInstalled[] = $oPimPlugin->get("folder"); +} + +// get plugins extracted but not installed +if (is_dir($cfg['path']['plugins'])) { + if ($handle = opendir($cfg['path']['plugins'])) { + $iPiExCount = (int) count($aPluginsInstalled) + 1; + $pluginsExtracted = ''; + $aNeededTplVar = array( + "description"=> i18n("This plugin has no description.", "pluginmanager"), + "dependencies" => i18n("This plugin has no dependencies.", "pluginmanager"), + "license" => i18n("License not set.", "pluginmanager") + ); + + $aDefaultLang = array( + 'lang_foldername' => i18n('Foldername', 'pluginmanager'), + 'lang_author' => i18n("Author", "pluginmanager"), + 'lang_contact' => i18n("Contact", "pluginmanager"), + 'lang_license' => i18n("License", "pluginmanager"), + 'lang_dependencies' => i18n("Dependencies", "pluginmanager"), + 'lang_writeable' => i18n("Writable", "pluginmanager") + ); + + while ($pluginFoldername = readdir($handle)) { + $pluginPath = $cfg['path']['contenido'] . $cfg['path']['plugins'] . $pluginFoldername; + $bPiPathWritable = (is_writable($pluginPath))?TRUE:FALSE; + $sPiCfg = $pluginPath . '/cl_plugin.xml'; + + if (is_dir($pluginPath) && file_exists($sPiCfg) && !in_array($pluginFoldername, $aPluginsInstalled)) { + + // get infos from plugin.xml + $oPluginHandler = new pimPluginHandler(); + if(FALSE === $oPluginHandler->loadXmlFile($sPiCfg)) { + $aMessages[] = "error:".sprintf(i18n('Invalid Xml document for %s. Please contact the plugin author.', 'pluginmanager'),$sPiCfg); + continue; + } + //echo "
";
+                //print_r($oPluginHandler->getCfgXmlObject());
+                $aNeededTplVar['writeable'] = ($bPiPathWritable)?i18n("Everything looks fine.", "pluginmanager"):''
+                    .i18n("Pluginfolder not writable!", "pluginmanager").'<\span>';
+                $aInfoGeneral = array_merge($aNeededTplVar, $oPluginHandler->getPiGeneralArray());
+                //echo "
";
+                //print_r($aInfoGeneral);
+                
+                // initalization new template class
+                $oView2 = new pimView();
+                $oView2->setVariable($iPiExCount, "PLUGIN_NUMBER");
+                $oView2->setMultiVariables($aInfoGeneral);
+                $aLang = array(
+                    'FOLDERNAME' => $pluginFoldername,
+                    'INSTALL_LINK' => $sess->url('main.php?area='.$area.'&frame=4&pim_view=install-extracted&pluginFoldername=' . $pluginFoldername)
+                );
+                $oView2->setMultiVariables(array_merge($aLang, $aDefaultLang));                
+                
+                $oView2->setTemplate('pi_manager_extracted_plugins.html');
+                $pluginsExtracted .= $oView2->getRendered(1);
+                $iPiExCount++;
+            }
+        }
+        closedir($handle);
+    }
+}
+
+// if pluginsExtracted var is empty
+if (empty($pluginsExtracted)) {
+    $pluginsExtracted = i18n('No entries', 'pim');
+}
+
+
+// added language vars
+$oView->setVariable(i18n("Add new plugin", 'pluginmanager'), 'LANG_ADD');
+$oView->setVariable(i18n("Please choose a plugin package", 'pluginmanager'), 'LANG_ADD_CHOOSE');
+$oView->setVariable(i18n("Upload plugin package", 'pluginmanager'), 'LANG_ADD_UPLOAD');
+$oView->setVariable(i18n("Remove marked Plugins", 'pluginmanager'), 'LANG_DELETE');
+$oView->setVariable(i18n("Installed Plugins", 'pluginmanager'), 'LANG_INSTALLED');
+$oView->setVariable(i18n("Update marked plugins", 'pluginmanager'), 'LANG_UPDATE');
+$oView->setVariable(i18n('Plugins to install', 'pluginmanager'), 'LANG_EXTRACTED');
+$oView->setVariable(i18n('Drag & Drop plugin to list of installed plugins to install it.', 'pluginmanager'), 'LANG_HINT_EXTRACTED');
+
+// added installed plugins to pi_manager_overview
+$oView->setVariable($iNumInstalledPlugins, 'INSTALLED_PLUGINS');
+$oView->setVariable($sPlugins, 'PLUGINS');
+$oView->setVariable($pluginsExtracted, 'PLUGINS_EXTRACTED');
+
+//print_r($aMessages);
+// show overview page
+$oView->setTemplate('pi_manager_overview.html');
+$sMessages = "";
+if(count($aMessages) > 0 ) {
+    $sMessages .= '";
+}
+//$oView->getRendered();
+$oPage->setContent(array($oView->getRendered(1), $sMessages));
+$oPage->render();
+?>
\ No newline at end of file
diff --git a/conlite/plugins/pluginmanager/locale/de_DE/LC_MESSAGES/pluginmanager.mo b/conlite/plugins/pluginmanager/locale/de_DE/LC_MESSAGES/pluginmanager.mo
new file mode 100644
index 0000000..eccc439
Binary files /dev/null and b/conlite/plugins/pluginmanager/locale/de_DE/LC_MESSAGES/pluginmanager.mo differ
diff --git a/conlite/plugins/pluginmanager/locale/de_DE/LC_MESSAGES/pluginmanager.po b/conlite/plugins/pluginmanager/locale/de_DE/LC_MESSAGES/pluginmanager.po
new file mode 100644
index 0000000..d4f6420
--- /dev/null
+++ b/conlite/plugins/pluginmanager/locale/de_DE/LC_MESSAGES/pluginmanager.po
@@ -0,0 +1,236 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Contenido PluginManager\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-08-11 14:07+0200\n"
+"PO-Revision-Date: 2017-12-19 10:21+0100\n"
+"Last-Translator: Ortwin Pinke \n"
+"Language-Team: Frederic Schneider \n"
+"Language: de_DE\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-KeywordsList: i18n\n"
+"X-Generator: Poedit 1.5.4\n"
+"X-Poedit-Basepath: .\n"
+"X-Poedit-SearchPath-0: C:\\Dateien\\Contenido PluginManager\\includes\n"
+
+#: includes/include.right_bottom.php:37
+msgid "Permission denied!"
+msgstr "Zugriff verweigert!"
+
+#: includes/include.right_bottom.php:44
+msgid "Currently the plugin system is disabled via configuration"
+msgstr "Momentan ist das Pluginsystem via Konfiguration abgeschaltet"
+
+#: includes/include.right_bottom.php:59
+msgid "Plugin uninstalled!"
+msgstr "Plugin deinstalliert!"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:61
+msgid "Cannot uninstall Plugin!"
+msgstr "Kann Plugin nicht entfernen!"
+
+#: includes/include.right_bottom.php:64
+msgid "Cannot uninstall Plugin! Plugin not found in Db."
+msgstr "Plugin kann nicht deinstalliert werden! Plugin nicht in der DB."
+
+#: includes/include.right_bottom.php:68
+msgid "Feature not implemented right now!"
+msgstr "Feature noch nicht implementiert!"
+
+#: includes/include.right_bottom.php:131
+msgid "This plugin has no description."
+msgstr "Das Plugin hat keine Beschreibung."
+
+#: includes/include.right_bottom.php:132
+msgid "This plugin has no dependencies."
+msgstr "Das Plugin hat keine Abhängigkeiten."
+
+#: includes/include.right_bottom.php:133
+msgid "License not set."
+msgstr "Keine Lizenzangabe vorhanden."
+
+#: includes/include.right_bottom.php:137
+#: classes/class.pim.plugin.handler.php:162
+msgid "Foldername"
+msgstr "Verzeichnisname"
+
+#: includes/include.right_bottom.php:138
+#: classes/class.pim.plugin.handler.php:163
+msgid "Author"
+msgstr "Autor"
+
+#: includes/include.right_bottom.php:139
+#: classes/class.pim.plugin.handler.php:164
+msgid "Contact"
+msgstr "Kontakt"
+
+#: includes/include.right_bottom.php:140
+#: classes/class.pim.plugin.handler.php:165
+msgid "License"
+msgstr "Lizenz"
+
+#: includes/include.right_bottom.php:141
+#: classes/class.pim.plugin.handler.php:167
+msgid "Dependencies"
+msgstr "Abhängigkeiten"
+
+#: includes/include.right_bottom.php:142
+#: classes/class.pim.plugin.handler.php:168
+msgid "Writable"
+msgstr "Beschreibbar"
+
+#: includes/include.right_bottom.php:156
+#, php-format
+msgid "Invalid Xml document for %s. Please contact the plugin author."
+msgstr ""
+"Ungültiges xml-Dokument für %s. Bitte kontaktieren Sie den Plugin-Entwickler."
+
+#: includes/include.right_bottom.php:161
+msgid "Everything looks fine."
+msgstr "Alles sieht gut aus."
+
+#: includes/include.right_bottom.php:162
+msgid "Pluginfolder not writable!"
+msgstr "Pluginverzeichnis nicht schreibbar!"
+
+#: includes/include.right_bottom.php:188
+msgid "No entries"
+msgstr "Keine Einträge"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:193
+msgid "Add new plugin"
+msgstr "Neues Plugin installieren"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:194
+msgid "Please choose a plugin package"
+msgstr "Plugin Paket auswählen"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:195
+msgid "Upload plugin package"
+msgstr "Plugin Paket hochladen"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:196
+msgid "Remove marked Plugins"
+msgstr "Markierte Plugins löschen"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:197
+msgid "Installed Plugins"
+msgstr "Installierte Plugins"
+
+# C:\Dateien\Contenido
+#: includes/include.right_bottom.php:198
+msgid "Update marked plugins"
+msgstr "Markierte Plugins aktualisieren"
+
+#: includes/include.right_bottom.php:199
+msgid "Plugins to install"
+msgstr "Plugins zum Installieren"
+
+#: includes/include.right_bottom.php:200
+msgid "Drag & Drop plugin to list of installed plugins to install it."
+msgstr ""
+"Um ein Plugin zu installieren ziehen Sie es mit der Maus auf die Liste "
+"installierter Plugins."
+
+#: classes/class.pluginmanager.ajax.php:37
+#: classes/class.pim.plugin.handler.php:190
+msgid "Plugin is active"
+msgstr "Plugin ist aktiv"
+
+#: classes/class.pluginmanager.ajax.php:39
+#: classes/class.pim.plugin.handler.php:193
+msgid "Plugin not active"
+msgstr "Plugin ist nicht aktiv"
+
+# C:\Dateien\Contenido
+#: classes/class.pim.plugin.handler.php:166
+msgid "Installed since"
+msgstr "Installiert seit"
+
+#: classes/class.pim.plugin.handler.php:169
+msgid "Install"
+msgstr "Installieren"
+
+#: classes/class.pim.plugin.handler.php:170
+msgid "Remove"
+msgstr "Entfernen"
+
+#: classes/class.pim.plugin.handler.php:171
+#: classes/class.pim.plugin.handler.php:173
+msgid "Update"
+msgstr "Updaten"
+
+# C:\Dateien\Contenido
+#: classes/class.pim.plugin.handler.php:172
+msgid "Please choose your new file"
+msgstr "Bitte wählen Sie Ihre neue Datei"
+
+#: classes/class.pim.plugin.handler.php:174
+msgid "Execute uninstall.sql"
+msgstr "uninstall.sql ausführen"
+
+#: classes/class.pim.plugin.handler.php:208
+#, php-format
+msgid "(%s remove database tables)"
+msgstr "(%s DB-Tabellen entfernen)"
+
+# C:\Dateien\Contenido
+#: classes/class.pim.plugin.handler.php:211
+msgid "Uninstall Plugin"
+msgstr "Plugin entfernen"
+
+#: classes/setup/class.pim.setup.plugin.install.php:133
+#: classes/setup/class.pim.setup.plugin.install.php:173
+#, php-format
+msgid ""
+"Defined area %s are not found on your ConLite installation. "
+"Please contact your plugin author."
+msgstr ""
+"Die gewünschte Area %s gibt es nicht in Ihrer ConLite "
+"Installation. Bitte kontaktieren Sie den Plugin-Autor."
+
+#: classes/setup/class.pim.setup.plugin.install.php:219
+msgid ""
+"There seem to be an empty main navigation entry in plugin.xml. Please "
+"contact your plugin author."
+msgstr ""
+"Es gibt anscheinend einen leeren Eintrag zur Main Navigation in der plugin."
+"xml. Bitte kontaktieren Sie den Plugin-Autor."
+
+#: classes/setup/class.pim.setup.plugin.install.php:255
+msgid ""
+"There seem to be an empty sub navigation entry in plugin.xml. Please contact "
+"your plugin author."
+msgstr ""
+"Es gibt anscheinend einen leeren Eintrag zur Sub Navigation in der plugin."
+"xml. Bitte kontaktieren Sie den Plugin-Autor."
+
+#: classes/setup/class.pim.setup.plugin.install.php:300
+msgid "You can install this plugin only for one time."
+msgstr "Sie können dieses Plugin nur ein Mal installieren."
+
+#: classes/setup/class.pim.setup.plugin.install.php:349
+#, php-format
+msgid ""
+"Defined area %s not found on your ConLite installation. "
+"Please contact your plugin author."
+msgstr ""
+"Die gewünschte Area %s gibt es nicht in Ihrer ConLite "
+"Installation. Bitte kontaktieren Sie den Plugin-Autor."
+
+#: classes/setup/class.pim.setup.plugin.install.php:359
+#, php-format
+msgid ""
+"Defined nav main %s not found on your ConLite installation. "
+"Please contact your plugin author."
+msgstr ""
+"Die gewünschte Nav Main %s gibt es nicht in Ihrer ConLite "
+"Installation. Bitte kontaktieren Sie den Plugin-Autor."
diff --git a/conlite/plugins/pluginmanager/locale/pluginmanager.pot b/conlite/plugins/pluginmanager/locale/pluginmanager.pot
new file mode 100644
index 0000000..57f6780
--- /dev/null
+++ b/conlite/plugins/pluginmanager/locale/pluginmanager.pot
@@ -0,0 +1,215 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR , YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2017-08-11 14:07+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: includes/include.right_bottom.php:37
+msgid "Permission denied!"
+msgstr ""
+
+#: includes/include.right_bottom.php:44
+msgid "Currently the plugin system is disabled via configuration"
+msgstr ""
+
+#: includes/include.right_bottom.php:59
+msgid "Plugin uninstalled!"
+msgstr ""
+
+#: includes/include.right_bottom.php:61
+msgid "Cannot uninstall Plugin!"
+msgstr ""
+
+#: includes/include.right_bottom.php:64
+msgid "Cannot uninstall Plugin! Plugin not found in Db."
+msgstr ""
+
+#: includes/include.right_bottom.php:68
+msgid "Feature not implemented right now!"
+msgstr ""
+
+#: includes/include.right_bottom.php:131
+msgid "This plugin has no description."
+msgstr ""
+
+#: includes/include.right_bottom.php:132
+msgid "This plugin has no dependencies."
+msgstr ""
+
+#: includes/include.right_bottom.php:133
+msgid "License not set."
+msgstr ""
+
+#: includes/include.right_bottom.php:137
+#: classes/class.pim.plugin.handler.php:162
+msgid "Foldername"
+msgstr ""
+
+#: includes/include.right_bottom.php:138
+#: classes/class.pim.plugin.handler.php:163
+msgid "Author"
+msgstr ""
+
+#: includes/include.right_bottom.php:139
+#: classes/class.pim.plugin.handler.php:164
+msgid "Contact"
+msgstr ""
+
+#: includes/include.right_bottom.php:140
+#: classes/class.pim.plugin.handler.php:165
+msgid "License"
+msgstr ""
+
+#: includes/include.right_bottom.php:141
+#: classes/class.pim.plugin.handler.php:167
+msgid "Dependencies"
+msgstr ""
+
+#: includes/include.right_bottom.php:142
+#: classes/class.pim.plugin.handler.php:168
+msgid "Writable"
+msgstr ""
+
+#: includes/include.right_bottom.php:156
+#, php-format
+msgid "Invalid Xml document for %s. Please contact the plugin author."
+msgstr ""
+
+#: includes/include.right_bottom.php:161
+msgid "Everything looks fine."
+msgstr ""
+
+#: includes/include.right_bottom.php:162
+msgid "Pluginfolder not writable!"
+msgstr ""
+
+#: includes/include.right_bottom.php:188
+msgid "No entries"
+msgstr ""
+
+#: includes/include.right_bottom.php:193
+msgid "Add new plugin"
+msgstr ""
+
+#: includes/include.right_bottom.php:194
+msgid "Please choose a plugin package"
+msgstr ""
+
+#: includes/include.right_bottom.php:195
+msgid "Upload plugin package"
+msgstr ""
+
+#: includes/include.right_bottom.php:196
+msgid "Remove marked Plugins"
+msgstr ""
+
+#: includes/include.right_bottom.php:197
+msgid "Installed Plugins"
+msgstr ""
+
+#: includes/include.right_bottom.php:198
+msgid "Update marked plugins"
+msgstr ""
+
+#: includes/include.right_bottom.php:199
+msgid "Plugins to install"
+msgstr ""
+
+#: includes/include.right_bottom.php:200
+msgid "Drag & Drop plugin to list of installed plugins to install it."
+msgstr ""
+
+#: classes/class.pluginmanager.ajax.php:37
+#: classes/class.pim.plugin.handler.php:190
+msgid "Plugin is active"
+msgstr ""
+
+#: classes/class.pluginmanager.ajax.php:39
+#: classes/class.pim.plugin.handler.php:193
+msgid "Plugin not active"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:166
+msgid "Installed since"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:169
+msgid "Install"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:170
+msgid "Remove"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:171
+#: classes/class.pim.plugin.handler.php:173
+msgid "Update"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:172
+msgid "Please choose your new file"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:174
+msgid "Execute uninstall.sql"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:208
+#, php-format
+msgid "(%s remove database tables)"
+msgstr ""
+
+#: classes/class.pim.plugin.handler.php:211
+msgid "Uninstall Plugin"
+msgstr ""
+
+#: classes/setup/class.pim.setup.plugin.install.php:133
+#: classes/setup/class.pim.setup.plugin.install.php:173
+#, php-format
+msgid ""
+"Defined area %s are not found on your ConLite installation. "
+"Please contact your plugin author."
+msgstr ""
+
+#: classes/setup/class.pim.setup.plugin.install.php:219
+msgid ""
+"There seem to be an empty main navigation entry in plugin.xml. Please "
+"contact your plugin author."
+msgstr ""
+
+#: classes/setup/class.pim.setup.plugin.install.php:255
+msgid ""
+"There seem to be an empty sub navigation entry in plugin.xml. Please contact "
+"your plugin author."
+msgstr ""
+
+#: classes/setup/class.pim.setup.plugin.install.php:300
+msgid "You can install this plugin only for one time."
+msgstr ""
+
+#: classes/setup/class.pim.setup.plugin.install.php:349
+#, php-format
+msgid ""
+"Defined area %s not found on your ConLite installation. "
+"Please contact your plugin author."
+msgstr ""
+
+#: classes/setup/class.pim.setup.plugin.install.php:359
+#, php-format
+msgid ""
+"Defined nav main %s not found on your ConLite installation. "
+"Please contact your plugin author."
+msgstr ""
diff --git a/conlite/plugins/pluginmanager/locale/potfiles.txt b/conlite/plugins/pluginmanager/locale/potfiles.txt
new file mode 100644
index 0000000..0333d6a
--- /dev/null
+++ b/conlite/plugins/pluginmanager/locale/potfiles.txt
@@ -0,0 +1,26 @@
+./includes/functions/simplexml_dump.php
+./includes/functions/simplexml_tree.php
+./includes/include.right_bottom.php
+./includes/config.autoloader.php
+./includes/config.plugin.php
+./templates/pi_manager_plugins.html
+./templates/pi_manager_install.html
+./templates/pi_manager_extracted_plugins.html
+./templates/pi_manager_overview.html
+./templates/pi_manager_installed_plugins.html
+./classes/exeptions/class.pim.exeption.php
+./classes/class.pluginmanager.ajax.php
+./classes/class.pim.plugin.handler.php
+./classes/class.pim.view.php
+./classes/class.pim.plugin.relation.php
+./classes/class.pim.ajax.php
+./classes/class.pim.plugin.dummy.php
+./classes/plugin/interface.plugins.php
+./classes/plugin/class.plugin.handler.abstract.php
+./classes/Util/Zip/Contenido_ArchiveExtractor.class.php
+./classes/Util/Zip/class.pim.plugin.archive.extractor.php
+./classes/Util/class.pim.sql.parser.php
+./classes/class.pim.plugin.php
+./classes/setup/class.pim.setup.plugin.uninstall.php
+./classes/setup/class.pim.setup.plugin.install.php
+./classes/setup/class.pim.setup.base.php
diff --git a/conlite/plugins/pluginmanager/scripts/jquery.plainmodal.js b/conlite/plugins/pluginmanager/scripts/jquery.plainmodal.js
new file mode 100644
index 0000000..8a3f715
--- /dev/null
+++ b/conlite/plugins/pluginmanager/scripts/jquery.plainmodal.js
@@ -0,0 +1,176 @@
+/*
+ * jQuery.plainModal
+ * https://github.com/anseki/jquery-plainmodal
+ *
+ * Copyright (c) 2014 anseki
+ * Licensed under the MIT license.
+ */
+
+;(function($, undefined) {
+'use strict';
+
+var APP_NAME = 'plainModal',
+    APP_PREFIX = APP_NAME.toLowerCase(),
+    EVENT_TYPE_OPEN = APP_PREFIX + 'open',
+    EVENT_TYPE_CLOSE = APP_PREFIX + 'close',
+
+    jqOpened = null, // jqOpened === null : Not opened / jqOpened === 0 : Fading now
+    jqWin, jqBody, jqOverlay, jqActive, jq1st,
+    orgOverflow, orgMarginR, orgMarginB,
+    winLeft, winTop;
+
+function init(jq, options) {
+  // The options object is shared by all elements in jq.
+  // Therefore, don't change properties later. (Replace options object for new object.)
+  var opt = $.extend(true, {
+        duration:       200,
+        effect:         {open: $.fn.fadeIn, close: $.fn.fadeOut},
+        overlay:        {opacity: 0.6, zIndex: 9000},
+        closeClass:     APP_PREFIX + '-close'
+        // Optional: offset, open, close
+      }, options);
+  opt.overlay.fillColor = opt.overlay.fillColor || opt.overlay.color /* alias */ || '#888';
+  opt.zIndex = opt.zIndex || opt.overlay.zIndex + 1;
+
+  if (!jqWin) { // page init
+    jqWin = $(window);
+    jqOverlay = $('
').css({ + position: 'fixed', + left: 0, + top: 0, + width: '100%', + height: '150%', // for Address Bar of Firefox for Android + display: 'none' + }).appendTo(jqBody = $('body')).click(modalClose) + .on('touchmove', function() { return false; }); // avoid scroll on touch devices + $(document).focusin(function(e) { + if (jqOpened && !jqOpened.has(e.target).length) { + if (jq1st) { jq1st.focus(); } + else { $(document.activeElement).blur(); } + } + }) + .keydown(function(e) { + if (jqOpened && e.keyCode === 27) { // Escape key + return modalClose(e); + } + }); + } + + return jq.each(function() { + var that = $(this), + cssProp = { + position: 'fixed', + display: 'none', + zIndex: opt.zIndex + }; + if (opt.offset) { + if (typeof opt.offset !== 'function') { + cssProp.left = opt.offset.left; + cssProp.top = opt.offset.top; + } + cssProp.marginLeft = cssProp.marginTop = ''; // for change + } else { + cssProp.left = cssProp.top = '50%'; + cssProp.marginLeft = '-' + (that.outerWidth() / 2) + 'px'; + cssProp.marginTop = '-' + (that.outerHeight() / 2) + 'px'; + } + if (opt.closeClass) { + that.find('.' + opt.closeClass).off('click', modalClose).click(modalClose); + } + if (typeof opt.open === 'function') + { that.off(EVENT_TYPE_OPEN, opt.open).on(EVENT_TYPE_OPEN, opt.open); } + if (typeof opt.close === 'function') + { that.off(EVENT_TYPE_CLOSE, opt.close).on(EVENT_TYPE_CLOSE, opt.close); } + that.css(cssProp).data(APP_NAME, opt).appendTo(jqBody) + .on('touchmove', function() { return false; }); // avoid scroll on touch devices + }); +} + +function modalOpen(jq, options) { + var jqTarget, opt, inlineStyles, calMarginR, calMarginB, offset; + if (jqOpened === null && jq.length) { + jqTarget = jq.eq(0); // only 1st + if (options || !(opt = jqTarget.data(APP_NAME))) { + opt = init(jqTarget, options).data(APP_NAME); + } + inlineStyles = jqBody.get(0).style; + + orgOverflow = inlineStyles.overflow; + calMarginR = jqBody.prop('clientWidth'); + calMarginB = jqBody.prop('clientHeight'); + jqBody.css('overflow', 'hidden'); + calMarginR -= jqBody.prop('clientWidth'); + calMarginB -= jqBody.prop('clientHeight'); + orgMarginR = inlineStyles.marginRight; + orgMarginB = inlineStyles.marginBottom; + if (calMarginR < 0) { jqBody.css('marginRight', '+=' + (-calMarginR)); } + if (calMarginB < 0) { jqBody.css('marginBottom', '+=' + (-calMarginB)); } + + jqActive = $(document.activeElement).blur(); // Save activeElement + jq1st = null; + winLeft = jqWin.scrollLeft(); + winTop = jqWin.scrollTop(); + jqWin.scroll(avoidScroll); + + if (typeof opt.offset === 'function') { + offset = opt.offset.call(jqTarget); + jqTarget.css({left: offset.left, top: offset.top}); + } + // If duration is 0, callback is called now. + opt.effect.open.call(jqTarget, opt.duration || 1, function() { + jqTarget.find('a,input,select,textarea,button,object,area,img,map').each(function() { + var that = $(this); + if (that.focus().get(0) === document.activeElement) { // Can focus + jq1st = that; + return false; + } + }); + jqOpened = jqTarget.trigger(EVENT_TYPE_OPEN); + }); + // Re-Style the overlay that is shared by all 'opt'. + jqOverlay.css({backgroundColor: opt.overlay.fillColor, zIndex: opt.overlay.zIndex}) + .fadeTo(opt.duration, opt.overlay.opacity); + jqOpened = 0; + } + return jq; +} + +function modalClose(jq) { // jq: target/event + var isEvent = jq instanceof $.Event, jqTarget, opt; + if (jqOpened) { + jqTarget = isEvent ? jqOpened : (function() { // jqOpened in jq + var index = jq.index(jqOpened); + return index > -1 ? jq.eq(index) : undefined; + })(); + if (jqTarget) { + opt = jqTarget.data(APP_NAME); + // If duration is 0, callback is called now. + opt.effect.close.call(jqTarget, opt.duration || 1, function() { + jqBody.css({overflow: orgOverflow, marginRight: orgMarginR, marginBottom: orgMarginB}); + if (jqActive && jqActive.length) { jqActive.focus(); } // Restore activeElement + jqWin.off('scroll', avoidScroll).scrollLeft(winLeft).scrollTop(winTop); + jqTarget.trigger(EVENT_TYPE_CLOSE); + jqOpened = null; + }); + jqOverlay.fadeOut(opt.duration); + jqOpened = 0; + } + } + if (isEvent) { jq.preventDefault(); return false; } + return jq; +} + +function avoidScroll(e) { + jqWin.scrollLeft(winLeft).scrollTop(winTop); + e.preventDefault(); + return false; +} + +$.fn[APP_NAME] = function(action, options) { + return ( + action === 'open' ? modalOpen(this, options) : + action === 'close' ? modalClose(this) : + init(this, action)); // options. +}; + +})(jQuery); diff --git a/conlite/plugins/pluginmanager/scripts/jquery.plainmodal.min.js b/conlite/plugins/pluginmanager/scripts/jquery.plainmodal.min.js new file mode 100644 index 0000000..0245127 --- /dev/null +++ b/conlite/plugins/pluginmanager/scripts/jquery.plainmodal.min.js @@ -0,0 +1 @@ +!function(o,e){"use strict";function t(e,t){var n=o.extend(!0,{duration:200,effect:{open:o.fn.fadeIn,close:o.fn.fadeOut},overlay:{opacity:.6,zIndex:9e3},closeClass:m+"-close"},t);return n.overlay.fillColor=n.overlay.fillColor||n.overlay.color||"#888",n.zIndex=n.zIndex||n.overlay.zIndex+1,r||(r=o(window),f=o('
').css({position:"fixed",left:0,top:0,width:"100%",height:"150%",display:"none"}).appendTo(c=o("body")).click(l).on("touchmove",function(){return!1}),o(document).focusin(function(e){C&&!C.has(e.target).length&&(s?s.focus():o(document.activeElement).blur())}).keydown(function(o){return C&&27===o.keyCode?l(o):void 0})),e.each(function(){var e=o(this),t={position:"fixed",display:"none",zIndex:n.zIndex};n.offset?("function"!=typeof n.offset&&(t.left=n.offset.left,t.top=n.offset.top),t.marginLeft=t.marginTop=""):(t.left=t.top="50%",t.marginLeft="-"+e.outerWidth()/2+"px",t.marginTop="-"+e.outerHeight()/2+"px"),n.closeClass&&e.find("."+n.closeClass).off("click",l).click(l),"function"==typeof n.open&&e.off(y,n.open).on(y,n.open),"function"==typeof n.close&&e.off(x,n.close).on(x,n.close),e.css(t).data(h,n).appendTo(c).on("touchmove",function(){return!1})})}function n(e,n){var l,m,x,I,w,z;return null===C&&e.length&&(l=e.eq(0),(n||!(m=l.data(h)))&&(m=t(l,n).data(h)),x=c.get(0).style,u=x.overflow,I=c.prop("clientWidth"),w=c.prop("clientHeight"),c.css("overflow","hidden"),I-=c.prop("clientWidth"),w-=c.prop("clientHeight"),d=x.marginRight,p=x.marginBottom,0>I&&c.css("marginRight","+="+-I),0>w&&c.css("marginBottom","+="+-w),a=o(document.activeElement).blur(),s=null,v=r.scrollLeft(),g=r.scrollTop(),r.scroll(i),"function"==typeof m.offset&&(z=m.offset.call(l),l.css({left:z.left,top:z.top})),m.effect.open.call(l,m.duration||1,function(){l.find("a,input,select,textarea,button,object,area,img,map").each(function(){var e=o(this);return e.focus().get(0)===document.activeElement?(s=e,!1):void 0}),C=l.trigger(y)}),f.css({backgroundColor:m.overlay.fillColor,zIndex:m.overlay.zIndex}).fadeTo(m.duration,m.overlay.opacity),C=0),e}function l(t){var n,l,s=t instanceof o.Event;return C&&(n=s?C:function(){var o=t.index(C);return o>-1?t.eq(o):e}(),n&&(l=n.data(h),l.effect.close.call(n,l.duration||1,function(){c.css({overflow:u,marginRight:d,marginBottom:p}),a&&a.length&&a.focus(),r.off("scroll",i).scrollLeft(v).scrollTop(g),n.trigger(x),C=null}),f.fadeOut(l.duration),C=0)),s?(t.preventDefault(),!1):t}function i(o){return r.scrollLeft(v).scrollTop(g),o.preventDefault(),!1}var r,c,f,a,s,u,d,p,v,g,h="plainModal",m=h.toLowerCase(),y=m+"open",x=m+"close",C=null;o.fn[h]=function(o,e){return"open"===o?n(this,e):"close"===o?l(this):t(this,o)}}(jQuery); \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/scripts/jquery.plainoverlay.js b/conlite/plugins/pluginmanager/scripts/jquery.plainoverlay.js new file mode 100644 index 0000000..48714bc --- /dev/null +++ b/conlite/plugins/pluginmanager/scripts/jquery.plainoverlay.js @@ -0,0 +1,426 @@ +/* + * jQuery.plainOverlay + * https://github.com/anseki/jquery-plainoverlay + * + * Copyright (c) 2015 anseki + * Licensed under the MIT license. + */ + +;(function($, undefined) { +'use strict'; + +var APP_NAME = 'plainOverlay', + APP_PREFIX = APP_NAME.toLowerCase(), + EVENT_TYPE_SHOW = APP_PREFIX + 'show', + EVENT_TYPE_HIDE = APP_PREFIX + 'hide', + + // builtin progress element + newProgress = (function() { + function experimental(props, supports, prefix, sep) { // similar to Compass + sep = sep === undefined ? ';' : sep; + return $.map(props, function(prop) { + return $.map(supports, function(support) { + return (prefix || '') + support + prop; + }).join(sep); + }).join(sep); + } + + var isLegacy, domId = 'jQuery-' + APP_NAME, + supports = ['-webkit-','-moz-','-ms-','-o-',''], prefix = domId + '-progress', + cssText = '.'+prefix+'{'+experimental(['box-sizing:border-box'],['-webkit-','-moz-',''])+';width:100%;height:100%;border-top:3px solid #17f29b;'+experimental(['border-radius:50%'],supports)+';-webkit-tap-highlight-color:rgba(0,0,0,0);transform:translateZ(0);box-shadow:0 0 1px rgba(0,0,0,0);'+experimental(['animation-name:'+domId+'-spin','animation-duration:1s','animation-timing-function:linear','animation-iteration-count:infinite'],supports)+'}'+experimental(['keyframes '+domId+'-spin{from{'+experimental(['transform:rotate(0deg)'],supports)+'}to{'+experimental(['transform:rotate(360deg)'],supports)+'}}'],supports,'@','')+'.'+prefix+'-legacy{width:100%;height:50%;padding-top:25%;text-align:center;white-space:nowrap;*zoom:1}.'+prefix+'-legacy:after,.'+prefix+'-legacy:before{content:" ";display:table}.'+prefix+'-legacy:after{clear:both}.'+prefix+'-legacy div{width:18%;height:100%;margin:0 1%;background-color:#17f29b;float:left;visibility:hidden}.'+prefix+'-1 div.'+prefix+'-1,.'+prefix+'-2 div.'+prefix+'-1,.'+prefix+'-2 div.'+prefix+'-2,.'+prefix+'-3 div.'+prefix+'-1,.'+prefix+'-3 div.'+prefix+'-2,.'+prefix+'-3 div.'+prefix+'-3{visibility:visible}', + + adjustProgress = function() { + var progressWH = Math.min(300, // max w/h + (this.isBody ? + Math.min(this.jqWin.width(), this.jqWin.height()) : + Math.min(this.jqTarget.innerWidth(), this.jqTarget.innerHeight())) * 0.9); + this.jqProgress.width(progressWH).height(progressWH); + if (!this.showProgress) { // CSS Animations + this.jqProgress.children('.' + prefix).css('borderTopWidth', + Math.max(3, progressWH / 30)); // min width + } + }, + showProgressLegacy = function(start) { + var that = this; + if (that.timer) { clearTimeout(that.timer); } + if (that.progressCnt) { + that.jqProgress.removeClass(prefix + '-' + that.progressCnt); + } + if (that.isShown) { + that.progressCnt = !start && that.progressCnt < 3 ? that.progressCnt + 1 : 0; + if (that.progressCnt) { + that.jqProgress.addClass(prefix + '-' + that.progressCnt); + } + that.timer = setTimeout(function() { that.showProgress(); }, 500); + } + }; + + return function(overlay) { + var jqProgress, sheet; + + // Graceful Degradation + if (typeof isLegacy !== 'boolean') { + isLegacy = (function() { // similar to Modernizr + function contains(str, substr) { return !!~('' + str).indexOf(substr); } + var res, feature, + modElem = document.createElement('modernizr'), + mStyle = modElem.style, + omPrefixes = 'Webkit Moz O ms', + cssomPrefixes = omPrefixes.split(' '), + tests = {}, + _hasOwnProperty = ({}).hasOwnProperty, + hasOwnProp = _hasOwnProperty !== undefined && + _hasOwnProperty.call !== undefined ? + function (object, property) { + return _hasOwnProperty.call(object, property); + } : + function (object, property) { + return (property in object) && + object.constructor.prototype[property] === undefined; + }; + + function testProps(props) { + var i; + for (i in props) { + if (!contains(props[i], '-') && mStyle[props[i]] !== undefined) { return true; } + } + return false; + } + function testPropsAll(prop) { + var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), + props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); + return testProps(props); + } + + tests.borderradius = function() { + return testPropsAll('borderRadius'); + }; + tests.cssanimations = function() { + return testPropsAll('animationName'); + }; + tests.csstransforms = function() { + return !!testPropsAll('transform'); + }; + + res = false; + for (feature in tests) { + if (hasOwnProp(tests, feature) && !tests[feature]()) { + res = true; + break; + } + } + mStyle.cssText = ''; + modElem = null; + return res; + })(); + } + + if (!overlay.elmDoc.getElementById(domId)) { // Add style rules + if (overlay.elmDoc.createStyleSheet) { // IE + sheet = overlay.elmDoc.createStyleSheet(); + sheet.owningElement.id = domId; + sheet.cssText = cssText; + } else { + sheet = (overlay.elmDoc.getElementsByTagName('head')[0] || overlay.elmDoc.documentElement) + .appendChild(overlay.elmDoc.createElement('style')); + sheet.type = 'text/css'; + sheet.id = domId; + sheet.textContent = cssText; + } + } + + if (isLegacy) { + jqProgress = $('
' + + '
'); + overlay.showProgress = showProgressLegacy; + } else { + jqProgress = $('
'); + } + overlay.adjustProgress = adjustProgress; + return jqProgress; + }; + })(); + +function Overlay(jqTarget, options, curObject) { + var that = this, elmTarget = jqTarget.get(0); + that.duration = options.duration; + that.opacity = options.opacity; + that.isShown = false; + + that.jqTargetOrg = jqTarget; + // that.jqWin = that.jqTarget.ownerDocument.defaultView; // Not supported by IE + if ($.isWindow(elmTarget) || elmTarget.nodeType === 9) { // window or document -> body + that.jqTarget = $('body'); + } else if (elmTarget.nodeName.toLowerCase() === 'iframe' || + elmTarget.nodeName.toLowerCase() === 'frame') { // iframe or frame -> body of it + // contentDocument not supported by IE + that.jqWin = $(elmTarget.contentWindow); + that.elmDoc = elmTarget.contentWindow.document; + that.jqTarget = $('body', that.elmDoc); + that.isFrame = true; + } else { + that.jqTarget = jqTarget; + } + that.jqWin = that.jqWin || $(window); + that.elmDoc = that.elmDoc || document; + that.isBody = that.jqTarget.get(0).nodeName.toLowerCase() === 'body'; + + if (curObject) { + // Remove jqProgress that exists always, because it may be replaced. + if (curObject.jqProgress) { + if (curObject.timer) { clearTimeout(curObject.timer); } + curObject.jqProgress.remove(); delete curObject.jqProgress; + } + curObject.reset(true); // Restore styles + curObject.jqOverlay.stop(); + } + + that.jqOverlay = (curObject && curObject.jqOverlay || + $('
').css({ + position: that.isBody ? 'fixed' : 'absolute', + left: 0, + top: 0, + display: 'none', + cursor: 'wait' + }).appendTo(that.jqTarget) + .on('touchmove', function() { return false; }) // avoid scroll on touch devices + ).css({backgroundColor: options.fillColor, zIndex: options.zIndex}); + + if (that.jqProgress = options.progress === false ? undefined : + (typeof options.progress === 'function' ? + options.progress.call(that.jqTarget, options) : newProgress(that))) { + that.jqProgress.css({ + position: that.isBody ? 'fixed' : 'absolute', + display: 'none', + zIndex: options.zIndex + 1, + cursor: 'wait' + }).appendTo(that.jqTarget) + .on('touchmove', function() { return false; }); // avoid scroll on touch devices; + } + + // Not shared methods for calling per object in event of one element. + that.callAdjust = (function(that) { + return that.adjustProgress ? function() { + that.adjustProgress(); + that.adjust(); + } : function() { that.adjust(); }; + })(that); + that.avoidFocus = (function(that) { + return function(e) { + $(that.elmDoc.activeElement).blur(); + e.preventDefault(); + return false; + }; + })(that); + that.avoidScroll = (function(that) { + return function(e) { + (function(jqView) { + jqView.scrollLeft(that.scrLeft).scrollTop(that.scrTop); + })(that.isBody ? that.jqWin : that.jqTarget); + e.preventDefault(); + return false; + }; + })(that); + + if (curObject) { + if (curObject.timer) { clearTimeout(curObject.timer); } + curObject = undefined; // Erase + } +} + +Overlay.prototype.show = function() { + var that = this, inlineStyles, position, calMarginR, calMarginB, jqActive; + that.reset(true); // Restore styles + inlineStyles = that.jqTarget.get(0).style; + + that.orgPosition = inlineStyles.position; + position = that.jqTarget.css('position'); + if (position !== 'relative' && position !== 'absolute' && position !== 'fixed') { + that.jqTarget.css('position', 'relative'); + } + + that.orgOverflow = inlineStyles.overflow; + calMarginR = that.jqTarget.prop('clientWidth'); + calMarginB = that.jqTarget.prop('clientHeight'); + that.jqTarget.css('overflow', 'hidden'); + calMarginR -= that.jqTarget.prop('clientWidth'); + calMarginB -= that.jqTarget.prop('clientHeight'); + that.addMarginR = that.addMarginB = 0; + if (calMarginR < 0) { that.addMarginR = -calMarginR; } + if (calMarginB < 0) { that.addMarginB = -calMarginB; } + if (that.isBody) { + if (that.addMarginR) { + that.orgMarginR = inlineStyles.marginRight; + that.jqTarget.css('marginRight', '+=' + that.addMarginR); + } + if (that.addMarginB) { + that.orgMarginB = inlineStyles.marginBottom; + that.jqTarget.css('marginBottom', '+=' + that.addMarginB); + } + } else { // change these in adjust() + if (that.addMarginR) { + that.orgMarginR = inlineStyles.paddingRight; + that.orgWidth = inlineStyles.width; + } + if (that.addMarginB) { + that.orgMarginB = inlineStyles.paddingBottom; + that.orgHeight = inlineStyles.height; + } + } + + that.jqActive = undefined; + jqActive = $(that.elmDoc.activeElement); + if (that.isBody && !that.isFrame) { that.jqActive = jqActive.blur(); } // Save activeElement + else if (that.jqTarget.has(jqActive.get(0)).length) { jqActive.blur(); } + that.jqTarget.focusin(that.avoidFocus); + (function(jqView) { + that.scrLeft = jqView.scrollLeft(); + that.scrTop = jqView.scrollTop(); + jqView.scroll(that.avoidScroll); + })(that.isBody ? that.jqWin : that.jqTarget); + that.jqWin.resize(that.callAdjust); + that.callAdjust(); + that.isShown = true; + + that.jqOverlay.stop().fadeTo(that.duration, that.opacity, + function() { that.jqTargetOrg.trigger(EVENT_TYPE_SHOW); }); + if (that.jqProgress) { + if (that.showProgress) { that.showProgress(true); } + that.jqProgress.fadeIn(that.duration); + } +}; + +Overlay.prototype.hide = function() { + var that = this; + if (!that.isShown) { return; } + that.jqOverlay.stop().fadeOut(that.duration, + function() { that.reset(); that.jqTargetOrg.trigger(EVENT_TYPE_HIDE); }); + if (that.jqProgress) { that.jqProgress.fadeOut(that.duration); } +}; + +Overlay.prototype.adjust = function() { + var calW, calH; + if (this.isBody) { + // base of overlay size and progress position is window. + calW = this.jqWin.width(); + calH = this.jqWin.height(); + this.jqOverlay.width(calW).height(calH); + if (this.jqProgress) { + this.jqProgress.css({ + left: (calW - this.jqProgress.outerWidth()) / 2, + top: (calH - this.jqProgress.outerHeight()) / 2 + }); + } + } else { + if (this.addMarginR) { + calW = this.jqTarget.css({paddingRight: this.orgMarginR, width: this.orgWidth}) + .width(); // original size + this.jqTarget.css('paddingRight', '+=' + this.addMarginR).width(calW - this.addMarginR); + } + if (this.addMarginB) { + calH = this.jqTarget.css({paddingBottom: this.orgMarginB, height: this.orgHeight}) + .height(); // original size + this.jqTarget.css('paddingBottom', '+=' + this.addMarginB).height(calH - this.addMarginB); + } + + // base of overlay size is element size that includes hidden area. + calW = Math.max(this.jqTarget.prop('scrollWidth'), this.jqTarget.innerWidth()); // for IE bug + calH = Math.max(this.jqTarget.prop('scrollHeight'), this.jqTarget.innerHeight()); + this.jqOverlay.width(calW).height(calH); + if (this.jqProgress) { + // base of progress position is element size that doesn't include hidden area. + calW = this.jqTarget.innerWidth(); + calH = this.jqTarget.innerHeight(); + this.jqProgress.css({ + left: (calW - this.jqProgress.outerWidth()) / 2 + this.scrLeft, + top: (calH - this.jqProgress.outerHeight()) / 2 + this.scrTop + }); + } + } +}; + +Overlay.prototype.reset = function(forceHide) { + // default: display of jqOverlay and jqProgress is kept + var that = this; + if (forceHide) { + that.jqOverlay.css('display', 'none'); + if (that.jqProgress) { that.jqProgress.css('display', 'none'); } + } + if (!that.isShown) { return; } + that.jqTarget.css({position: that.orgPosition, overflow: that.orgOverflow}); + if (that.isBody) { + if (that.addMarginR) { that.jqTarget.css('marginRight', that.orgMarginR); } + if (that.addMarginB) { that.jqTarget.css('marginBottom', that.orgMarginB); } + } else { + if (that.addMarginR) { + that.jqTarget.css({paddingRight: that.orgMarginR, width: that.orgWidth}); + } + if (that.addMarginB) { + that.jqTarget.css({paddingBottom: that.orgMarginB, height: that.orgHeight}); + } + } + that.jqTarget.off('focusin', that.avoidFocus); + if (that.jqActive && that.jqActive.length) { that.jqActive.focus(); } // Restore activeElement + (function(jqView) { + jqView.off('scroll', that.avoidScroll).scrollLeft(that.scrLeft).scrollTop(that.scrTop); + })(that.isBody ? that.jqWin : that.jqTarget); + that.jqWin.off('resize', that.callAdjust); + that.isShown = false; +}; + +function init(jq, options) { + var opt = $.extend({ + duration: 200, + opacity: 0.6, + zIndex: 9000 + // Optional: progress, show, hide + }, options); + opt.fillColor = opt.fillColor || opt.color /* alias */ || '#888'; + return jq.each(function() { + var that = $(this); + that.data(APP_NAME, new Overlay(that, opt, that.data(APP_NAME))); + if (typeof opt.show === 'function') + { that.off(EVENT_TYPE_SHOW, opt.show).on(EVENT_TYPE_SHOW, opt.show); } + if (typeof opt.hide === 'function') + { that.off(EVENT_TYPE_HIDE, opt.hide).on(EVENT_TYPE_HIDE, opt.hide); } + }); +} + +function overlayShow(jq, options) { + return jq.each(function() { + var that = $(this), overlay; + if (options || !(overlay = that.data(APP_NAME))) { + overlay = init(that, options).data(APP_NAME); + } + overlay.show(); + }); +} + +function overlayHide(jq) { + return jq.each(function() { + var overlay = $(this).data(APP_NAME); + if (overlay) { overlay.hide(); } + }); +} + +function overlaySetOption(jq, name, newValue) { + var jqTarget = jq.length ? jq.eq(0) : undefined, // only 1st + overlay; + if (!jqTarget) { return; } + overlay = jqTarget.data(APP_NAME) || init(jqTarget).data(APP_NAME); + if (!overlay.hasOwnProperty(name)) { return; } +/* jshint eqnull:true */ + if (newValue != null) { overlay[name] = newValue; } +/* jshint eqnull:false */ + return overlay[name]; +} + +$.fn[APP_NAME] = function(action, arg1, arg2) { + return ( + action === 'show' ? overlayShow(this, arg1) : + action === 'hide' ? overlayHide(this) : + action === 'option' ? overlaySetOption(this, arg1, arg2) : + init(this, action)); // action = options. +}; + +})(jQuery); diff --git a/conlite/plugins/pluginmanager/scripts/jquery.plainoverlay.min.js b/conlite/plugins/pluginmanager/scripts/jquery.plainoverlay.min.js new file mode 100644 index 0000000..8b54482 --- /dev/null +++ b/conlite/plugins/pluginmanager/scripts/jquery.plainoverlay.min.js @@ -0,0 +1 @@ +!function(t,r){"use strict";function i(i,e,o){var s=this,n=i.get(0);s.duration=e.duration,s.opacity=e.opacity,s.isShown=!1,s.jqTargetOrg=i,t.isWindow(n)||9===n.nodeType?s.jqTarget=t("body"):"iframe"===n.nodeName.toLowerCase()||"frame"===n.nodeName.toLowerCase()?(s.jqWin=t(n.contentWindow),s.elmDoc=n.contentWindow.document,s.jqTarget=t("body",s.elmDoc),s.isFrame=!0):s.jqTarget=i,s.jqWin=s.jqWin||t(window),s.elmDoc=s.elmDoc||document,s.isBody="body"===s.jqTarget.get(0).nodeName.toLowerCase(),o&&(o.jqProgress&&(o.timer&&clearTimeout(o.timer),o.jqProgress.remove(),delete o.jqProgress),o.reset(!0),o.jqOverlay.stop()),s.jqOverlay=(o&&o.jqOverlay||t('
').css({position:s.isBody?"fixed":"absolute",left:0,top:0,display:"none",cursor:"wait"}).appendTo(s.jqTarget).on("touchmove",function(){return!1})).css({backgroundColor:e.fillColor,zIndex:e.zIndex}),(s.jqProgress=e.progress===!1?r:"function"==typeof e.progress?e.progress.call(s.jqTarget,e):c(s))&&s.jqProgress.css({position:s.isBody?"fixed":"absolute",display:"none",zIndex:e.zIndex+1,cursor:"wait"}).appendTo(s.jqTarget).on("touchmove",function(){return!1}),s.callAdjust=function(t){return t.adjustProgress?function(){t.adjustProgress(),t.adjust()}:function(){t.adjust()}}(s),s.avoidFocus=function(r){return function(i){return t(r.elmDoc.activeElement).blur(),i.preventDefault(),!1}}(s),s.avoidScroll=function(t){return function(r){return function(r){r.scrollLeft(t.scrLeft).scrollTop(t.scrTop)}(t.isBody?t.jqWin:t.jqTarget),r.preventDefault(),!1}}(s),o&&(o.timer&&clearTimeout(o.timer),o=r)}function e(r,e){var o=t.extend({duration:200,opacity:.6,zIndex:9e3},e);return o.fillColor=o.fillColor||o.color||"#888",r.each(function(){var r=t(this);r.data(n,new i(r,o,r.data(n))),"function"==typeof o.show&&r.off(d,o.show).on(d,o.show),"function"==typeof o.hide&&r.off(g,o.hide).on(g,o.hide)})}function o(r,i){return r.each(function(){var r,o=t(this);(i||!(r=o.data(n)))&&(r=e(o,i).data(n)),r.show()})}function s(r){return r.each(function(){var r=t(this).data(n);r&&r.hide()})}var n="plainOverlay",a=n.toLowerCase(),d=a+"show",g=a+"hide",c=function(){function i(i,e,o,s){return s=s===r?";":s,t.map(i,function(r){return t.map(e,function(t){return(o||"")+t+r}).join(s)}).join(s)}var e,o="jQuery-"+n,s=["-webkit-","-moz-","-ms-","-o-",""],a=o+"-progress",d="."+a+"{"+i(["box-sizing:border-box"],["-webkit-","-moz-",""])+";width:100%;height:100%;border-top:3px solid #17f29b;"+i(["border-radius:50%"],s)+";-webkit-tap-highlight-color:rgba(0,0,0,0);transform:translateZ(0);box-shadow:0 0 1px rgba(0,0,0,0);"+i(["animation-name:"+o+"-spin","animation-duration:1s","animation-timing-function:linear","animation-iteration-count:infinite"],s)+"}"+i(["keyframes "+o+"-spin{from{"+i(["transform:rotate(0deg)"],s)+"}to{"+i(["transform:rotate(360deg)"],s)+"}}"],s,"@","")+"."+a+"-legacy{width:100%;height:50%;padding-top:25%;text-align:center;white-space:nowrap;*zoom:1}."+a+"-legacy:after,."+a+'-legacy:before{content:" ";display:table}.'+a+"-legacy:after{clear:both}."+a+"-legacy div{width:18%;height:100%;margin:0 1%;background-color:#17f29b;float:left;visibility:hidden}."+a+"-1 div."+a+"-1,."+a+"-2 div."+a+"-1,."+a+"-2 div."+a+"-2,."+a+"-3 div."+a+"-1,."+a+"-3 div."+a+"-2,."+a+"-3 div."+a+"-3{visibility:visible}",g=function(){var t=Math.min(300,.9*(this.isBody?Math.min(this.jqWin.width(),this.jqWin.height()):Math.min(this.jqTarget.innerWidth(),this.jqTarget.innerHeight())));this.jqProgress.width(t).height(t),this.showProgress||this.jqProgress.children("."+a).css("borderTopWidth",Math.max(3,t/30))},c=function(t){var r=this;r.timer&&clearTimeout(r.timer),r.progressCnt&&r.jqProgress.removeClass(a+"-"+r.progressCnt),r.isShown&&(r.progressCnt=!t&&r.progressCnt<3?r.progressCnt+1:0,r.progressCnt&&r.jqProgress.addClass(a+"-"+r.progressCnt),r.timer=setTimeout(function(){r.showProgress()},500))};return function(i){var s,n;return"boolean"!=typeof e&&(e=function(){function t(t,r){return!!~(""+t).indexOf(r)}function i(i){var e;for(e in i)if(!t(i[e],"-")&&a[i[e]]!==r)return!0;return!1}function e(t){var r=t.charAt(0).toUpperCase()+t.slice(1),e=(t+" "+g.join(r+" ")+r).split(" ");return i(e)}var o,s,n=document.createElement("modernizr"),a=n.style,d="Webkit Moz O ms",g=d.split(" "),c={},h={}.hasOwnProperty,l=h!==r&&h.call!==r?function(t,r){return h.call(t,r)}:function(t,i){return i in t&&t.constructor.prototype[i]===r};c.borderradius=function(){return e("borderRadius")},c.cssanimations=function(){return e("animationName")},c.csstransforms=function(){return!!e("transform")},o=!1;for(s in c)if(l(c,s)&&!c[s]()){o=!0;break}return a.cssText="",n=null,o}()),i.elmDoc.getElementById(o)||(i.elmDoc.createStyleSheet?(n=i.elmDoc.createStyleSheet(),n.owningElement.id=o,n.cssText=d):(n=(i.elmDoc.getElementsByTagName("head")[0]||i.elmDoc.documentElement).appendChild(i.elmDoc.createElement("style")),n.type="text/css",n.id=o,n.textContent=d)),e?(s=t('
'),i.showProgress=c):s=t('
'),i.adjustProgress=g,s}}();i.prototype.show=function(){var i,e,o,s,n,a=this;a.reset(!0),i=a.jqTarget.get(0).style,a.orgPosition=i.position,e=a.jqTarget.css("position"),"relative"!==e&&"absolute"!==e&&"fixed"!==e&&a.jqTarget.css("position","relative"),a.orgOverflow=i.overflow,o=a.jqTarget.prop("clientWidth"),s=a.jqTarget.prop("clientHeight"),a.jqTarget.css("overflow","hidden"),o-=a.jqTarget.prop("clientWidth"),s-=a.jqTarget.prop("clientHeight"),a.addMarginR=a.addMarginB=0,0>o&&(a.addMarginR=-o),0>s&&(a.addMarginB=-s),a.isBody?(a.addMarginR&&(a.orgMarginR=i.marginRight,a.jqTarget.css("marginRight","+="+a.addMarginR)),a.addMarginB&&(a.orgMarginB=i.marginBottom,a.jqTarget.css("marginBottom","+="+a.addMarginB))):(a.addMarginR&&(a.orgMarginR=i.paddingRight,a.orgWidth=i.width),a.addMarginB&&(a.orgMarginB=i.paddingBottom,a.orgHeight=i.height)),a.jqActive=r,n=t(a.elmDoc.activeElement),a.isBody&&!a.isFrame?a.jqActive=n.blur():a.jqTarget.has(n.get(0)).length&&n.blur(),a.jqTarget.focusin(a.avoidFocus),function(t){a.scrLeft=t.scrollLeft(),a.scrTop=t.scrollTop(),t.scroll(a.avoidScroll)}(a.isBody?a.jqWin:a.jqTarget),a.jqWin.resize(a.callAdjust),a.callAdjust(),a.isShown=!0,a.jqOverlay.stop().fadeTo(a.duration,a.opacity,function(){a.jqTargetOrg.trigger(d)}),a.jqProgress&&(a.showProgress&&a.showProgress(!0),a.jqProgress.fadeIn(a.duration))},i.prototype.hide=function(){var t=this;t.isShown&&(t.jqOverlay.stop().fadeOut(t.duration,function(){t.reset(),t.jqTargetOrg.trigger(g)}),t.jqProgress&&t.jqProgress.fadeOut(t.duration))},i.prototype.adjust=function(){var t,r;this.isBody?(t=this.jqWin.width(),r=this.jqWin.height(),this.jqOverlay.width(t).height(r),this.jqProgress&&this.jqProgress.css({left:(t-this.jqProgress.outerWidth())/2,top:(r-this.jqProgress.outerHeight())/2})):(this.addMarginR&&(t=this.jqTarget.css({paddingRight:this.orgMarginR,width:this.orgWidth}).width(),this.jqTarget.css("paddingRight","+="+this.addMarginR).width(t-this.addMarginR)),this.addMarginB&&(r=this.jqTarget.css({paddingBottom:this.orgMarginB,height:this.orgHeight}).height(),this.jqTarget.css("paddingBottom","+="+this.addMarginB).height(r-this.addMarginB)),t=Math.max(this.jqTarget.prop("scrollWidth"),this.jqTarget.innerWidth()),r=Math.max(this.jqTarget.prop("scrollHeight"),this.jqTarget.innerHeight()),this.jqOverlay.width(t).height(r),this.jqProgress&&(t=this.jqTarget.innerWidth(),r=this.jqTarget.innerHeight(),this.jqProgress.css({left:(t-this.jqProgress.outerWidth())/2+this.scrLeft,top:(r-this.jqProgress.outerHeight())/2+this.scrTop})))},i.prototype.reset=function(t){var r=this;t&&(r.jqOverlay.css("display","none"),r.jqProgress&&r.jqProgress.css("display","none")),r.isShown&&(r.jqTarget.css({position:r.orgPosition,overflow:r.orgOverflow}),r.isBody?(r.addMarginR&&r.jqTarget.css("marginRight",r.orgMarginR),r.addMarginB&&r.jqTarget.css("marginBottom",r.orgMarginB)):(r.addMarginR&&r.jqTarget.css({paddingRight:r.orgMarginR,width:r.orgWidth}),r.addMarginB&&r.jqTarget.css({paddingBottom:r.orgMarginB,height:r.orgHeight})),r.jqTarget.off("focusin",r.avoidFocus),r.jqActive&&r.jqActive.length&&r.jqActive.focus(),function(t){t.off("scroll",r.avoidScroll).scrollLeft(r.scrLeft).scrollTop(r.scrTop)}(r.isBody?r.jqWin:r.jqTarget),r.jqWin.off("resize",r.callAdjust),r.isShown=!1)},t.fn[n]=function(t,r){return"show"===t?o(this,r):"hide"===t?s(this):e(this,t)}}(jQuery); \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/scripts/pluginmanager.js b/conlite/plugins/pluginmanager/scripts/pluginmanager.js new file mode 100644 index 0000000..40a4b0c --- /dev/null +++ b/conlite/plugins/pluginmanager/scripts/pluginmanager.js @@ -0,0 +1,275 @@ + +// Ignore console on platforms where it is not available +if (typeof (window.console) == "undefined") { + console = {}; + console.log = console.warn = console.error = function (a) { + }; +} + +function showMessage(Msg, Level) { + var msgClass = ""; + switch (Level) { + case 'info': + msgClass = "info"; + break; + case 'warning': + msgClass = "warning"; + break; + case 'error': + msgClass = "error"; + break; + case 'success': + msgClass = "success"; + break; + default: + msgClass = "info"; + } + if ($("#pimmsg").length == 0) { + $("body").append('
' + Msg + '
'); + } else { + $("#pimmsg").attr('class', msgClass).html(Msg); + } + + $("#pimmsg").plainModal( + 'open', + { + duration: 500, + offset: { + left: 20, + top: 10 + }, + overlay: { + fillColor: '#fff', + opacity: 0.5 + } + }); + + setTimeout(function () { + $("#pimmsg").plainModal('close'); + }, 3000); +} + +function togglePluginInfo(tableId) { + var collapseButton = 'images/close_all.gif'; + var expandButton = 'images/open_all.gif'; + var curDiv = document.getElementById(tableId); + var curButton = document.getElementById(tableId + '_img'); + + if (curDiv.style.display == "table-row" || curDiv.style.display == "" || curDiv.style.display == "block") { + curDiv.style.display = "none"; + curButton.src = expandButton; + } else if (curDiv.style.display == "none") { + if (ie == 7) { + $('#' + tableId).css('display', 'block'); + } else { + curDiv.style.display = "table-row"; + } + curButton.src = collapseButton; + } +} + +// Read a page's GET URL variables and return them as an associative array. +function getUrlVars() { + var vars = [], hash; + var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); + for (var i = 0; i < hashes.length; i++) { + hash = hashes[i].split('='); + if (hash[0] == "contenido" || hash[0] == "plugin_action" || hash[0] == "plugin_id" || hash[0] == "delete_sql") { + continue; + } + vars.push(hash[0]); + vars[hash[0]] = hash[1]; + } + console.log(vars); + return vars; +} + + +$(function () { + + if ($("ul#pim_messages").length) { + var tmp = $("ul#pim_messages li").html(); + var message = tmp.split(':'); + showMessage(message[1], message[0]); + $("ul#pim_messages").remove(); + } + + $(document) + .ajaxStart(function () { + $('body').plainOverlay('show'); + }) + .ajaxStop(function () { + $('body').plainOverlay('hide'); + }); + + // add custom event before start to ui sortable + var oldMouseStart = $.ui.sortable.prototype._mouseStart; + $.ui.sortable.prototype._mouseStart = function (event, overrideHandle, noActivation) { + this._trigger("CustomBeforeStart", event, this._uiHash()); + oldMouseStart.apply(this, [event, overrideHandle, noActivation]); + }; + + $("#pimPluginsExtracted").sortable({ + connectWith: "#pimPluginsInstalled", + cursor: "move", + opacity: 0.5, + placeholder: "ui-state-highlight", + forceHelperSize: true, + forcePlaceholderSize: true, + CustomBeforeStart: function (event, ui) { + console.log(ui.item); + if (ui.item.find("div.pimInfo").is(":visible")) { + togglePluginInfo(ui.item.attr('id').replace("_", "-")); + } + } + }); + $("#pimPluginsInstalled").sortable({ + placeholder: "ui-state-highlight", + axis: "y", + containment: "parent", + forcePlaceholderSize: true, + CustomBeforeStart: function (event, ui) { + console.log(ui.item); + if (ui.item.find("div.pimInfo").is(":visible")) { + togglePluginInfo(ui.item.attr('id').replace("_", "-")); + } + }, + update: function (event, ui) { + console.log({plugins: $("#pimPluginsInstalled").sortable("serialize")}); + $.post("ajaxmain.php", { + plugins: $("#pimPluginsInstalled").sortable("serialize"), + ajax: 'plugin_request', + plugin: 'pluginmanager', + plugin_ajax_action: 'pim_save_sort', + contenido: cSessionId + }); + }, + receive: function (event, ui) { + console.log(ui.item); + $.ajax({ + type: "POST", + url: "ajaxmain.php", + data: { + plugin_folder: ui.item.data('plugin-foldername'), + new_position: ui.item.index(), + ajax: 'plugin_request', + plugin: 'pluginmanager', + plugin_ajax_action: 'pim_install', + contenido: cSessionId + }, + beforeSend: function (xhr, obj) { + //alert("Before"); + }, + success: function (data, textStatus, xhr) { + console.log(data); + var answer = data.split(":"); + console.log(answer); + if (answer[0] == "Ok") { + $.ajax({ + type: "POST", + url: "ajaxmain.php", + data: { + ajax: 'plugin_request', + plugin: 'pluginmanager', + plugin_ajax_action: 'pim_get_info_installed', + plugin_id: answer[1], + contenido: cSessionId + } + }).done(function (data) { + console.log(data); + $(ui.item).replaceWith(data); + }); + showMessage(answer[2], 'info'); + } else if (answer[0] == "Error") { + console.log("Remove New List Item."); + ui.sender.sortable("cancel"); // send back entry to sender :) + showMessage(answer[2], 'error'); + } else { + //window.location.replace("index.php"); // redirect to index if answer not correct or not set + } + $("span#plugin_count").html($("#pimPluginsInstalled").children().length); + }, + error: function (xhr, textStatus, errorThrown) { + showMessage(textStatus, 'error'); + console.log('a' + textStatus); + } + }); + return true; + } + }); + $("#pimPluginsInstalled li, #pimPluginsExtracted li").disableSelection(); + // actions for buttons in plugin info + var labelID; + $('label.pimButLabel').click(function (e) { + if ($(e.target).is('input')) { + return; + } + labelID = $(this).attr('for'); + $('#' + labelID).trigger('click'); + }); + $("ul#pimPluginsInstalled").on("click", "input.pimImgBut", function () { + var pluginID = $(this).attr('id'); + var thisInput = $(this); + switch ($(this).attr('name')) { + case "toggle_active": + $('body').plainOverlay('show'); + $.ajax({ + type: "POST", + url: "ajaxmain.php", + data: { + ajax: 'plugin_request', + plugin: 'pluginmanager', + plugin_ajax_action: 'toggle_active', + plugin_id: pluginID.split('-')[3], + contenido: cSessionId + }, + success: function (data, textStatus, xhr) { + console.log(data); + var aData = data.split(":"); + console.log(aData); + if (aData[0] == "Ok") { + if (aData[1] == '1') { + thisInput.attr('src', 'images/online.gif'); + } else { + thisInput.attr('src', 'images/offline.gif'); + } + $("label[for=" + pluginID + "]").html(aData[2]); + } + } + }); + break; + case "uninstall_plugin": + $('body').plainOverlay('show'); + var hiddenFields = []; + hiddenFields.push("plugin_id"); + hiddenFields["plugin_id"] = pluginID.split('-')[3]; + hiddenFields.push("plugin_action"); + hiddenFields["plugin_action"] = "uninstall_plugin"; + /* + hiddenFields.push("contenido"); + hiddenFields["contenido"] = cSessionId; */ + hiddenFields.push("delete_sql"); + console.log($(this).parent().children("label:eq(1)").children("input")); + if ($(this).parent().children("label:eq(1)").children("input").prop('checked') == true) { + hiddenFields["delete_sql"] = "delete"; + } else { + hiddenFields["delete_sql"] = "hold"; + } + $("#pim_uninstall").remove(); + var form = document.createElement('form'); + form.id = "pim_uninstall"; + form.method = 'post'; + $.each(hiddenFields, function (index, name) { + var input = document.createElement('input'); + input.type = 'hidden'; + input.name = name; + input.value = hiddenFields[name]; + form.appendChild(input); + }); + form.action = window.location.protocol + '//' + window.location.hostname + window.location.pathname + window.location.search; + document.body.appendChild(form); + form.submit(); + break; + } + }); +}); \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/temp/conlite_sample_plugin.zip b/conlite/plugins/pluginmanager/temp/conlite_sample_plugin.zip new file mode 100644 index 0000000..e1c9d41 Binary files /dev/null and b/conlite/plugins/pluginmanager/temp/conlite_sample_plugin.zip differ diff --git a/conlite/plugins/pluginmanager/temp/linkchecker.zip b/conlite/plugins/pluginmanager/temp/linkchecker.zip new file mode 100644 index 0000000..d84bc16 Binary files /dev/null and b/conlite/plugins/pluginmanager/temp/linkchecker.zip differ diff --git a/conlite/plugins/pluginmanager/templates/pi_manager_extracted_plugins.html b/conlite/plugins/pluginmanager/templates/pi_manager_extracted_plugins.html new file mode 100644 index 0000000..424e17d --- /dev/null +++ b/conlite/plugins/pluginmanager/templates/pi_manager_extracted_plugins.html @@ -0,0 +1,53 @@ +
  • +
    +
    + + + + {PLUGIN_NAME} {VERSION} +
    + +
    +
  • \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/templates/pi_manager_install.html b/conlite/plugins/pluginmanager/templates/pi_manager_install.html new file mode 100644 index 0000000..f122870 --- /dev/null +++ b/conlite/plugins/pluginmanager/templates/pi_manager_install.html @@ -0,0 +1,11 @@ + + + + + Untitled Document + + + + + diff --git a/conlite/plugins/pluginmanager/templates/pi_manager_installed_plugins.html b/conlite/plugins/pluginmanager/templates/pi_manager_installed_plugins.html new file mode 100644 index 0000000..55a0ac9 --- /dev/null +++ b/conlite/plugins/pluginmanager/templates/pi_manager_installed_plugins.html @@ -0,0 +1,94 @@ +
  • +
    +
    + + + + {NAME} {VERSION} + +
    + + +
    +
  • \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/templates/pi_manager_overview.html b/conlite/plugins/pluginmanager/templates/pi_manager_overview.html new file mode 100644 index 0000000..50043d9 --- /dev/null +++ b/conlite/plugins/pluginmanager/templates/pi_manager_overview.html @@ -0,0 +1,31 @@ + + +

    ConLite Plugin Manager

    +

    {LANG_EXTRACTED}

    +

    {LANG_HINT_EXTRACTED}

    +
      {PLUGINS_EXTRACTED}
    +
     
    +
    +

    {LANG_INSTALLED} ({INSTALLED_PLUGINS})

    + +
      {PLUGINS}
    +
    \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/templates/pi_manager_plugins.html b/conlite/plugins/pluginmanager/templates/pi_manager_plugins.html new file mode 100644 index 0000000..ca5a1f7 --- /dev/null +++ b/conlite/plugins/pluginmanager/templates/pi_manager_plugins.html @@ -0,0 +1,12 @@ + + {NAME} {VERSION} + + + + + +
    + \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/xml/lang_de_DE.xml b/conlite/plugins/pluginmanager/xml/lang_de_DE.xml new file mode 100644 index 0000000..31b2252 --- /dev/null +++ b/conlite/plugins/pluginmanager/xml/lang_de_DE.xml @@ -0,0 +1,10 @@ + + + + + +
    PluginManager
    +
    +
    +
    +
    \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/xml/lang_en_EN.xml b/conlite/plugins/pluginmanager/xml/lang_en_EN.xml new file mode 100644 index 0000000..31b2252 --- /dev/null +++ b/conlite/plugins/pluginmanager/xml/lang_en_EN.xml @@ -0,0 +1,10 @@ + + + + + +
    PluginManager
    +
    +
    +
    +
    \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/xml/lang_en_US.xml b/conlite/plugins/pluginmanager/xml/lang_en_US.xml new file mode 100644 index 0000000..31b2252 --- /dev/null +++ b/conlite/plugins/pluginmanager/xml/lang_en_US.xml @@ -0,0 +1,10 @@ + + + + + +
    PluginManager
    +
    +
    +
    +
    \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/xml/plugin_default.xml b/conlite/plugins/pluginmanager/xml/plugin_default.xml new file mode 100644 index 0000000..67ecf46 --- /dev/null +++ b/conlite/plugins/pluginmanager/xml/plugin_default.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conlite/plugins/pluginmanager/xml/plugin_info.xml b/conlite/plugins/pluginmanager/xml/plugin_info.xml new file mode 100644 index 0000000..be67288 --- /dev/null +++ b/conlite/plugins/pluginmanager/xml/plugin_info.xml @@ -0,0 +1,44 @@ + + + + + Linkchecker + linkchecker + a9613eabde004e1ad4daad30a25def6555f4ac28 + Checks intern and extern links to valid + Frederic Schneider (4fb) + four for business AG + 2.0.0 + 4.6.0 + + + + b9653ztdbde004e1ad4dbbd90a25def6555f4gh40 + + + + + + linkchecker + lc_whitelist + + + + linkchecker + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conlite/plugins/pluginmanager/xml/plugin_info.xsd b/conlite/plugins/pluginmanager/xml/plugin_info.xsd new file mode 100644 index 0000000..356b5ac --- /dev/null +++ b/conlite/plugins/pluginmanager/xml/plugin_info.xsd @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/cronlog/move_articles.php.job b/data/cronlog/move_articles.php.job new file mode 100644 index 0000000..1c57515 --- /dev/null +++ b/data/cronlog/move_articles.php.job @@ -0,0 +1 @@ +1582131720 \ No newline at end of file diff --git a/data/cronlog/move_old_stats.php.job b/data/cronlog/move_old_stats.php.job new file mode 100644 index 0000000..4954459 --- /dev/null +++ b/data/cronlog/move_old_stats.php.job @@ -0,0 +1 @@ +1580511600 \ No newline at end of file diff --git a/data/cronlog/optimize_database.php.job b/data/cronlog/optimize_database.php.job new file mode 100644 index 0000000..2ed1f0d --- /dev/null +++ b/data/cronlog/optimize_database.php.job @@ -0,0 +1 @@ +1582066800 \ No newline at end of file diff --git a/data/cronlog/send_reminder.php.job b/data/cronlog/send_reminder.php.job new file mode 100644 index 0000000..8d3a7e1 --- /dev/null +++ b/data/cronlog/send_reminder.php.job @@ -0,0 +1 @@ +1582131600 \ No newline at end of file diff --git a/data/cronlog/session_cleanup.php.job b/data/cronlog/session_cleanup.php.job new file mode 100644 index 0000000..8d3a7e1 --- /dev/null +++ b/data/cronlog/session_cleanup.php.job @@ -0,0 +1 @@ +1582131600 \ No newline at end of file diff --git a/data/cronlog/setfrontenduserstate.php.job b/data/cronlog/setfrontenduserstate.php.job new file mode 100644 index 0000000..8d3a7e1 --- /dev/null +++ b/data/cronlog/setfrontenduserstate.php.job @@ -0,0 +1 @@ +1582131600 \ No newline at end of file diff --git a/data/logs/.gitignore b/data/logs/.gitignore new file mode 100644 index 0000000..2323280 --- /dev/null +++ b/data/logs/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore +!index.php \ No newline at end of file