Exemple #1
0
 public function toPhp(array &$context = array())
 {
     if (!$this->isActive()) {
         return '';
     }
     $php = '';
     if (!$this->getFile() && !$this->getFilesets()) {
         SystemEvent::raise(SystemEvent::ERROR, 'No source files set for task copy.', __METHOD__);
         return false;
     }
     if (!$this->getToFile() && !$this->getToDir()) {
         SystemEvent::raise(SystemEvent::ERROR, 'No destination set for task copy.', __METHOD__);
         return false;
     }
     $php .= "\n\$GLOBALS['result']['task'] = 'copy';\n\$baseToFilename = '';\n";
     if ($this->getToFile()) {
         $php .= "\n\$path = pathinfo(expandStr('{$this->getToFile()}'));\n\$baseToDir = \$path['dirname'];\n\$baseToFilename = '/' . \$path['basename']; // pathinfo's dirname *always* returns the dirname without the trailing slash.\n";
     } elseif ($this->getToDir()) {
         $php .= "\n\$baseToDir = expandStr('{$this->getToDir()}');\n";
     }
     //
     // TODO: Potential bug here. If the following generated mkdir does
     // indeed fail and failOnError == true, the execution will continue
     // because we are not returning true... A return true here would
     // halt the generated script execution (that's what return false does
     // in case of error...)
     //
     // Wrapping this whole element into a generated auto-executing closure
     // a la Javascript would be awesome, because that way we could just
     // force a return and not risk shutting down the whole builder script
     //
     $php .= "\nif (!file_exists(\$baseToDir) && !@mkdir(\$baseToDir, 0755, true)) {\n  output(\"Failed creating dir \$baseToDir.\");\n\tif ({$this->getFailOnError()}) {\n    \$GLOBALS['result']['ok'] = false;\n    return false;\n  } else {\n\t  \$GLOBALS['result']['ok'] = \$GLOBALS['result']['ok'] & true;\n  }\n}";
     //
     // Internally treat $this->getFile() as a fileset.
     //
     $filesets = array();
     if ($this->getFile()) {
         $getFile = self::_expandStr($this->getFile(), $context);
         $pathFrom = pathinfo($getFile);
         $fileset = new Build_BuilderElement_Type_Fileset();
         if (!file_exists($getFile)) {
             $php .= "\noutput(\"No such file or directory {$getFile}.\");\nif ({$this->getFailOnError()}) { // failonerror\n  \$GLOBALS['result']['ok'] = false;\n  return false;\n} else {\n  \$GLOBALS['result']['ok'] = \$GLOBALS['result']['ok'] & true;\n}\n";
         } elseif (is_file($getFile)) {
             $fileset->addInclude($pathFrom['basename']);
             $fileset->setDir($pathFrom['dirname']);
             $fileset->setType(Build_BuilderElement_Type_Fileset::FILE);
             $php .= "\n\$baseFromDir = '{$pathFrom['dirname']}';\n";
         } else {
             // It's a directory
             $fileset->addInclude('**/*');
             $fileset->setDir($getFile);
             $fileset->setType(Build_BuilderElement_Type_Fileset::BOTH);
             // Very important default!!!
             $php .= "\n\$baseFromDir = '{$getFile}';\n";
         }
         $filesets[] = $fileset;
     } elseif ($this->getFilesets()) {
         // If file exists, it takes precedence over filesets
         $realFilesets = $this->getFilesets();
         // Not to be overwritten
         if (!$realFilesets[0]->getDir() || !$realFilesets[0]->getInclude()) {
             SystemEvent::raise(SystemEvent::ERROR, 'No source files set for task copy.', __METHOD__);
             return false;
         }
         // Iterator mode for copy() must enforce parent dirs before their children,
         // so that we can mkdir the parent without first trying to copy in the children
         // on a non-existing dir.
         $fileset = new Build_BuilderElement_Type_Fileset();
         $fileset->setDir(self::_expandStr($realFilesets[0]->getDir(), $context));
         $fileset->setInclude(explode(' ', self::_expandStr(implode(' ', $realFilesets[0]->getInclude()), $context)));
         $fileset->setExclude(explode(' ', self::_expandStr(implode(' ', $realFilesets[0]->getExclude()), $context)));
         $filesets[] = $fileset;
         $php .= "\n\$baseFromDir = '{$fileset->getDir()}';\n";
     }
     $php .= "\n\$callback = function (\$entry) use (\$baseToDir, \$baseFromDir, \$baseToFilename) {\n  \$dest = \$baseToDir . (!empty(\$baseToFilename)?\$baseToFilename:substr(\$entry, strlen(\$baseFromDir)));\n  if (is_file(\$entry)) {\n    \$ret = @copy(\$entry, \$dest);\n  } elseif (is_dir(\$entry)) {\n  \tif (!file_exists(\$dest) && !@mkdir(\$dest, 0755, true)) {\n  \t  \$ret = false;\n  \t} else {\n  \t  \$ret = true;\n    }\n  } else {\n    \$ret = false;\n  }\n  if (!\$ret) {\n    output(\"Failed copy of \$entry to \$dest.\");\n  } else {\n    output(\"Copied \$entry to \$dest.\");\n  }\n  return \$ret;\n};\n";
     $context['iteratorMode'] = RecursiveIteratorIterator::SELF_FIRST;
     // Make sure dirs come before their children, in order to be created first
     foreach ($filesets as $fileset) {
         $php .= "\n" . $fileset->toPhp($context) . "\nif (!fileset{$fileset->getId()}_{$context['id']}(\$callback) && {$this->getFailOnError()}) {\n  \$GLOBALS['result']['ok'] = false;\n  return false;\n} else {\n  \$GLOBALS['result']['ok'] = \$GLOBALS['result']['ok'] & true;\n}\n";
     }
     return $php;
 }