getAddonDownloadFilename(); if (!isset($filename) || empty($filename)) { $filename = "download.tar"; } $dir = $this->getDownloadDirectory(); return "$dir/$filename"; } public function getDownloadDirectory() { $dir = PATH_DATA . "upgrade/{$this->getStoreId()}_{$this->getAddonName()}"; if (!file_exists($dir)) { mkdir($dir, 0777, true); } return ($dir); } /** * Check to see if the download file exists and has the right data. * * @return mixed true if exists and md5 is good, false otherwise. Returns null * if file exists but md5 for the download is not available. */ public function checkDownload() { $filename = $this->getDownloadFilename(); if (!file_exists($filename)) { return false; } $download_md5 = $this->getAddonDownloadMd5(); if ($download_md5 == null) { return null; } return (strcasecmp(G::encryptFileOld($filename), $download_md5) == 0); } /** * Returns if this addon is of type 'plugin' * * @return bool true if is of type 'plugin', false otherwise */ public function isPlugin() { return ($this->getAddonType() == 'plugin'); } /** * Returns if this addon is of type 'core' * * @return bool true if is of type 'core', false otherwise */ public function isCore() { return ($this->getAddonType() == 'core'); } /** * Returns if this addon is installed or not- * * @return bool true if installed, false otherwise */ public function isInstalled() { if ($this->isCore()) { return ($this->getAddonVersion() == $this->getInstalledVersion()); } elseif ($this->isPlugin()) { return (file_exists(PATH_PLUGINS . "{$this->getAddonName()}.php")); } else { throw new Exception("Addon type '{$this->getAddonType()}' unsupported"); } } /** * Returns if this addon is enabled or not. * * @return bool true if enabled, false otherwise */ public function isEnabled() { if ($this->isCore()) { return $this->isInstalled(); } elseif ($this->isPlugin()) { if (!$this->isInstalled()) { return false; } $oPluginRegistry = PluginRegistry::loadSingleton(); return $oPluginRegistry->isEnable($this->getAddonName()); } else { throw new Exception("Addon type '{$this->getAddonType()}' unsupported"); } } public function setEnabled($enable = true) { if (!$this->isInstalled() || !$this->isPlugin()) { return false; } if ($this->getAddonName() == "enterprise") { return false; } $oPluginRegistry = PluginRegistry::loadSingleton(); $filter = new InputFilter(); $requiredPath = PATH_PLUGINS . $this->getAddonName() . ".php"; $requiredPath = $filter->validateInput($requiredPath, 'path'); require_once($requiredPath); if ($enable) { $oPluginRegistry->enablePlugin($this->getAddonName()); $oPluginRegistry->setupPlugins(); //get and setup enabled plugins } else { $oPluginRegistry->disablePlugin($this->getAddonName()); } $oPluginRegistry->savePlugin($this->getAddonName()); return true; } /** * Returns the currently installed version of this addon. * * @return string the installed version or an empty string otherwise. */ public function getInstalledVersion() { if ($this->isCore()) { return (EnterpriseUtils::pmVersion(System::getVersion())); } else { if ($this->isPlugin()) { if (!$this->isInstalled()) { return (null); } $oPluginRegistry = PluginRegistry::loadSingleton(); $details = $oPluginRegistry->getPluginDetails($this->getAddonName() . ".php"); $v = (!($details == null))? $details->getVersion() : null; if ($v != "") { return ($v); } if (file_exists(PATH_PLUGINS . $this->getAddonName() . PATH_SEP . "VERSION")) { return (trim(file_get_contents(PATH_PLUGINS . $this->getAddonName() . PATH_SEP . "VERSION"))); } } else { if ($this->getAddonType() == "core") { throw new Exception("Addon type \"" . $this->getAddonType() . "\" unsupported"); } } } } public function refresh() { /* Update our information from the db */ $rs = $this->getPeer()->doSelectRS($this->buildPkeyCriteria()); $rs->first(); $this->hydrate($rs); } /** * Download this addon from the download url. * * @return bool true on success, false otherwise. */ public function download() { $this->setState("download"); /////// $aux = explode("?", $this->getAddonDownloadUrl()); $url = $aux[0]; $var = explode("&", $aux[1]); /////// $boundary = "---------------------" . substr(G::encryptOld(rand(0, 32000)), 0, 10); $data = null; for ($i = 0; $i <= count($var) - 1; $i++) { $aux = explode("=", $var[$i]); $data = $data . "--$boundary\n"; $data = $data . "Content-Disposition: form-data; name=\"" . $aux[0] . "\"\n\n" . $aux[1] . "\n"; } if (count($var) > 0) { $data = $data . "--$boundary\n"; } /////// $licenseManager = PmLicenseManager::getSingleton(); $activeLicense = $licenseManager->getActiveLicense(); $data = $data . "Content-Disposition: form-data; name=\"licenseFile\"; filename=\"" . $licenseManager->file . "\"\n"; $data = $data . "Content-Type: text/plain\n"; //$data = $data . "Content-Type: image/jpeg\n"; $data = $data . "Content-Transfer-Encoding: binary\n\n"; $data = $data . file_get_contents($activeLicense["LICENSE_PATH"]) . "\n"; $data = $data . "--$boundary\n"; /////// $option = array( "http" => array( "method" => "POST", //"method" => "post", "header" => "Content-Type: multipart/form-data; boundary=" . $boundary, "content" => $data ) ); // Proxy settings $sysConf = System::getSystemConfiguration(); if ($sysConf['proxy_host'] != '') { if (!is_array($option['http'])) { $option['http'] = array(); } $option['http']['request_fulluri'] = true; $option['http']['proxy'] = 'tcp://' . $sysConf['proxy_host'] . ($sysConf['proxy_port'] != '' ? ':' . $sysConf['proxy_port'] : ''); if ($sysConf['proxy_user'] != '') { if (!isset($option['http']['header'])) { $option['http']['header'] = ''; } $option['http']['header'] .= 'Proxy-Authorization: Basic ' . base64_encode($sysConf['proxy_user'] . ($sysConf['proxy_pass'] != '' ? ':' . $sysConf['proxy_pass'] : '')); } } $context = stream_context_create($option); /////// $handle = fopen($url, "rb", false, $context); if ($handle === false) { throw new Exception("Could not open download url."); } $this->setAddonDownloadFilename(null); //Try to get the download size and filename (ok if it fails) $meta = stream_get_meta_data($handle); $totalSize = 0; if ($meta["wrapper_type"] == "http") { foreach ($meta["wrapper_data"] as $info) { $info = explode(":", $info); if (strcasecmp(trim($info[0]), "Content-Length") == 0) { $totalSize = intval(trim($info[1])); } if (strcasecmp(trim($info[0]), "Content-Disposition") == 0) { foreach (explode(";", $info[1]) as $params) { $params = explode("=", $params); if (count($params) <= 1) { continue; } if (strcasecmp(trim($params[0]), "filename") == 0) { $this->setAddonDownloadFilename(trim($params[1], "\" ")); } } } } } //Save the filename $this->save(); $units = array(" B", " KB", " MB", " GB", " TB"); //if ($totalSize) { // $bytes = $totalSize; // for ($i = 0; $bytes >= 1024 && $i < 4; $i++) $bytes /= 1024; // printf("Download size: %.2f%s\n", round($bytes, 2), $units[$i]); //} $downloadFile = $this->getDownloadFilename(); $file = @fopen($downloadFile, "wb"); if ($file === false) { throw new Exception("Could not open destination file."); } $start = microtime(true); $rate = null; $position = null; $elapsed = null; while (!feof($handle)) { $this->refresh(); /* Check if download was cancelled from the ui */ if ($this->getAddonState() == "cancel" || $this->getAddonState() == "") { $this->setState(); break; } /* Update the database information to show we are still alive */ $this->setState("download"); $data = fread($handle, BUFSIZE); //TODO: We should use these values for something $elapsed = microtime(true) - $start; $position = ftell($handle); $rate = $position / $elapsed; if ($totalSize) { $progress = 100 * ($position / $totalSize); $this->setAddonDownloadProgress($progress); $this->save(); } /* Just to be safe, check all error conditions */ if ($data === "" or $data === false) { break; } if (fwrite($file, $data) === false) { break; } } fclose($handle); fclose($file); if ($elapsed > 60) { $time = sprintf("%.0f minutes and %.0f seconds", round($elapsed / 60), round($elapsed) % 60); } else { $time = sprintf("%.0f seconds", round($elapsed)); } for ($i = 0; $position >= 1024 && $i < 4; $i++) { $position /= 1024; } for ($j = 0; $rate >= 1024 && $j < 4; $j++) { $rate /= 1024; } //printf("Downloaded %.2f%s in %s (rate: %.2f%s/s)\n", $position, $units[$i], $time, $rate, $units[$j]); return ($this->checkDownload()); } /** * Install this addon from the downloaded file. */ public function install() { $this->setState("install"); $filename = $this->getDownloadFilename(); //if ($this->checkDownload() === false) { // throw new Exception("Download file is invalid"); //} if ($this->isPlugin()) { if ($this->getAddonId() == "enterprise") { $_SESSION["__ENTERPRISE_INSTALL__"] = 1; } $oPluginRegistry = PluginRegistry::loadSingleton(); $oPluginRegistry->installPluginArchive($filename, $this->getAddonName()); $this->setState(); } else { if ($this->getAddonType() == "core") { $upgrade = new Upgrade($this); $upgrade->install(); } else { throw new Exception("Addon type {$this->getAddonType()} not supported."); } } } public function uninstall() { if ($this->isPlugin()) { if (!$this->isInstalled()) { return false; } $oPluginRegistry = PluginRegistry::loadSingleton(); $oPluginRegistry->uninstallPlugin($this->getAddonName()); return true; } } public function getInstallLog() { $logFile = $this->getDownloadDirectory() . "/download.log"; $contents = false; if (file_exists($logFile)) { $contents = @file_get_contents($logFile); } if ($contents === false) { return null; } return $contents; } public function setState($state = "") { $this->setAddonState($state); $this->setAddonStateChanged('now'); $this->save(); } public function checkState() { if ($this->getAddonState() == 'error') { $this->setState(); return false; } if ($this->getAddonState() == '' || $this->getAddonState() == 'install-finish') { return true; } $elapsed = time() - strtotime($this->getAddonStateChanged()); $timeout = 3; if ($this->isCore()) { $timeout = 10; } if ($elapsed > $timeout * 60) { $this->setState(); return false; } return true; } /** * Exists in Addons Manager Table * * @param string $addonId * @param string $storeId * @return type * @throws type */ public function exists($addonId, $storeId) { $oAddManager = AddonsManagerPeer::retrieveByPK($addonId, $storeId); return (!is_null($oAddManager)); } /** * Update Addons Manager Table * * @param type $data * @return type * @throws type */ public function update($data) { $con = Propel::getConnection(AddonsManagerPeer::DATABASE_NAME); try { $con->begin(); $this->setNew(false); $this->fromArray($data, BasePeer::TYPE_FIELDNAME); if ($this->validate()) { $result = $this->save(); $con->commit(); return $result; } else { $con->rollback(); throw (new Exception("Failed Validation in class " . get_class($this) . ".")); } } catch (Exception $e) { $con->rollback(); throw ($e); } } }