/**
  * @inheritDoc
  */
 public function readLine()
 {
     if (!$this->file->eof()) {
         $line = $this->file->current();
         $this->file->next();
         return json_decode($line);
     }
     return false;
 }
Esempio n. 2
0
/**
 * 返回文件从X行到Y行的内容(支持php5、php4)
 * @param  String  $filename  文件名
 * @param  integer $startLine 开始行
 * @param  integer $endLine   结束行
 * @param  string  $method    方法
 * @return array() 返回数组
 */
function readFileByLines($filename, $startLine = 1, $endLine = 50, $method = 'rb')
{
    $content = array();
    $count = $endLine - $startLine;
    // 判断php版本(因为要用到SplFileObject,PHP>=5.1.0)
    if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
        $fp = new SplFileObject($filename, $method);
        // 转到第N行, seek方法参数从0开始计数
        $fp->seek($startLine - 1);
        for ($i = 0; $i <= $count; ++$i) {
            // current()获取当前行内容
            $content[] = $fp->current();
            // 下一行
            $fp->next();
        }
    } else {
        //PHP<5.1
        $fp = fopen($filename, $method);
        if (!$fp) {
            return 'error:can not read file';
        }
        // 跳过前$startLine行
        for ($i = 1; $i < $startLine; ++$i) {
            fgets($fp);
        }
        // 读取文件行内容
        for ($i; $i <= $endLine; ++$i) {
            $content[] = fgets($fp);
        }
        fclose($fp);
    }
    // array_filter过滤:false,null,''
    return array_filter($content);
}
Esempio n. 3
0
 /**
  * Get Code from file
  * @param $path
  * @param $line
  * @param $numLines
  * @return array|null
  */
 private function getCode($path, $line, $numLines)
 {
     if (empty($path) || empty($line) || !file_exists($path)) {
         return NULL;
     }
     try {
         // Get the number of lines in the file
         $file = new \SplFileObject($path);
         $file->seek(PHP_INT_MAX);
         $totalLines = $file->key() + 1;
         // Work out which lines we should fetch
         $start = max($line - floor($numLines / 2), 1);
         $end = $start + ($numLines - 1);
         if ($end > $totalLines) {
             $end = $totalLines;
             $start = max($end - ($numLines - 1), 1);
         }
         // Get the code for this range
         $code = array();
         $file->seek($start - 1);
         while ($file->key() < $end) {
             $code[$file->key() + 1] = rtrim($file->current());
             $file->next();
         }
         return $code;
     } catch (RuntimeException $ex) {
         return null;
     }
 }
Esempio n. 4
0
 protected function export($var, $return = false)
 {
     if ($var instanceof Closure) {
         /* dump anonymous function in to plain code.*/
         $ref = new ReflectionFunction($var);
         $file = new SplFileObject($ref->getFileName());
         $file->seek($ref->getStartLine() - 1);
         $result = '';
         while ($file->key() < $ref->getEndLine()) {
             $result .= $file->current();
             $file->next();
         }
         $begin = strpos($result, 'function');
         $end = strrpos($result, '}');
         $result = substr($result, $begin, $end - $begin + 1);
     } elseif (is_object($var)) {
         /* dump object with construct function. */
         $result = 'new ' . get_class($var) . '(' . $this->export(get_object_vars($var), true) . ')';
     } elseif (is_array($var)) {
         /* dump array in plain array.*/
         $array = array();
         foreach ($var as $k => $v) {
             $array[] = var_export($k, true) . ' => ' . $this->export($v, true);
         }
         $result = 'array(' . implode(', ', $array) . ')';
     } else {
         $result = var_export($var, true);
     }
     if (!$return) {
         print $result;
     }
     return $result;
 }
Esempio n. 5
0
 /**
  * Write the compiled csv to disk and return the file name
  *
  * @param array $sortedHeaders An array of sorted headers
  *
  * @return string The csv filename where the data was written
  */
 public function prepare($cacheFile, $sortedHeaders)
 {
     $csvFile = $cacheFile . '.csv';
     $handle = fopen($csvFile, 'w');
     // Generate a csv version of the multi-row headers to write to disk
     $headerRows = [[], []];
     foreach ($sortedHeaders as $idx => $header) {
         if (!is_array($header)) {
             $headerRows[0][] = $header;
             $headerRows[1][] = '';
         } else {
             foreach ($header as $headerName => $subHeaders) {
                 $headerRows[0][] = $headerName;
                 $headerRows[1] = array_merge($headerRows[1], $subHeaders);
                 if (count($subHeaders) > 1) {
                     /**
                      * We need to insert empty cells for the first row of headers to account for the second row
                      * this acts as a faux horizontal cell merge in a csv file
                      * | Header 1 | <---- 2 extra cells ----> |
                      * | Sub 1    | Subheader 2 | Subheader 3 |
                      */
                     $headerRows[0] = array_merge($headerRows[0], array_fill(0, count($subHeaders) - 1, ''));
                 }
             }
         }
     }
     fputcsv($handle, $headerRows[0]);
     fputcsv($handle, $headerRows[1]);
     // TODO: Track memory usage
     $file = new \SplFileObject($cacheFile);
     while (!$file->eof()) {
         $csvRow = [];
         $row = json_decode($file->current(), true);
         if (!is_array($row)) {
             // Invalid json data -- don't process this row
             continue;
         }
         foreach ($sortedHeaders as $idx => $header) {
             if (!is_array($header)) {
                 $csvRow[] = isset($row[$header]) ? $row[$header] : '';
             } else {
                 // Multi-row header, so we need to set all values
                 $nestedHeaderName = array_keys($header)[0];
                 $nestedHeaders = $header[$nestedHeaderName];
                 foreach ($nestedHeaders as $nestedHeader) {
                     $csvRow[] = isset($row[$nestedHeaderName][$nestedHeader]) ? $row[$nestedHeaderName][$nestedHeader] : '';
                 }
             }
         }
         fputcsv($handle, $csvRow);
         $file->next();
     }
     $file = null;
     // Get rid of the file handle that SplFileObject has on cache file
     unlink($cacheFile);
     fclose($handle);
     return $csvFile;
 }
Esempio n. 6
0
 /**
  * @param \SplFileObject $stream
  *
  * Reads the file to parse its lines
  */
 public function readFile(\SplFileObject $stream)
 {
     $stream->setFlags(\SplFileObject::READ_CSV | \SplFileObject::READ_AHEAD | \SplFileObject::SKIP_EMPTY | \SplFileObject::DROP_NEW_LINE);
     while (!$stream->eof()) {
         $this->parseLine($stream->current());
         $stream->next();
     }
     $stream = null;
 }
 public function actionIndex()
 {
     Yii::import("application.models.*");
     //get the latest idle cron job
     /* @var $latestidle JobQueue*/
     $latestidle = JobQueue::model()->findByAttributes(array("status" => JobQueue::$JOBQUEUE_STATUS_IDLE));
     if (!$latestidle) {
         echo "No file queued";
         die;
     }
     //set status to on-going
     $latestidle->status = JobQueue::$JOBQUEUE_STATUS_ON_GOING;
     $latestidle->save(false);
     //retrieve file
     $queueFile = new SplFileObject($latestidle->filename);
     //read file
     $queueFile->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
     $queueFile->next();
     // Total_records ,
     $queueFile->seek(PHP_INT_MAX);
     $linesTotal = $queueFile->key();
     $latestidle->total_records = $linesTotal;
     $latestidle->save(false);
     $index = 0;
     foreach ($queueFile as $currentLine) {
         //iterate content
         if ($queueFile->key() === 0) {
             continue;
         }
         //TODO: processed_record
         $latestidle->processed_record = ++$index;
         $latestidle->save(false);
         $currentMobile = $currentLine[0];
         $newBlackListedmobile = new BlackListedMobile();
         //cleaning time
         $currentMobile = trim($currentMobile);
         $currentMobile = rtrim($currentMobile);
         $currentMobile = ltrim($currentMobile);
         $newBlackListedmobile->mobile_number = $currentMobile;
         $newBlackListedmobile->queue_id = $latestidle->queue_id;
         //set queueid
         if ($newBlackListedmobile->save()) {
             //save content
             echo "{$newBlackListedmobile->mobile_number} : Saved \n";
         } else {
             echo "{$newBlackListedmobile->mobile_number} : Failed \n";
         }
     }
     //when done
     //set status to done
     $latestidle->status = JobQueue::$JOBQUEUE_STATUS_DONE;
     $latestidle->date_done = date("Y-m-d H:i:s");
     //set done datetime to now()
     $latestidle->save();
     echo "Queue DONE \n";
 }
Esempio n. 8
0
 public function rewind()
 {
     parent::rewind();
     // If we are getting the first line as columns, take them then skip to
     // the next line.
     if ($this->_firstLineIsColumns) {
         $this->setColumns(parent::current());
         parent::next();
     }
 }
Esempio n. 9
0
function generate($nb, $fixture = __DIR__ . '/fixtures/lorem.txt')
{
    $lorems = new SplFileObject($fixture, 'a+');
    $txt = '';
    while ($nb > 0 && $lorems->valid()) {
        $txt .= $lorems->current();
        $lorems->next();
        $nb--;
    }
    return $txt;
}
Esempio n. 10
0
 /**
  * @param $fileName
  * @param $page
  * @param $rows
  * @param string $methord
  * @return array
  */
 public static function getContents($fileName, $page, $rows, $methord = 'rb')
 {
     $content = array();
     $start = ($page - 1) * $rows;
     $fp = new \SplFileObject($fileName, $methord);
     $fp->seek($start);
     for ($i = 0; $i < $rows; ++$i) {
         $content[] = $fp->current();
         $fp->next();
     }
     return array_filter($content);
 }
Esempio n. 11
0
 public function getData()
 {
     try {
         $file = new SplFileObject($this->tmp_name, 'rb');
         $data = null;
         for ($file; $file->valid(); $file->next()) {
             $data .= $file->current();
         }
         return $data;
     } catch (RuntimeException $e) {
     }
     return null;
 }
Esempio n. 12
0
 public function testCheckAnswerTask3()
 {
     $this->assertFileExists('data/export.csv');
     $filecsv = new \SplFileObject('data/export.csv');
     $filecsv->setFlags(\SplFileObject::READ_CSV);
     $header = $filecsv->current();
     $processor = new YieldProcessor(ReaderFactory::create('Db\\Product', include 'config/database.php'), WriterFactory::create('Stub'), function () {
     });
     foreach ($processor->processing() as $item) {
         $filecsv->next();
         $this->assertEquals($item, array_combine($header, $filecsv->current()));
     }
 }
Esempio n. 13
0
 /**
  * Move forward to next element
  */
 public function next()
 {
     if (null === $this->_file) {
         $this->_openFile();
     }
     if ($this->_file) {
         $this->_key = $this->_key + 1;
         if (!$this->_file->eof()) {
             $this->_file->next();
             $this->_filepos = $this->_file->ftell();
         }
     }
 }
 public function testAgainstOriginalSedImplementation()
 {
     $tokenizer = new PennTreeBankTokenizer();
     $tokenized = new \SplFileObject(TEST_DATA_DIR . "/Tokenizers/PennTreeBankTokenizerTest/tokenized");
     $tokenized->setFlags(\SplFileObject::DROP_NEW_LINE);
     $sentences = new \SplFileObject(TEST_DATA_DIR . "/Tokenizers/PennTreeBankTokenizerTest/test.txt");
     $sentences->setFlags(\SplFileObject::DROP_NEW_LINE);
     $tokenized->rewind();
     foreach ($sentences as $sentence) {
         if ($sentence) {
             $this->assertEquals($tokenized->current(), implode(" ", $tokenizer->tokenize($sentence)), "Sentence: '{$sentence}' was not tokenized correctly");
         }
         $tokenized->next();
     }
 }
Esempio n. 15
0
 private function getClosureCode(\Closure $closure)
 {
     $reflection = new \ReflectionFunction($closure);
     // Open file and seek to the first line of the closure
     $file = new \SplFileObject($reflection->getFileName());
     $file->seek($reflection->getStartLine() - 1);
     // Retrieve all of the lines that contain code for the closure
     $code = '';
     while ($file->key() < $reflection->getEndLine()) {
         $line = $file->current();
         $line = ltrim($line);
         $code .= $line;
         $file->next();
     }
     return $code;
 }
Esempio n. 16
0
 function getMethodCode($name, $comment = false)
 {
     $fun = $this->getMethod($name);
     $start = $fun->getStartLine();
     $end = $fun->getEndLine();
     $fileName = $fun->getFileName();
     $file = new SplFileObject($fileName);
     $file->seek($start - 1);
     $i = 0;
     $str = $comment ? $fun->getDocComment() : '';
     while ($i++ < $end + 1 - $start) {
         $str .= $file->current();
         $file->next();
     }
     return $str;
 }
Esempio n. 17
0
 public static function setUpBeforeClass()
 {
     $reflection = new ReflectionClass(__NAMESPACE__ . '\\TestClass');
     self::$startLine = $reflection->getStartLine();
     self::$endLine = $reflection->getEndLine();
     self::$testClassCode = NULL;
     /* GetCode as String */
     $file = new \SplFileObject($reflection->getFileName());
     $file->seek(self::$startLine - 1);
     while ($file->key() < $reflection->getEndLine()) {
         self::$testClassCode .= $file->current();
         $file->next();
     }
     self::$testClassCode = rtrim(self::$testClassCode, "\n");
     unset($file);
 }
Esempio n. 18
0
 protected function _fetchCode()
 {
     // Open file and seek to the first line of the closure
     $file = new SplFileObject($this->reflection->getFileName());
     $file->seek($this->reflection->getStartLine() - 1);
     // Retrieve all of the lines that contain code for the closure
     $code = '';
     while ($file->key() < $this->reflection->getEndLine()) {
         $code .= $file->current();
         $file->next();
     }
     // Only keep the code defining that closure
     $begin = strpos($code, 'function');
     $end = strrpos($code, '}');
     $code = substr($code, $begin, $end - $begin + 1);
     return $code;
 }
Esempio n. 19
0
 /**
  * Move forward to next element
  */
 public function next()
 {
     if (null === $this->_file) {
         $this->_openFile();
     }
     if ($this->_file) {
         $this->_key = $this->_key + 1;
         while ($this->_file->valid()) {
             $this->_file->next();
             $this->_filepos = $this->_file->ftell();
             if ($this->_accept()) {
                 $this->_valid = true;
                 return;
             }
         }
     }
     $this->_valid = false;
 }
Esempio n. 20
0
/**
 * 获取程序文件的文件头注释的标题
 */
function getFileCommentTitle($filename, $startLine = 1, $endLine = 50, $method = 'rb')
{
    $ret = '';
    $count = $endLine - $startLine;
    $fp = new SplFileObject($filename, $method);
    $fp->seek($startLine - 1);
    // 转到第N行, seek方法参数从0开始计数
    for ($i = 0; $i <= $count; ++$i) {
        $currLineStr = $fp->current();
        // current()获取当前行内容
        if (preg_match('/s?\\*s?([^\\*]{3,})/', $currLineStr, $matches)) {
            return $matches[1];
        }
        $fp->next();
        // 下一行
    }
    return $ret;
}
Esempio n. 21
0
 private function displaySource(\Exception $e)
 {
     $source = '';
     $file = new \SplFileObject($e->getFile());
     $lineNum = $e->getLine() - 4;
     if ($lineNum < 1) {
         $lineNum = 1;
     }
     $file->seek($lineNum);
     for ($l = 0; $l < 8; $l++) {
         if ($file->eof()) {
             break;
         }
         $source .= $file->current();
         $file->next();
     }
     return $source;
 }
 /**
  * Evaluates the closure and the code in the reset of the file. This sets
  * the code for the closure, the namespace it is declared in (if any) and
  * any applicable namespace imports
  * @param ReflectionFunction The reflected function of the closure
  * @return String The code the closure runs 
  */
 private function evaluate(\ReflectionFunction $reflection)
 {
     $code = '';
     $full = '';
     $file = new \SplFileObject($reflection->getFileName());
     while (!$file->eof()) {
         if ($file->key() >= $reflection->getStartLine() - 1 && $file->key() < $reflection->getEndLine()) {
             $code .= $file->current();
         }
         $full .= $file->current();
         $file->next();
     }
     //@todo this assumes the function will be the only one on that line
     $begin = strpos($code, 'function');
     //@todo this assumes the } will be the only one on that line
     $end = strrpos($code, '}');
     $this->code = substr($code, $begin, $end - $begin + 1);
     $this->extractDetail($full);
 }
 /**
  * Get's the next string of hook code to process.
  *
  * @return string
  */
 public function getHook()
 {
     foreach ($this->hooks as $value) {
         $hook = '<?php function ' . $value[1] . '(){';
         $reflection = new \ReflectionFunction($value[2]);
         $file = new \SplFileObject($reflection->getFileName());
         $file->seek($reflection->getStartLine() - 1);
         $code = '';
         while ($file->key() < $reflection->getEndLine()) {
             $code .= $file->current();
             $file->next();
         }
         $begin = strpos($code, 'function') + 8;
         $begin = strrpos($code, '{', $begin) + 1;
         $end = strrpos($code, '}');
         $hook .= substr($code, $begin, $end - $begin);
         $hook .= '}' . PHP_EOL;
         (yield $value[0] => $hook);
     }
 }
Esempio n. 24
0
 /**
  * @param string $file
  * @param int    $start
  * @param int    $end
  *
  * @return string
  */
 private function extractLines($file, $start, $end)
 {
     $fileObject = new \SplFileObject($file);
     $fileObject->seek($start - 1);
     $whitespaceLength = null;
     $content = '';
     $iterator = $end - $start;
     while ($line = $fileObject->current()) {
         if ($whitespaceLength === null && preg_match('/^\\s*/', $line, $matches)) {
             $whitespaceLength = strlen($matches[0]);
         }
         $line = substr($line, $whitespaceLength);
         $content .= $line ?: PHP_EOL;
         $fileObject->next();
         $iterator--;
         if ($iterator < 0) {
             break;
         }
     }
     return trim($content);
 }
Esempio n. 25
0
function getFileLines($filename, $startLine = 1, $endLine = 50, $method = 'rb')
{
    $content = array();
    $count = $endLine - $startLine;
    $fp = new SplFileObject($filename, $method);
    $fp->seek($startLine - 1);
    // 转到第N行, seek方法参数从0开始计数
    for ($i = 0; $i <= $count; ++$i) {
        $content[] = $fp->current();
        // current()获取当前行内容
        $fp->next();
        // 下一行
    }
    array_filter($content);
    // array_filter过滤:false,null,''
    $str = "";
    foreach ($content as $v) {
        $str .= $v . "\n";
    }
    return $str;
}
Esempio n. 26
0
 public function parseFile($logFile, &$startId, $finish = false)
 {
     if (!$logFile || !file_exists($logFile)) {
         return $this->setError('Log file error');
     }
     try {
         $file = new SplFileObject($logFile);
         $file->seek(!$startId ? 0 : $startId - 1);
         $counter = 0;
         $items = array();
         $item = null;
         while ($file->valid()) {
             $row = trim($file->current());
             $file->next();
             if (!$row) {
                 continue;
             }
             $item = Mage::getModel('mpbackup/backup_progress_item')->parse($row, $item);
             $items[] = $item;
             $counter += $item->getLength();
             if (!$finish && $counter > Mageplace_Backup_Helper_Const::BACKUP_PROCESS_REQUEST_PERIOD * Mageplace_Backup_Helper_Const::BACKUP_PROCESS_RESPONSE_SIZE) {
                 break;
             }
         }
         $startId = $file->key();
     } catch (Exception $e) {
         Mage::logException($e);
         return $this->setError($e->getMessage());
     }
     if (empty($items)) {
         if ($finish) {
             return $this->setError('Log is empty (' . print_r($items, true) . ') and log process is finished');
         } else {
             return $this->setData(self::TEXT, self::TEXT_TREE_POINT)->setError(print_r($items, true));
         }
     }
     return $this->setData(self::ITEMS, $items);
 }
Esempio n. 27
0
 /**
  * Read a key from the cache
  *
  * @param string $key Identifier for the data
  * @return mixed The cached data, or false if the data doesn't exist, has
  *   expired, or if there was an error fetching it
  */
 public function read($key)
 {
     $key = $this->_key($key);
     if (!$this->_init || $this->_setKey($key) === false) {
         return false;
     }
     if ($this->_config['lock']) {
         $this->_File->flock(LOCK_SH);
     }
     $this->_File->rewind();
     $time = time();
     $cachetime = (int) $this->_File->current();
     if ($cachetime !== false && ($cachetime < $time || $time + $this->_config['duration'] < $cachetime)) {
         if ($this->_config['lock']) {
             $this->_File->flock(LOCK_UN);
         }
         return false;
     }
     $data = '';
     $this->_File->next();
     while ($this->_File->valid()) {
         $data .= $this->_File->current();
         $this->_File->next();
     }
     if ($this->_config['lock']) {
         $this->_File->flock(LOCK_UN);
     }
     $data = trim($data);
     if ($data !== '' && !empty($this->_config['serialize'])) {
         if ($this->_config['isWindows']) {
             $data = str_replace('\\\\\\\\', '\\', $data);
         }
         $data = unserialize((string) $data);
     }
     return $data;
 }
Esempio n. 28
0
 public function read($key)
 {
     if (!$this->is_init || $this->_openFile($key) === false) {
         return false;
     }
     if ($this->settings['lock']) {
         $this->file->flock(LOCK_SH);
     }
     $this->file->rewind();
     $time = time();
     $cachetime = intval($this->file->current());
     //check for expiry
     if ($cachetime !== false && ($cachetime < $time || $time + $this->settings['cache_duration'] < $cachetime)) {
         if ($this->settings['lock']) {
             $this->file->flock(LOCK_UN);
         }
         return false;
     }
     $data = '';
     $this->file->next();
     while ($this->file->valid()) {
         $data .= $this->file->current();
         $this->file->next();
     }
     if ($this->settings['lock']) {
         $this->file->flock(LOCK_UN);
     }
     $data = trim($data);
     if ($data !== '' && !empty($this->settings['serialize'])) {
         if ($this->settings['is_windows']) {
             $data = str_replace('\\\\\\\\', '\\', $data);
         }
         $data = json_decode((string) $data, TRUE);
     }
     return $data;
 }
Esempio n. 29
0
 /**
  *	create_generic()
  *	
  *	A function that creates an archive file
  *	
  *	The $excludes will be a list or relative path excludes if the $listmaker object is NULL otehrwise
  *	will be absolute path excludes and relative path excludes can be had from the $listmaker object
  *	
  *	@param		string	$zip			Full path & filename of ZIP Archive file to create
  *	@param		string	$dir			Full path of directory to add to ZIP Archive file
  *	@parame		array	$excludes		List of either absolute path exclusions or relative exclusions
  *	@param		string	$tempdir		[Optional] Full path of directory for temporary usage
  *	@param		object	$listmaker		The object from which we can get an inclusions list
  *	@return		bool					True if the creation was successful, false otherwise
  *
  */
 protected function create_generic($zip, $dir, $excludes, $tempdir, $listmaker)
 {
     $exitcode = 0;
     $output = array();
     $zippath = '';
     $command = '';
     $temp_zip = '';
     $excluding_additional = false;
     $exclude_count = 0;
     $exclusions = array();
     $have_zip_errors = false;
     $zip_errors_count = 0;
     $zip_errors = array();
     $have_zip_warnings = false;
     $zip_warnings_count = 0;
     $zip_warnings = array();
     $have_zip_additions = false;
     $zip_additions_count = 0;
     $zip_additions = array();
     $have_zip_debug = false;
     $zip_debug_count = 0;
     $zip_debug = array();
     $have_zip_other = false;
     $zip_other_count = 0;
     $zip_other = array();
     $zip_using_log_file = false;
     $logfile_name = '';
     $zip_ignoring_symlinks = false;
     // The basedir must have a trailing directory separator
     $basedir = rtrim(trim($dir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
     if (empty($tempdir) || !@file_exists($tempdir)) {
         pb_backupbuddy::status('details', __('Temporary working directory must be available.', 'it-l10n-backupbuddy'));
         return false;
     }
     // Tell which zip version is being used
     $version = $this->get_zip_version();
     if (true === is_array($version)) {
         2 == $version['major'] && 0 == $version['minor'] ? $version['minor'] = 'X' : true;
         pb_backupbuddy::status('details', sprintf(__('Using zip version: %1$s.%2$s', 'it-l10n-backupbuddy'), $version['major'], $version['minor']));
     } else {
         $version = array("major" => "X", "minor" => "Y");
         pb_backupbuddy::status('details', sprintf(__('Using zip version: %1$s.%2$s', 'it-l10n-backupbuddy'), $version['major'], $version['minor']));
     }
     // Get the command path for the zip command - should return a trimmed string
     $zippath = $this->get_command_path(self::COMMAND_ZIP_PATH);
     // Determine if we are using an absolute path
     if (!empty($zippath)) {
         pb_backupbuddy::status('details', __('Using absolute zip path: ', 'it-l10n-backupbuddy') . $zippath);
     }
     // Add the trailing slash if required
     $command = $this->slashify($zippath) . 'zip';
     // Always do recursive operation
     $command .= ' -r';
     // Check if the version of zip in use supports log file (which will help with memory usage for large sites)
     if (true === $this->get_zip_supports_log_file()) {
         // Choose to use log file so quieten stdout - we'll set up the log file later
         $command .= ' -q';
         $zip_using_log_file = true;
     }
     // Check if we need to turn off compression by settings (faster but larger backup)
     if (true !== $this->get_compression()) {
         $command .= ' -0';
         pb_backupbuddy::status('details', __('Zip archive creation compression disabled based on settings.', 'it-l10n-backupbuddy'));
     } else {
         pb_backupbuddy::status('details', __('Zip archive creation compression enabled based on settings.', 'it-l10n-backupbuddy'));
     }
     // Check if ignoring (not following) symlinks
     if (true === $this->get_ignore_symlinks()) {
         // Not all OS support this for command line zip but best to handle it late and just
         // indicate here it is requested but not supported by OS
         switch ($this->get_os_type()) {
             case self::OS_TYPE_NIX:
                 // Want to not follow symlinks so set command option and set flag for later use
                 $command .= ' -y';
                 $zip_ignoring_symlinks = true;
                 pb_backupbuddy::status('details', __('Zip archive creation symbolic links will not be followed based on settings.', 'it-l10n-backupbuddy'));
                 break;
             case self::OS_TYPE_WIN:
                 pb_backupbuddy::status('details', __('Zip archive creation symbolic links requested to not be followed based on settings but this option is not supported on this operating system.', 'it-l10n-backupbuddy'));
                 break;
             default:
                 pb_backupbuddy::status('details', __('Zip archive creation symbolic links requested to not be followed based on settings but this option is not supported on this operating system.', 'it-l10n-backupbuddy'));
         }
     } else {
         pb_backupbuddy::status('details', __('Zip archive creation symbolic links will be followed based on settings.', 'it-l10n-backupbuddy'));
     }
     // Check if we are ignoring warnings - meaning can still get a backup even
     // if, e.g., some files cannot be read
     if (true === $this->get_ignore_warnings()) {
         // Note: warnings are being ignored but will still be gathered and logged
         pb_backupbuddy::status('details', __('Zip archive creation actionable warnings will be ignored based on settings.', 'it-l10n-backupbuddy'));
     } else {
         pb_backupbuddy::status('details', __('Zip archive creation actionable warnings will not be ignored based on settings.', 'it-l10n-backupbuddy'));
     }
     // Delete any existing zip file of same name - really this should never happen
     if (@file_exists($zip)) {
         pb_backupbuddy::status('details', __('Existing ZIP Archive file will be replaced.', 'it-l10n-backupbuddy'));
         @unlink($zip);
     }
     // Now we'll set up the logging to file if required - use full logging
     if (true === $zip_using_log_file) {
         $logfile_name = $tempdir . self::ZIP_LOG_FILE_NAME;
         $command .= " -lf '{$logfile_name}' -li";
     }
     // Set temporary directory to store ZIP while it's being generated.
     $command .= " -b '{$tempdir}'";
     // Specify where to place the finalized zip archive file
     // If warnings are being ignored we can tell zip to create the zip archive in the final
     // location - otherwise we must put it in a temporary location and move it later only
     // if there are no warnings. This copes with the case where (this) controlling script
     // gets timed out by the server and if the file were created in the final location with
     // warnings that should not be ignored we cannot prevent it being created. The -MM option
     // could be used but this prevents us catching such warnings and being able to report
     // them to the user in the case where the script hasn't been terminated. Additionally the
     // -MM option would bail out on the first encountered problem and so if there were a few
     // problems they would each not be found until the current one is fixed and try again.
     if (true === $this->get_ignore_warnings()) {
         $temp_zip = $zip;
     } else {
         $temp_zip = $tempdir . basename($zip);
     }
     $command .= " '{$temp_zip}' .";
     // Now work out exclusions dependent on what we have been given
     if (is_object($listmaker) && (defined('USE_EXPERIMENTAL_ZIPBUDDY_INCLUSION') && true === USE_EXPERIMENTAL_ZIPBUDDY_INCLUSION)) {
         // We're doing an inclusion operation, but first we'll just show the exclusiosn
         // For zip we need relative rather than absolute exclusion spaths
         $exclusions = $listmaker->get_relative_excludes($basedir);
         if (count($exclusions) > 0) {
             pb_backupbuddy::status('details', __('Calculating directories to exclude from backup.', 'it-l10n-backupbuddy'));
             $excluding_additional = false;
             $exclude_count = 0;
             foreach ($exclusions as $exclude) {
                 if (!strstr($exclude, 'backupbuddy_backups')) {
                     // Set variable to show we are excluding additional directories besides backup dir.
                     $excluding_additional = true;
                 }
                 pb_backupbuddy::status('details', __('Excluding', 'it-l10n-backupbuddy') . ': ' . $exclude);
                 $exclude_count++;
             }
         }
         // Get the list of inclusions to process
         $inclusions = $listmaker->get_terminals();
         // For each directory we need to put the "wildcard" on the end
         foreach ($inclusions as &$inclusion) {
             if (is_dir($inclusion)) {
                 $inclusion .= DIRECTORY_SEPARATOR . "*";
             }
             // Remove directory path prefix excluding leading slash to make relative (needed for zip)
             $inclusion = str_replace(rtrim($basedir, DIRECTORY_SEPARATOR), '', $inclusion);
         }
         // Now create the inclusions file in the tempdir
         // And update the command options
         $ifile = $tempdir . self::ZIP_INCLUSIONS_FILE_NAME;
         if (file_exists($ifile)) {
             @unlink($ifile);
         }
         file_put_contents($ifile, implode(PHP_EOL, $inclusions) . PHP_EOL . PHP_EOL);
         $command .= " -i@" . "'{$ifile}'";
     } else {
         // We're doing an exclusion operation
         //$command .= "-i '*' "; // Not needed. Zip defaults to doing this. Removed July 10, 2012 for v3.0.41.
         // Since we had no $listmaker object or not using it get the standard relative excludes to process
         $exclusions = $excludes;
         if (count($exclusions) > 0) {
             // Handle exclusions by placing them in an exclusion text file.
             $exclusion_file = $tempdir . self::ZIP_EXCLUSIONS_FILE_NAME;
             $this->_render_exclusions_file($exclusion_file, $exclusions);
             pb_backupbuddy::status('details', sprintf(__('Using exclusion file `%1$s`', 'it-l10n-backupbuddy'), $exclusion_file));
             $command .= ' -x@' . "'{$exclusion_file}'";
         }
     }
     // If we can't use a log file but exec_dir isn't in use we can redirect stderr to stdout
     // If exec_dir is in use we cannot redirect because of command line escaping so cannot log errors/warnings
     if (false === $zip_using_log_file) {
         if (false === $this->get_exec_dir_flag()) {
             $command .= ' 2>&1';
         } else {
             pb_backupbuddy::status('details', sprintf(__('Zip Errors/Warnings cannot not be logged with this version of zip and exec_dir active', 'it-l10n-backupbuddy'), true));
         }
     }
     // Remember the current directory and change to the directory being added so that "." is valid in command
     $working_dir = getcwd();
     chdir($dir);
     $command = self::OS_TYPE_WIN === $this->get_os_type() ? str_replace('\'', '"', $command) : $command;
     pb_backupbuddy::status('details', $this->get_method_tag() . __(' command', 'it-l10n-backupbuddy') . ': ' . $command);
     @exec($command, $output, $exitcode);
     // Set current working directory back to where we were
     chdir($working_dir);
     // Convenience for handling different scanarios
     $result = false;
     // If we used a log file then process the log file - else process output
     // Always scan the output/logfile for warnings, etc. and show warnings even if user has chosen to ignore them
     if (true === $zip_using_log_file) {
         try {
             $logfile = new SplFileObject($logfile_name, "rb");
             while (!$logfile->eof()) {
                 $line = $logfile->current();
                 $id = $logfile->key();
                 // Use the line number as unique key for later sorting
                 $logfile->next();
                 if (preg_match('/^\\s*(zip warning:)/i', $line)) {
                     // Looking for specific types of warning - in particular want the warning that
                     // indicates a file couldn't be read as we want to treat that as a "skipped"
                     // warning that indicates that zip flagged this as a potential problem but
                     // created the zip file anyway - but it would have generated the non-zero exit
                     // code of 18 and we key off that later. All other warnings are not considered
                     // reasons to return a non-zero exit code whilst still creating a zip file so
                     // we'll follow the lead on that and not have other warning types halt the backup.
                     // So we'll try and look for a warning output that looks like it is file related...
                     if (preg_match('/^\\s*(zip warning:)\\s*([^:]*:)\\s*(.*)/i', $line, $matches)) {
                         // Matched to what looks like a file related warning so check particular cases
                         switch (strtolower($matches[2])) {
                             case "could not open for reading:":
                                 $zip_warnings[self::ZIP_WARNING_SKIPPED][$id] = trim($line);
                                 $zip_warnings_count++;
                                 break;
                             case "name not matched:":
                                 $zip_other[self::ZIP_OTHER_GENERIC][$id] = trim($line);
                                 $zip_other_count++;
                                 break;
                             default:
                                 $zip_warnings[self::ZIP_WARNING_GENERIC][$id] = trim($line);
                                 $zip_warnings_count++;
                         }
                     } else {
                         // Didn't match to what would look like a file related warning so count it regardless
                         $zip_warnings[self::ZIP_WARNING_GENERIC][$id] = trim($line);
                         $zip_warnings_count++;
                     }
                 } elseif (preg_match('/^\\s*(zip error:)/i', $line)) {
                     $zip_errors[$id] = trim($line);
                     $zip_errors_count++;
                 } elseif (preg_match('/^\\s*(adding:)/i', $line)) {
                     // Currently not processing additions entried
                     //$zip_additions[] = trim( $line );
                     //$zip_additions_count++;
                 } elseif (preg_match('/^\\s*(sd:)/i', $line)) {
                     $zip_debug[$id] = trim($line);
                     $zip_debug_count++;
                 } else {
                     // Currently not processing other entries
                     //$zip_other[] = trim( $line );
                     //$zip_other_count++;
                 }
             }
             unset($logfile);
             @unlink($logfile_name);
         } catch (Exception $e) {
             // Something fishy - we should have been able to open the log file...
             $error_string = $e->getMessage();
             pb_backupbuddy::status('details', sprintf(__('Log file could not be opened - error reported: %1$s', 'it-l10n-backupbuddy'), $error_string));
         }
     } else {
         // TODO: $output could be large so if we parse it all into separate arrays then may want to shift
         // out each line and then discard it after copied to another array
         $id = 0;
         // Create a unique key (like a line number) for later sorting
         foreach ($output as $line) {
             if (preg_match('/^\\s*(zip warning:)/i', $line)) {
                 // Looking for specific types of warning - in particular want the warning that
                 // indicates a file couldn't be read as we want to treat that as a "skipped"
                 // warning that indicates that zip flagged this as a potential problem but
                 // created the zip file anyway - but it would have generated the non-zero exit
                 // code of 18 and we key off that later. All other warnings are not considered
                 // reasons to return a non-zero exit code whilst still creating a zip file so
                 // we'll follow the lead on that and not have other warning types halt the backup.
                 // So we'll try and look for a warning output that looks like it is file related...
                 if (preg_match('/^\\s*(zip warning:)\\s*([^:]*:)\\s*(.*)/i', $line, $matches)) {
                     // Matched to what looks like a file related warning so check particular cases
                     switch (strtolower($matches[2])) {
                         case "could not open for reading:":
                             $zip_warnings[self::ZIP_WARNING_SKIPPED][$id++] = trim($line);
                             $zip_warnings_count++;
                             break;
                         case "name not matched:":
                             $zip_other[self::ZIP_OTHER_GENERIC][$id++] = trim($line);
                             $zip_other_count++;
                             break;
                         default:
                             $zip_warnings[self::ZIP_WARNING_GENERIC][$id++] = trim($line);
                             $zip_warnings_count++;
                     }
                 } else {
                     // Didn't match to what would look like a file related warning so count it regardless
                     $zip_warnings[self::ZIP_WARNING_GENERIC][$id++] = trim($line);
                     $zip_warnings_count++;
                 }
             } elseif (preg_match('/^\\s*(zip error:)/i', $line)) {
                 $zip_errors[$id++] = trim($line);
                 $zip_errors_count++;
             } elseif (preg_match('/^\\s*(adding:)/i', $line)) {
                 // Currently not processing additions entried
                 //$zip_additions[] = trim( $line );
                 //$zip_additions_count++;
                 $id++;
             } elseif (preg_match('/^\\s*(sd:)/i', $line)) {
                 $zip_debug[$id++] = trim($line);
                 $zip_debug_count++;
             } else {
                 // Currently not processing other entries
                 //$zip_other[] = trim( $line );
                 //$zip_other_count++;
                 $id++;
             }
         }
         // Now free up the memory...
         unset($output);
     }
     // Set convenience flags
     $have_zip_warnings = 0 < $zip_warnings_count;
     $have_zip_errors = 0 < $zip_errors_count;
     $have_zip_additions = 0 < $zip_additions_count;
     $have_zip_debug = 0 < $zip_debug_count;
     $have_zip_other = 0 < $zip_other_count;
     // Always report the exit code regardless of whether we might ignore it or not
     pb_backupbuddy::status('details', __('Zip process exit code: ', 'it-l10n-backupbuddy') . $exitcode);
     // Always report the number of warnings - even just to confirm that we didn't have any
     pb_backupbuddy::status('details', sprintf(__('Zip process reported: %1$s warning%2$s', 'it-l10n-backupbuddy'), $zip_warnings_count, 1 == $zip_warnings_count ? '' : 's'));
     // Always report warnings regardless of whether user has selected to ignore them
     if (true === $have_zip_warnings) {
         $this->log_zip_reports($zip_warnings, self::$_warning_desc, "WARNING", self::MAX_WARNING_LINES_TO_SHOW, dirname(dirname($tempdir)) . DIRECTORY_SEPARATOR . 'pb_backupbuddy' . DIRECTORY_SEPARATOR . self::ZIP_WARNINGS_FILE_NAME);
     }
     // Always report other reports regardless
     if (true === $have_zip_other) {
         // Only report number of informationals if we have any as they are not that important
         pb_backupbuddy::status('details', sprintf(__('Zip process reported: %1$s information%2$s', 'it-l10n-backupbuddy'), $zip_other_count, 1 == $zip_other_count ? 'al' : 'als'));
         $this->log_zip_reports($zip_other, self::$_other_desc, "INFORMATION", self::MAX_OTHER_LINES_TO_SHOW, dirname(dirname($tempdir)) . DIRECTORY_SEPARATOR . 'pb_backupbuddy' . DIRECTORY_SEPARATOR . self::ZIP_OTHERS_FILE_NAME);
     }
     // See if we can figure out what happened - note that $exitcode could be non-zero for actionable warning(s) or error
     // if ( (no zip file) or (fatal exit code) or (not ignoring warnable exit code) )
     // TODO: Handle condition testing with function calls based on mapping exit codes to exit type (fatal vs non-fatal)
     if (!@file_exists($temp_zip) || 0 != $exitcode && 18 != $exitcode || 18 == $exitcode && !$this->get_ignore_warnings()) {
         // If we have any zip errors reported show them regardless
         if (true === $have_zip_errors) {
             pb_backupbuddy::status('details', sprintf(__('Zip process reported: %1$s error%2$s', 'it-l10n-backupbuddy'), $zip_errors_count, 1 == $zip_errors_count ? '' : 's'));
             foreach ($zip_errors as $line) {
                 pb_backupbuddy::status('details', __('Zip process reported: ', 'it-l10n-backupbuddy') . $line);
             }
         }
         // Report whether or not the zip file was created (whether that be in the final or temporary location)
         if (!@file_exists($temp_zip)) {
             pb_backupbuddy::status('details', __('Zip Archive file not created - check process exit code.', 'it-l10n-backupbuddy'));
         } else {
             pb_backupbuddy::status('details', __('Zip Archive file created but with errors/actionable-warnings so will be deleted - check process exit code and warnings.', 'it-l10n-backupbuddy'));
         }
         // The operation has failed one way or another. Note that as the user didn't choose to ignore errors the zip file
         // is always created in a temporary location and then only moved to final location on success without error or warnings.
         // Therefore if there is a zip file (produced but with warnings) it will not be visible and will be deleted when the
         // temporary directory is deleted below.
         $result = false;
     } else {
         // Got file with no error or warnings _or_ with warnings that the user has chosen to ignore
         if (false === $this->get_ignore_warnings()) {
             // Because not ignoring warnings the zip archive was built in temporary location so we need to move it
             pb_backupbuddy::status('details', __('Moving Zip Archive file to local archive directory.', 'it-l10n-backupbuddy'));
             // Make sure no stale file information
             clearstatcache();
             @rename($temp_zip, $zip);
             if (@file_exists($zip)) {
                 pb_backupbuddy::status('details', __('Zip Archive file moved to local archive directory.', 'it-l10n-backupbuddy'));
                 pb_backupbuddy::status('message', __('Zip Archive file successfully created with no errors or actionable warnings.', 'it-l10n-backupbuddy'));
                 $this->log_archive_file_stats($zip);
                 $result = true;
             } else {
                 pb_backupbuddy::status('details', __('Zip Archive file could not be moved to local archive directory.', 'it-l10n-backupbuddy'));
                 $result = false;
             }
         } else {
             // Warnings were being ignored so built in final location so no need to move it
             if (@file_exists($zip)) {
                 pb_backupbuddy::status('message', __('Zip Archive file successfully created with no errors (any actionable warnings ignored by user settings).', 'it-l10n-backupbuddy'));
                 $this->log_archive_file_stats($zip);
                 $result = true;
             } else {
                 // Odd condition - file should be present but apparently not?
                 pb_backupbuddy::status('details', __('Zip Archive file could not be found in local archive directory.', 'it-l10n-backupbuddy'));
                 $result = false;
             }
         }
     }
     // Cleanup the temporary directory that will have all detritus and maybe incomplete zip file
     pb_backupbuddy::status('details', __('Removing temporary directory.', 'it-l10n-backupbuddy'));
     if (!$this->delete_directory_recursive($tempdir)) {
         pb_backupbuddy::status('details', __('Temporary directory could not be deleted: ', 'it-l10n-backupbuddy') . $tempdir);
     }
     return $result;
 }
Esempio n. 30
0
 private static function read_source_file($filename, $lineno, $context_lines = 5)
 {
     $frame = array('prefix' => array(), 'line' => '', 'suffix' => array(), 'filename' => $filename, 'lineno' => $lineno);
     if ($filename === null || $lineno === null) {
         return $frame;
     }
     // Code which is eval'ed have a modified filename.. Extract the
     // correct filename + linenumber from the string.
     $matches = array();
     $matched = preg_match("/^(.*?)\\((\\d+)\\) : eval\\(\\)'d code\$/", $filename, $matches);
     if ($matched) {
         $frame['filename'] = $filename = $matches[1];
         $frame['lineno'] = $lineno = $matches[2];
     }
     // In the case of an anonymous function, the filename is sent as:
     // "</path/to/filename>(<lineno>) : runtime-created function"
     // Extract the correct filename + linenumber from the string.
     $matches = array();
     $matched = preg_match("/^(.*?)\\((\\d+)\\) : runtime-created function\$/", $filename, $matches);
     if ($matched) {
         $frame['filename'] = $filename = $matches[1];
         $frame['lineno'] = $lineno = $matches[2];
     }
     try {
         $file = new SplFileObject($filename);
         $target = max(0, $lineno - ($context_lines + 1));
         $file->seek($target);
         $cur_lineno = $target + 1;
         while (!$file->eof()) {
             $line = rtrim($file->current(), "\r\n");
             if ($cur_lineno == $lineno) {
                 $frame['line'] = $line;
             } elseif ($cur_lineno < $lineno) {
                 $frame['prefix'][] = $line;
             } elseif ($cur_lineno > $lineno) {
                 $frame['suffix'][] = $line;
             }
             $cur_lineno++;
             if ($cur_lineno > $lineno + $context_lines) {
                 break;
             }
             $file->next();
         }
     } catch (RuntimeException $exc) {
         return $frame;
     }
     return $frame;
 }