/** * @return string */ public function JS() { $code = $this->getCode(); if (is_string($code)) { $code = array($code); // blöde interfaces vom js helper } elseif ($code instanceof \Psc\JS\Expression) { $code = array($code->JS()); } // load-wrappers (von innen nach außen) if ($this->onPscReady === 'main') { // non blocking mode (is save to use in html inline scripts directly) $this->unshiftRequirement('app/main'); $this->unshiftRequirementAlias('main'); $this->unshiftRequirement('jquery'); $this->unshiftRequirementAlias('jQuery'); $code = Helper::bootLoad($this->getRequirements(), $this->requirementsAliases, $code); } elseif ($this->onPscReady) { // is only save to use in ajax requests / inline scripts where window.requireLoad is already defined $this->unshiftRequirement('jquery'); $this->unshiftRequirementAlias('jQuery'); $code = Helper::requireLoad($this->getRequirements(), $this->requirementsAliases, $code); } elseif (count($req = $this->getRequirements()) > 0) { $code = Helper::requirejs($req, array(), $code); } else { $code = count($code) > 1 ? \Webforge\Common\ArrayUtil::join($code, "%s\n") : current($code); } return TPL::miniTemplate((string) $code, (array) $this->vars); }
protected function hash($fqn, $uniqueData) { asort($uniqueData); return $fqn . '__' . A::implode($uniqueData, ',', function ($value, $field) { return $field . ':' . $value; }); }
protected function createRowFromArray(array $row) { foreach ($row as $column => $value) { if (!array_key_exists($column, $this->columns)) { throw new \Psc\Exception('Request eines unbekannten Spalten-Typs: "' . $column . '" ' . print_r(A::keys($row), true) . '. Wurde dieser mit addColumn() hinzugefügt?'); } $cell = $this->sheet->setCellValue($this->columns[$column][0] . $this->row->getRowIndex(), $value, true); } }
public function hydrate($entity, $data) { if (is_array($data) && !\Webforge\Common\ArrayUtil::isNumeric($data)) { // numeric bedeutet composite key (z.b. OID) return $this->getRepository($entity)->hydrateBy($data); } else { return $this->getRepository($entity)->hydrate($data); } }
public function hasMethod($name, array $parameters = NULL) { $this->test->assertTrue($this->gClass->hasMethod($name), $this->msg("hasMethod '%s'. Methods avaible: [%s]", $name, implode(", ", A::pluck($this->gClass->getMethods(), 'name')))); $method = $this->gClass->getMethod($name); if (isset($parameters)) { $this->assertMethodParameters($method, $parameters); } $this->lastGet = $method; return $this; }
public function walkArrayValue($phpValue, Type $type) { $isList = $type->isList() !== NULL ? $type->isList() : \Webforge\Common\ArrayUtil::isNumeric($phpValue); if ($isList) { return $this->walkListValue((array) $phpValue, $type); } else { return $this->walkHashMapValue((object) $phpValue, $type); // alternativ: doch lValue übergeben und lValue->castToHashMap() oder sowas haben } }
public function insertRow(array $row, $index = self::END) { if (!is_integer($index) && $index !== self::END) { throw new \InvalidArgumentException('index muss ein integer sein. self::END f?r append'); } if (!count($row) === count($this->columns)) { throw new \InvalidArgumentException("Zeile hat nicht %d Spalten sondern %d Spalten.", count($row), count($this->columns)); } A::insert($this->rows, $row, $index); return $this; }
/** * @return array */ protected function parseParams($input) { $params = json_decode($json = $input->getArgument('parametersJSON')); if ($params === NULL) { throw new \InvalidArgumentException(sprintf("parametersJSON muss valides JSON sein: '%s' wurde übergeben", $json)); } $params = (array) $params; if (\Webforge\Common\ArrayUtil::isNumeric($params)) { throw new \InvalidArgumentException(sprintf("parametesrJSON muss ein object sein, mit constructorParameterName => value oder propertyName => value")); } return $params; }
protected function exportMixedValue($value) { if (is_array($value) && A::getType($value) === 'numeric') { return $this->getCodeWriter()->exportList($value); } elseif (is_array($value)) { return $this->getCodeWriter()->exportKeyList($value); } else { try { return $this->getCodeWriter()->exportBaseTypeValue($value); } catch (\Psc\Code\Generate\BadExportTypeException $e) { throw new \RuntimeException('In Argumenten oder Properties können nur Skalare DefaultValues stehen. Die value muss im Constructor stehen.', 0, $e); } } }
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); }
public function addRow($headline, $content, $index = self::END, $class = NULL) { if ($index === self::END) { $indexHeadline = $indexContent = self::END; } else { // wenn bei 0 eingefügt werden soll ist head = 0 und div = 1 $indexHeadline = $index * 2; // wenn bei 2 eingefügt werden soll ist head = 4 (weil div+head 0 und div+head1 davor sind) und div = 5 $indexContent = $indexHeadline + 1; } \Webforge\Common\ArrayUtil::insert($this->html->content, $head = new HTMLTag($this->getOption('headlineTag'), $headline, array('class' => $class)), $indexHeadline); \Webforge\Common\ArrayUtil::insert($this->html->content, $div = new HTMLTag($this->getOption('contentTag'), $content, array('class' => $class)), $indexContent); $head->addClass('ui-accordion-header'); $div->setOption('br.openTag', TRUE)->setOption('tag.indent', $this->indent + 2); }
/** * @param string $command nur der befehl oder mehrere (z. B. lb für list simple) * @param array $options alle optionen ohne - davor */ protected function exec($command, array $options = array(), $append = NULL) { $cmd = sprintf('%s %s%s %s%s', SystemUtil::escapeShellArg($this->bin), $command, count($options) > 0 ? \Webforge\Common\ArrayUtil::join($options, ' -%s') : NULL, (string) escapeshellarg($this->rar), mb_strlen($append) > 0 ? ' ' . $append : NULL); $out = array(); $ret = NULL; $out = System::execute($cmd, NULL, NULL, $stdout, $stderr, NULL, $ret); if ($ret !== 0) { throw new Exception(sprintf("Fehler '%s' beim Ausführen des Befehls '%s'. Rückgabe: %d", $out, $cmd, $ret)); } /* sonderfall für listfiles denn das gibt immer $ret = 0 zurück, toll, was? */ if (!empty($stderr)) { throw new Exception(sprintf("Fehler '%s' beim Ausführen des Befehls '%s'.", $stderr, $cmd)); } return $out; }
/** * @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 testParameter() { $class = new ReflectionClass('Psc\\Code\\Generate\\ParameterTestClass'); $method = $class->getMethod('comboBox'); $params = $method->getParameters(); $param = new GParameter(); $param->elevate($params[4]); $this->assertEquals('commonItemData', $param->getName()); $this->assertEquals(array(), $param->getDefault()); $this->assertTrue($param->isOptional()); $this->assertEquals('Array $commonItemData = array()', $param->php()); $param = new GParameter(); $param->elevate($params[3]); $this->assertEquals('$itemType = NULL', $param->php()); $param = new GParameter(); $param->elevate($params[0]); $this->assertEquals('$label', $param->php()); $param = new GParameter(); $param->elevate(A::index($class->getMethod('factory')->getParameters(), 0)); $this->assertEquals('\\Psc\\Code\\Generate\\TestHint $dunno', $param->php($useFQN = TRUE)); }
protected function processErrors() { $errors = libxml_get_errors(); if (count($errors) == 0) { $this->rollback(); throw new LoadingException('Fehler beim Laden des XMLS, es konnten aber keine Fehlerinformationen ermittelt werden.'); } $cnt = count($errors); if ($cnt == 1) { $msg = 'Beim Laden des XMLs ist ein Fehler aufgetreten: '; } else { $msg = sprintf('Beim Laden des XMLs sind %d Fehler aufgetreten: ', $cnt); } $that = $this; $e = new LoadingException($msg . "\n" . \Webforge\Common\ArrayUtil::joinc($errors, "\n %s\n\n", function ($error) use($that) { return $that->errorToString($error); })); $e->libxmlErrors = $errors; libxml_clear_errors(); $this->rollback(); throw $e; }
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; }
protected static function buildRequirements(array $requirements) { return A::implode($requirements, ', ', function ($requirement) { return sprintf("'%s'", $requirement); }); }
public static function fromCode(array $codeLines) { return new static(\Webforge\Common\ArrayUtil::join($codeLines, "%s\n")); }
protected function debugTokens(array $tokens) { return \Webforge\Common\ArrayUtil::joinc($tokens, ', ', function ($token) { return is_string($token) ? $token : j_token_name($token); }); }
/** * @param string|array $name ist dies ein array wird der Name in PHP-Post-Array Syntax zurückgegeben $name = "var[key1][key2]" */ public static function getName($name) { if (is_array($name)) { $root = array_shift($name); $name = $root . A::join($name, '[%s]'); return $name; } return $name; }
/** * @param mixed[] $columns die Spalten in der richtigen Reihenfolge */ public function addRow(array $row) { $this->init(); $names = array_keys($this->columns); if (!A::isNumeric($row)) { throw new InvalidArgumentException('Bis jetzt nur numerische Arrays. Die Reihenfolge ist: ' . implode(', ', $names)); } if (count($row) !== count($names)) { throw new InvalidArgumentException('Spalten für addRow haben nicht die richtige Anzahl. Die Reihenfolge ist: ' . implode(', ', $names)); } $grid = $this->getGrid(); $grid->tr(); foreach ($row as $index => $value) { $column = $this->getColumn($names[$index]); // validate wäre schön nach type? $td = $grid->td()->setContent($value)->addClass($this->classify($column->getName()))->addClass($column->getClasses()); } $grid->tr(); return $this; }
/** * 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(); }
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; }
public function debug() { print \Webforge\Common\ArrayUtil::join($this->log, " [phar] %s\n"); }
/** * Gibt das HTML zum Laden von allen CSS Dateien aus */ public function load($glue = "%s \n") { print A::join($this->getHTML(), "%s \n"); }
/** * @param array ein identifier array mit columnname => value der id-werte * @return string|id gibt den Identifier als Scalar Value zurück */ public static function _getIdentifierHash(array $identifiers) { if (count($identifiers) == 1) { return A::peek($identifiers); } elseif (count($identifiers) > 0) { ksort($identifiers); return implode('.', $identifiers); } else { throw new Exception('Kein Hash für leere identifiers möglich'); } }
public function generateDataRandomType(array $types) { return $this->generateData(A::randomValue($types)); }
public function insertBody(array $codeLines, $index) { $this->getBodyCode(); \Webforge\Common\ArrayUtil::insertArray($this->bodyCode, $codeLines, $index); return $this; }
/** * Findet den Controller anhand des Requests * * GET [/$prefix]/person/1 * => * \Project::getNamespace()\Controllers\PersonController::getEntity(1) * => * \CoC\Controllers\PersonController::getEntity(1) * * GET [/$prefix]/person/1/form * => * \Project::getNamespace()\Controllers\PersonController::getEntity(1,'form') * * GET [/$prefix]/persons/grid?filter1=value1&filter2=value2 * => * \Project::getNamespace()\Controllers\PersonController::getEntities(array('filter1'=>'value1', 'filter2'=>'value2'),'grid') */ public function routeController(ServiceRequest $request) { $r = $this->initRequestMatcher($request); $entityPart = $r->qmatchRx('/^[a-z-0-9]+$/i', 0); if (mb_strpos($entityPart, '-') !== FALSE) { $entityPart = Code::dashToCamelCase($entityPart); } // alle weiteren Parameter an den Controller weitergeben $params = $r->getLeftParts(); if ($request->getType() === self::GET) { $this->log('EntityPart: ' . $entityPart . ' ' . ($this->isPlural($entityPart) ? 'ist plural' : 'ist singular'), 2); if ($this->isPlural($entityPart)) { if ($r->part() === 'form') { $method = 'getNewEntityFormular'; } else { $method = 'getEntities'; A::insert($params, $request->getQuery(), 0); // query als 1. parameter } $entityPart = Inflector::singular($entityPart); } else { $method = 'getEntity'; $params = array(); $params[] = $r->shift(); // id $params[] = count($r->getLeftParts()) > 1 ? $r->getLeftParts() : $r->shift(); // subresource $params[] = $request->getQuery(); } } elseif ($request->getType() === self::PUT) { if ($r->part() === 'grid') { $entityPart = Inflector::singular($entityPart); $controller = $this->getEntityController($entityPart); $method = 'saveSort'; $params = array($r->bvar($controller->getSortField(), array())); } elseif ($request->hasMeta('revision') && $request->getMeta('revision') !== 'default') { $method = 'saveEntityAsRevision'; A::insert($params, $request->getMeta('revision'), 1); A::insert($params, (object) $request->getBody(), 2); } else { $method = 'saveEntity'; A::insert($params, (object) $request->getBody(), 1); // $formData als parameter 2 } } elseif ($request->getType() === self::PATCH) { $method = 'patchEntity'; A::insert($params, (object) $request->getBody(), 1); // $formData als parameter 2 } elseif ($request->getType() === self::DELETE) { $method = 'deleteEntity'; // das gibt einen "missing argument 1" fehler, wenn id fehlt, aber ka welche httpException ich hier nehmensoll, deshalb bleibt das erstmal so } elseif ($request->getType() === self::POST) { $entityPart = Inflector::singular($entityPart); // singular und plural okay A::insert($params, $request->getBody(), 0); // $formData als parameter 1 if ($request->hasMeta('revision')) { $method = 'insertEntityRevision'; A::insert($params, $request->getMeta('revision'), 0); } else { $method = 'insertEntity'; } } else { // das kann glaub ich nicht mehr passieren, weil wir jetzt alle haben: put/pust/delete/get gibts nicht noch head? throw HTTPException::MethodNotAllowed('Die Methode: ' . $request->getType() . ' ist für diesen Request nicht erlaubt'); } if (!isset($controller)) { $controller = $this->getEntityController($entityPart); } return array($controller, $method, $params); }