protected function hash($fqn, $uniqueData) { asort($uniqueData); return $fqn . '__' . A::implode($uniqueData, ',', function ($value, $field) { return $field . ':' . $value; }); }
public function run() { if (!isset($this->changes) || !is_array($this->changes)) { throw new \InvalidArgumentException('changes muss gesetzt sein'); } if (!$this->changelog->exists()) { throw new \RuntimeException('changelogFile ' . $targetFile . ' muss existieren'); } require $this->changelog; /* changeslist : 'bugfix: Im Sound Content stand nur "content" statt dem eigentlichen Soundtext', 'geändert: Bei der Soundsuche wird bei sehr großen Results das Ergebnis auf 15 Einträge eingeschränkt' */ /* version */ //2.0.9-Beta $version = \Psc\Preg::qmatch($data[0]['version'], '/^([0-9]+)\\.([0-9]+)\\.([0-9]+)\\-(Alpha|Beta|Gamma)$/i', array(1, 2, 3, 4)); if (!is_array($version)) { throw new \RuntimeException('Fehler beim Version Parsing. Alte Version ' . $oldVersion); } if ($this->versionIncrement === 'minor') { $version[2]++; } else { throw new \InvalidArgumentException('Kann nichts anderes als minor für versionIncrement'); } $newVersion = vsprintf('%d.%d.%d-%s', $version); $php = <<<'PHP' $data[] = array( 'version'=>'%version%', 'time'=>'%time%', 'changelog'=>array( %changesList% ) ); PHP; $php = \Psc\TPL\TPL::miniTemplate($php, array('version' => $newVersion, 'time' => date('H:i d.m.Y'), 'changesList' => \Webforge\Common\ArrayUtil::implode($this->changes, ",\n ", function ($change) { return var_export($change, true); }))); $contents = $this->changelog->getContents(); $pos = mb_strpos($contents, $needle = '$data = array();' . "\n"); if ($pos === FALSE) { throw new \RuntimeException('Cannot Modify File: ' . \Webforge\Common\String::cutAt($contents, 300) . ' enhält nicht ' . $needle); } $pos += mb_strlen($needle); $contents = mb_substr($contents, 0, $pos) . $php . "\n" . mb_substr($contents, $pos); $this->changelog->writeContents($contents); }
/** * @var mixed $print Closure|String wenn ein String wird dies als Attribute gesehen welches mit get$print() vom Objekt geladen werden kann */ public static function listStrings($collection, $sep = ', ', $andsep = NULL, Closure $formatter = NULL) { $collection = Code::castArray($collection); $cnt = count($collection); if (isset($andsep) && $cnt >= 2) { $last = array_pop($collection); } else { $andsep = NULL; } $formatter = $formatter ?: function ($item) { return (string) $item; }; $ret = A::implode($collection, $sep, $formatter); if (isset($andsep) && $last != NULL) { $ret .= $andsep . $formatter($last); } return $ret; }
protected function compileClosure(GMethod $method, $closureName) { // wir erzeugen sowas hier (ohne semikolon am ende) /* parameter von $funcName sind $name und $type $funcName = function ($name, $type) use ($that) { return $that->funcName($name, $type); } */ $code = <<<'PHP' $%closureName% = function (%parameters%) use ($that) { return $that->%method%(%callParameters%); } PHP; $codeWithFuncArgs = <<<'PHP' $%closureName% = function () use ($that) { return call_user_func_array(array($that, '%method%'), func_get_args()); } PHP; // wenn die innere funktion func_get_args() benutzt, müssen wir call_user_func nehmen ($codeWithFuncArgs) if (mb_strpos($method->getBody(), 'func_get_args()')) { // das ist natürlich nicht so schön als entscheidung, aber false positive macht nichts (außer bissl performance) $code = $codeWithFuncArgs; $parameters = $callParameters = NULL; } else { // kopiert von GFunction $parameters = \Webforge\Common\ArrayUtil::implode($method->getParameters(), ', ', function ($parameter) { return $parameter->php($useFQNHints = TRUE); }); $callParameters = \Webforge\Common\ArrayUtil::implode($method->getParameters(), ', ', function ($parameter) { // für die 2ten parameter entfernen wir alle hints, damit wir nur die parameter auflistungen haben $parameter = clone $parameter; $parameter->setHint(NULL); $parameter->setArray(FALSE); $parameter->setDefault(GParameter::UNDEFINED); return $parameter->php(); }); } $code = \Psc\TPL\TPL::miniTemplate($code, array('parameters' => $parameters, 'callParameters' => $callParameters, 'method' => $method->getName(), 'closureName' => $closureName)); return $code; }
public function compile() { $gClass = new \Psc\Code\Generate\GClass(\Psc\Code\Code::getClass($this)); $gClass->elevateClass(); $this->log('compiling ProjectEntities:'); foreach ($gClass->getMethods() as $method) { if (\Psc\Preg::match($method->getName(), '/^compile[a-z0-9A-Z_]+$/') && $method->isPublic()) { $this->modelCompiler = NULL; // neuen erzeugen damit flags resetted werden, etc $m = $method->getName(); $this->log(' ' . $m . ':'); try { $out = $this->{$m}($this->getModelCompiler()); } catch (\Doctrine\DBAL\DBALException $e) { if (mb_strpos($e->getMessage(), 'Unknown column type') !== FALSE) { $types = A::implode(\Doctrine\DBAL\Types\Type::getTypesMap(), "\n", function ($fqn, $type) { return $type . "\t\t" . ': ' . $fqn; }); throw new \Psc\Exception('Database Error: Unknown Column Type: types are: ' . "\n" . $types, $e->getCode(), $e); } throw $e; } catch (\Exception $e) { $this->log(' Fehler beim Aufruf von ' . $m); throw $e; } if ($out instanceof \Webforge\Common\System\File) { $this->log(' ' . $out . ' geschrieben'); } elseif (is_array($out)) { foreach ($out as $file) { $this->log(' ' . $file . ' geschrieben'); } } elseif ($out instanceof \Psc\Doctrine\EntityBuilder) { $this->log(' ' . $out->getWrittenFile() . ' geschrieben'); } } } $this->log('finished.'); return $this; }
public function generatePHP(array $imports = array()) { if (!isset($this->gClass)) { throw new ClassWritingException('Klasse nicht gesetzt. (zuerst setClass() dann write().'); } $use = NULL; /* merge mit params */ foreach ($imports as $iClass) { $alias = NULL; if (is_array($iClass)) { list($iClass, $alias) = $iClass; } if (!$iClass instanceof GClass) { throw new \Psc\Exception('Imports können nur vom typ GClass sein'); } $this->addImport($iClass, $alias); } if (count($this->foundImports) > 0) { $useImports = array(); foreach ($this->foundImports as $alias => $gClass) { // wir filten nach den imports, die im selben Namespace sind und keinen besonderen Alias haben if ($alias !== $gClass->getClassName() || $gClass->getNamespace() !== $this->gClass->getNamespace()) { $useImports[$alias] = $gClass; } } /* Render PHP */ $classAlias = function ($gClass, $alias) { if ($alias === $gClass->getClassName()) { return $gClass->getFQN(); } else { return $gClass->getFQN() . ' AS ' . $alias; } }; if (count($useImports) > 0) { $use .= "\n"; // abstand zu namespace (neue Zeile) if ($this->useStyle === self::USE_STYLE_LINES) { $use .= A::joinc($useImports, "use %s;\n", $classAlias); } else { $use .= 'use ' . A::implode($useImports, ",\n ", $classAlias); $use .= ';'; $use .= "\n"; // abstand zu class (neue Zeile) } } } $php = TPL::miniTemplate($this->template, array('class' => $this->gClass->php(), 'use' => $use, 'namespace' => $this->gClass->getNamespace() != NULL ? 'namespace ' . ltrim($this->gClass->getNamespace(), '\\') . ';' : NULL)); return $php; }
protected static function buildRequirements(array $requirements) { return A::implode($requirements, ', ', function ($requirement) { return sprintf("'%s'", $requirement); }); }
public function getParametersString() { $php = '('; $php .= A::implode($this->getParameters(), ', ', function ($parameter) { return $parameter->php(); }); $php .= ')'; return $php; }
/** * Sucht den ersten der Services, der den Request bearbeiten will * * @throws NoServiceFoundException */ public function findService(ServiceRequest $serviceRequest) { $this->log('Find Services..'); foreach ($this->services as $service) { $this->log('Service: ' . Code::getClass($service) . '::isResponsibleFor'); if ($service->isResponsibleFor($serviceRequest)) { $this->log('ok: Service übernimmt den Request'); return $service; } } throw NoServiceFoundException::build('Es konnte kein passender Service ermittelt werden. Es wurden %d Services (%s) befragt.', count($this->services), \Webforge\Common\ArrayUtil::implode($this->services, ', ', function ($svc) { return Code::getClass($svc); }))->set('serviceRequest', $serviceRequest)->end(); }
/** * Gibt die Klasse als PHP Code zurück * * die Klasse ist noch nicht mit Namespace vor class notiert! * Eingerückt wird mit 2 whitespaces. * Em Ende befindet sich hinter der schließenden Klammer ein LF */ public function php() { $cr = "\n"; $php = $this->phpDocBlock(0); $ms = array(self::MODIFIER_ABSTRACT => 'abstract', self::MODIFIER_FINAL => 'final'); foreach ($ms as $const => $modifier) { if (($const & $this->modifiers) == $const) { $php .= $modifier . ' '; } } $php .= 'class ' . $this->getClassName() . ' '; /* Extends */ if (isset($this->parentClass)) { if ($this->parentClass->getNamespace() === $this->getNamespace()) { $php .= 'extends ' . $this->parentClass->getClassName() . ' '; // don't prefix namespace } else { $php .= 'extends ' . '\\' . $this->parentClass->getFQN() . ' '; } } /* Interfaces */ if (count($this->getInterfaces()) > 0) { $php .= 'implements '; $that = $this; $php .= A::implode($this->getInterfaces(), ', ', function (GClass $iClass) use($that) { if ($that->getNamespace() === $iClass->getNamespace()) { return $iClass->getClassName(); } else { return '\\' . $iClass->getFQN(); } }); $php .= ' '; } $php .= '{' . $cr; /* Die Funktionen machen immer den Abstand nach oben. Also vor jedem Property und jeder Methode macht dies ein "\n" */ /* Constants */ $php .= A::joinc($this->getConstants(), ' ' . $cr . '%s;' . $cr, function ($constant) { return $constant->php(2); }); /* Properties */ $php .= A::joinc($this->getProperties(), ' ' . $cr . '%s;' . $cr, function ($property) { return $property->php(2); // hier jetzt auch wegen DocBlock einrücken }); /* Methods */ $php .= A::joinc($this->getMethods(), ' ' . $cr . '%s' . $cr, function ($method) { return $method->php(2); // rückt selbst zwischen den Klammern ein, aber wir wollen ja den body z.b. auf 4 haben nicht auf 2 }); $php .= '}'; // kein umbruch hinten, immer abstand nach oben! return $php; }
public static function debugCollection($collection, $glue = "\n", $label = NULL) { $ret = $label ? 'Collection ' . $label . $glue : NULL; if (count($collection) === 0) { $ret .= '[leere Collection]'; } else { $ret .= \Webforge\Common\ArrayUtil::implode(Code::castArray($collection), $glue, function ($item, $key) { return sprintf('[%s] %s', $key, \Psc\Doctrine\Helper::debugEntity($item)); }); } return $ret; }
public static function convertToId($name) { if (is_array($name)) { return A::implode($name, '-', function ($part) { return is_array($part) ? 'Array' : $part; }); } return $name; }