/** * Download a part (or the whole) of a remote URL and return the downloaded * data. You are supposed to check the size of the returned data. If it's * smaller than what you expected you've reached end of file. If it's empty * you have tried reading past EOF. If it's larger than what you expected * the server doesn't support chunk downloads. * * If this class' supportsChunkDownload returns false you should assume * that the $from and $to parameters will be ignored. * * @param string $url The remote file's URL * @param integer $from Byte range to start downloading from. Use null for start of file. * @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored) * * @return string The raw file data retrieved from the remote URL. * * @throws \Exception A generic exception is thrown on error */ public function downloadAndReturn($url, $from = null, $to = null) { $ch = curl_init(); if (empty($from)) { $from = 0; } if (empty($to)) { $to = 0; } if ($to < $from) { $temp = $to; $to = $from; $from = $temp; unset($temp); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); if (!(empty($from) && empty($to))) { curl_setopt($ch, CURLOPT_RANGE, "{$from}-{$to}"); } $result = curl_exec($ch); $errno = curl_errno($ch); $errmsg = curl_error($ch); $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($result === false) { $error = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_CURL_ERROR', $errno, $errmsg); } elseif ($http_status > 299) { $result = false; $errno = $http_status; $error = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_HTTPERROR', $http_status); } curl_close($ch); if ($result === false) { throw new \Exception($error, $errno); } else { return $result; } }
/** * Loads a template given any path. The path is in the format: * viewname/templatename * * @param string $path The template path * @param array $forceParams A hash array of variables to be extracted in the local scope of the template file * * @return string The output of the template * * @throws \Exception When the layout file is not found */ public function loadAnyTemplate($path = '', $forceParams = array()) { $template = \Awf\Application\Application::getInstance()->getTemplate(); $layoutTemplate = $this->getLayoutTemplate(); // Parse the path $templateParts = $this->parseTemplatePath($path); // Get the default paths $templatePath = $this->container->templatePath; $paths = array(); $paths[] = $templatePath . '/' . $template . '/html/' . $this->input->getCmd('option', '') . '/' . $templateParts['view']; $paths[] = $this->container->basePath . '/views/' . $templateParts['view'] . '/tmpl'; $paths[] = $this->container->basePath . '/View/' . $templateParts['view'] . '/tmpl'; $paths = array_merge($paths, $this->templatePaths); // Look for a template override if (isset($layoutTemplate) && $layoutTemplate != '_' && $layoutTemplate != $template) { $apath = array_shift($paths); array_unshift($paths, str_replace($template, $layoutTemplate, $apath)); } $filetofind = $templateParts['template'] . '.php'; $this->_tempFilePath = \Awf\Utils\Path::find($paths, $filetofind); if ($this->_tempFilePath) { // Unset from local scope unset($template); unset($layoutTemplate); unset($paths); unset($path); unset($filetofind); // Never allow a 'this' property if (isset($this->this)) { unset($this->this); } // Force parameters into scope if (!empty($forceParams)) { extract($forceParams); } // Start capturing output into a buffer ob_start(); // Include the requested template filename in the local scope // (this will execute the view logic). include $this->_tempFilePath; // Done with the requested template; get the buffer and // clear it. $this->output = ob_get_contents(); ob_end_clean(); return $this->output; } else { return new \Exception(\Awf\Text\Text::sprintf('AWF_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $path), 500); } }
/** * Download a part (or the whole) of a remote URL and return the downloaded * data. You are supposed to check the size of the returned data. If it's * smaller than what you expected you've reached end of file. If it's empty * you have tried reading past EOF. If it's larger than what you expected * the server doesn't support chunk downloads. * * If this class' supportsChunkDownload returns false you should assume * that the $from and $to parameters will be ignored. * * @param string $url The remote file's URL * @param integer $from Byte range to start downloading from. Use null for start of file. * @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored) * * @return string The raw file data retrieved from the remote URL. * * @throws \Exception A generic exception is thrown on error */ public function downloadAndReturn($url, $from = null, $to = null) { if (empty($from)) { $from = 0; } if (empty($to)) { $to = 0; } if ($to < $from) { $temp = $to; $to = $from; $from = $temp; unset($temp); } if (!(empty($from) && empty($to))) { $options = array('http' => array('method' => 'GET', 'header' => "Range: bytes={$from}-{$to}\r\n")); $context = stream_context_create($options); $result = @file_get_contents($url, false, $context, $from - $to + 1); } else { $options = array('http' => array('method' => 'GET')); $context = stream_context_create($options); $result = @file_get_contents($url, false, $context); } if (!isset($http_response_header)) { $error = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_FOPEN_ERROR'); throw new \Exception($error, 404); } else { $http_code = 200; $nLines = count($http_response_header); for ($i = $nLines - 1; $i >= 0; $i--) { $line = $http_response_header[$i]; if (strncasecmp("HTTP", $line, 4) == 0) { $response = explode(' ', $line); $http_code = $response[1]; break; } } if ($http_code >= 299) { $error = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_FOPEN_ERROR'); throw new \Exception($error, 404); } } if ($result === false) { $error = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_FOPEN_ERROR'); throw new \Exception($error, 1); } else { return $result; } }
/** * Executes a given controller task. The onBefore<task> and onAfter<task> * methods are called automatically if they exist. * * @param string $task The task to execute, e.g. "browse" * * @return null|bool False on execution failure * * @throws \Exception When the task is not found */ public function execute($task) { $this->task = $task; $task = strtolower($task); if (isset($this->taskMap[$task])) { $doTask = $this->taskMap[$task]; } elseif (isset($this->taskMap['__default'])) { $doTask = $this->taskMap['__default']; } else { throw new \Exception(Text::sprintf('AWF_APPLICATION_ERROR_TASK_NOT_FOUND', $task), 404); } $method_name = 'onBefore' . ucfirst($task); if (method_exists($this, $method_name)) { $result = $this->{$method_name}(); if (!$result) { return false; } } // Do not allow the display task to be directly called $task = strtolower($task); if (isset($this->taskMap[$task])) { $doTask = $this->taskMap[$task]; } elseif (isset($this->taskMap['__default'])) { $doTask = $this->taskMap['__default']; } else { $doTask = null; } // Record the actual task being fired $this->doTask = $doTask; $ret = $this->{$doTask}(); $method_name = 'onAfter' . ucfirst($task); if (method_exists($this, $method_name)) { $result = $this->{$method_name}(); if (!$result) { return false; } } return $ret; }
/** * Executes a SQL statement, ignoring errors in the $allowedErrorCodes list. * * @param string $sql The SQL statement to execute * * @return mixed A database cursor on success, false on failure * * @throws \Exception On error */ protected function execute($sql) { $db = $this->getDatabase(); try { $db->setQuery($sql); $result = $db->execute(); } catch (\Exception $exc) { $result = false; if (!in_array($exc->getCode(), $this->allowedErrorCodes)) { // Format the error message and throw it again $message = '<h2>' . Text::sprintf('AWF_RESTORE_ERROR_ERRORATLINE', $this->lineNumber) . '</h2>' . "\n"; $message .= '<p>' . Text::_('AWF_RESTORE_ERROR_MYSQLERROR') . '</p>' . "\n"; $message .= '<code>ErrNo #' . htmlspecialchars($exc->getCode()) . '</code>' . "\n"; $message .= '<pre>' . htmlspecialchars($exc->getMessage()) . '</pre>' . "\n"; $message .= '<p>' . Text::_('AWF_RESTORE_ERROR_RAWQUERY') . '</p>' . "\n"; $message .= '<pre>' . htmlspecialchars($sql) . '</pre>' . "\n"; // Rethrow the exception if we're not supposed to handle it throw new \Exception($message); } } return $result; }
/** * Create and return the pagination result set counter string, e.g. Results 1-10 of 42 * * @return string Pagination result set counter string. */ public function getResultsCounter() { $html = null; $fromResult = $this->limitStart + 1; // If the limit is reached before the end of the list. if ($this->limitStart + $this->limit < $this->total) { $toResult = $this->limitStart + $this->limit; } else { $toResult = $this->total; } // If there are results found. if ($this->total > 0) { $msg = Text::sprintf('AWF_PAGINATION_LBL_RESULTS_OF', $fromResult, $toResult, $this->total); $html .= "\n" . $msg; } else { $html .= "\n" . Text::_('AWF_PAGINATION_LBL_NO_RESULTS'); } return $html; }
/** * Performs the staggered download of file. * * @param array $params A parameters array, as sent by the user interface * * @return array A return status array */ public function importFromURL($params) { $this->params = $params; // Fetch data $filename = $this->getParam('file'); $frag = $this->getParam('frag', -1); $totalSize = $this->getParam('totalSize', -1); $doneSize = $this->getParam('doneSize', -1); $maxExecTime = $this->getParam('maxExecTime', 5); $runTimeBias = $this->getParam('runTimeBias', 75); $minExecTime = $this->getParam('minExecTime', 1); $localFilename = 'download.zip'; $tmpDir = Application::getInstance()->getContainer()->temporaryPath; $tmpDir = rtrim($tmpDir, '/\\'); $localFilename = $this->getParam('localFilename', $localFilename); // Init retArray $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => 0); try { $timer = new Timer($minExecTime, $runTimeBias); $start = $timer->getRunningTime(); // Mark the start of this download $break = false; // Don't break the step // Figure out where on Earth to put that file $local_file = $tmpDir . '/' . $localFilename; //debugMsg("- Importing from $filename"); while ($timer->getTimeLeft() > 0 && !$break) { // Do we have to initialize the file? if ($frag == -1) { //debugMsg("-- First frag, killing local file"); // Currently downloaded size $doneSize = 0; if (@file_exists($local_file)) { @unlink($local_file); } // Delete and touch the output file $fp = @fopen($local_file, 'wb'); if ($fp !== false) { @fclose($fp); } // Init $frag = 0; //debugMsg("-- First frag, getting the file size"); $retArray['totalSize'] = $this->adapter->getFileSize($filename); $totalSize = $retArray['totalSize']; } // Calculate from and length $length = 1048576; $from = $frag * $length; $to = $length + $from - 1; // Try to download the first frag $required_time = 1.0; //debugMsg("-- Importing frag $frag, byte position from/to: $from / $to"); try { $result = $this->adapter->downloadAndReturn($filename, $from, $to); if ($result === false) { throw new \Exception(Text::sprintf('AWF_DOWNLOAD_ERR_LIB_COULDNOTDOWNLOADFROMURL', $filename), 500); } } catch (\Exception $e) { $result = false; $error = $e->getMessage(); } if ($result === false) { // Failed download if ($frag == 0) { // Failure to download first frag = failure to download. Period. $retArray['status'] = false; $retArray['error'] = $error; //debugMsg("-- Download FAILED"); return $retArray; } else { // Since this is a staggered download, consider this normal and finish $frag = -1; //debugMsg("-- Import complete"); $totalSize = $doneSize; $break = true; } } // Add the currently downloaded frag to the total size of downloaded files if ($result) { $filesize = strlen($result); //debugMsg("-- Successful download of $filesize bytes"); $doneSize += $filesize; // Append the file $fp = @fopen($local_file, 'ab'); if ($fp === false) { //debugMsg("-- Can't open local file $local_file for writing"); // Can't open the file for writing $retArray['status'] = false; $retArray['error'] = Text::sprintf('AWF_DOWNLOAD_ERR_LIB_COULDNOTWRITELOCALFILE', $local_file); return $retArray; } fwrite($fp, $result); fclose($fp); //debugMsg("-- Appended data to local file $local_file"); $frag++; //debugMsg("-- Proceeding to next fragment, frag $frag"); if ($filesize < $length || $filesize > $length) { // A partial download or a download larger than the frag size means we are done $frag = -1; //debugMsg("-- Import complete (partial download of last frag)"); $totalSize = $doneSize; $break = true; } } // Advance the frag pointer and mark the end $end = $timer->getRunningTime(); // Do we predict that we have enough time? $required_time = max(1.1 * ($end - $start), $required_time); if ($required_time > 10 - $end + $start) { $break = true; } $start = $end; } if ($frag == -1) { $percent = 100; } elseif ($doneSize <= 0) { $percent = 0; } else { if ($totalSize > 0) { $percent = 100 * ($doneSize / $totalSize); } else { $percent = 0; } } // Update $retArray $retArray = array("status" => true, "error" => '', "frag" => $frag, "totalSize" => $totalSize, "doneSize" => $doneSize, "percent" => $percent); } catch (\Exception $e) { //debugMsg("EXCEPTION RAISED:"); //debugMsg($e->getMessage()); $retArray['status'] = false; $retArray['error'] = $e->getMessage(); } return $retArray; }