/** * Testet ob ein Widget im HTML aufgerufen wird und gibt dessen Parameter als objekt zurück * * @return object */ public function jqueryWidget($widgetName, $html) { $json = \Psc\Preg::qmatch($html, '/\\.' . $widgetName . '\\((.*?)\\)/s', 1); $this->testCase->assertNotEmpty($json, 'JSON Parameter für .' . $widgetName . ' konnte nicht aus dem HTML ausgelesen werden: ' . $html); $data = $this->json($json, FALSE); return $data; }
protected function injectToSetter(GClass $gClass) { $setter = 'set' . $this->relation->getSourceMethodName(); if (!$gClass->hasOwnMethod($setter)) { throw new \RuntimeException('in der Klasse kann ' . $setter . ' nicht gefunden werden. Womöglich muss der Setter vererbt werden'); } else { $setter = $gClass->getMethod($setter); } if ($this->relation->isTargetNullable()) { $firstParam = current($setter->getParameters()); $firstParam->setOptional(TRUE)->setDefault(NULL); } if ($this->relation->shouldUpdateOtherSide()) { // wenn die Relation bidrektional ist muss der normale setter auf der Inverse side addXXX auf der aufrufen // das ist aber gar nicht so trivial, weil wie wird removed? // before('return $this').insert(...) $body = $setter->getBodyCode(); $lastLine = array_pop($body); if (\Psc\Preg::match($lastLine, '/^\\s*return \\$this;$/') <= 0) { throw new \Psc\Exception('EntityRelationInterfaceBuilder möchte den Setter: ' . $setter->getName() . ' für ' . $gClass . ' ergänzen, aber der Body code scheint kein autoGenererierter zu sein.'); } $body[] = \Psc\TPL\TPL::miniTemplate(($this->relation->isTargetNullable() ? 'if (isset($%paramName%)) ' : NULL) . '$%paramName%->add%otherMethodName%($this);' . "\n", array('paramName' => $this->relation->getTarget()->getParamName(), 'otherMethodName' => $this->relation->getSource()->getMethodName('singular'))); $body[] = $lastLine; $setter->setBodyCode($body); } }
public function __construct(\PDOException $e = NULL) { if (isset($e)) { parent::__construct($e->errorInfo[2], $e->errorInfo[1]); $this->uniqueConstraint = \Psc\Preg::qmatch($e->errorInfo[2], "/key\\s+'(.*?)'/"); } }
protected function sync() { $unison = $this->unisonBinary . ' -batch -terse '; $unison .= \Psc\TPL\TPL::miniTemplate('%profile% ', array('profile' => $this->profile)); //print 'running: '.$unison."\n"; $envs = array(); $inherits = array('UNISON', 'HOME', 'PATH', 'SystemRoot', 'LOCALAPPDATA', 'SystemDrive', 'SSH_AUTH_SOCK', 'CommonProgramFiles', 'APPDATA', 'COMPUTERNAME', 'TEMP', 'TMP', 'USERNAME'); foreach ($inherits as $inherit) { $envs[$inherit] = getenv($inherit); } $process = new Process($unison, NULL, $envs); $process->setTimeout(0); $log = NULL; $result = new \stdClass(); $resultFound = FALSE; $ret = $process->run(function ($type, $buffer) use(&$log, &$result, &$resultFound) { // suche nach dem endergebnis: $m = array(); if (\Psc\Preg::match($buffer, '/^Synchronization\\s*complete\\s*at\\s*[0-9:]*\\s*\\(([0-9]+)\\s*items?\\s*transferred, ([0-9]+) skipped,\\s*([0-9]+)\\s*failed\\)/i', $m)) { $resultFound = TRUE; $result = (object) array('transferred' => (int) $m[1], 'skipped' => (int) $m[2], 'failed' => (int) $m[3]); } $log .= $buffer; //if ('err' === $type) { // echo '[unison-ERR]: '.$buffer; //} else { // echo '[unison-OUT]: '.$buffer; //} }); print "\n"; if ($resultFound) { print sprintf("Unison: (%d transferred, %d skipped, %d failed)\n", $result->transferred, $result->skipped, $result->failed); } // http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html#exit switch ($ret) { case 0: print 'Unison: successful synchronization'; break; case 1: print 'Unison: some files were skipped, but all file transfers were successful.'; break; case 2: print 'Unison: non-fatal failures occurred during file transfer.'; break; case 3: print 'Unison: a fatal error occurred, or the execution was interrupted.'; break; default: print 'Unison: unknown exit code: ' . $ret; break; } print "\n"; if ($ret !== 0) { throw new RuntimeException('Unison failed: ' . $log); } }
public function guessLabel($identifier) { if (array_key_exists($identifier, $this->commonLabels)) { return $this->commonLabels[$identifier]; } // camelCase => camel Case $identifier = Preg::replace($identifier, '/([a-z])([A-Z])/', '$1 $2'); // camel Case => Camel Case return S::ucfirst($identifier); }
public function parseFrom($string) { $fields = explode("\r\n", Preg::replace($string, '/\\x0D\\x0A[\\x09\\x20]+/', ' ')); //Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF //HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT if (!Preg::match($statusLine = array_shift($fields), '|HTTP/([0-9]+\\.[0-9]+)\\s+([0-5][0-9]+)\\s+(.*)|', $match)) { throw new \Psc\Exception('Kann Header Status-Line nicht parsen: "' . $statusLine . '"'); } list($NULL, $this->version, $this->code, $this->reason) = $match; parent::parseFrom($string); }
public function validate($data) { if ($data === NULL) { throw new EmptyDataException(); } $data = trim($data); // 60345+ und [A-Z]-340545345345, etc if (Preg::match($data, '/[0-9+]/') > 0 || Preg::match($data, '/[A-Z]+-[0-9+]/')) { return $data; } throw new \Psc\Exception('ist keine valide Postleitzahl'); }
public function testConstruct() { $tag = new Tag('div'); $this->debugger->container($tag); $this->assertNotEmpty($color = \Psc\Preg::qmatch($tag->htmlAttributes(), '/[0-9]+px solid (.*)/')); $this->debugger->container($tag); $this->assertNotEmpty($color2 = \Psc\Preg::qmatch($tag->htmlAttributes(), '/[0-9]+px solid (.*)/')); $this->assertNotEquals($color, $color2); $this->debugger->container($tag); $this->assertNotEmpty($color3 = \Psc\Preg::qmatch($tag->htmlAttributes(), '/[0-9]+px solid (.*)/')); $this->assertNotEquals($color2, $color3); // usw }
/** * @return string $match[$set] */ public function qmatchiRX($rx, $set = 1) { if (($match = Preg::qmatch($this->part(), Preg::setModifier($rx, 'i'), $set, FALSE)) !== FALSE) { $ret = $this->success($match); if (is_array($ret)) { return array_map($ret, 'mb_strtolower'); } elseif (is_string($ret)) { return mb_strtolower($ret); } else { return $ret; } } $this->fail('%s matched nicht: ' . $rx); }
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 setJSONFields(stdClass $json) { foreach ($this->getJSONFields() as $field => $meta) { if ($meta === NULL) { $this->{$field} = $json->{$field}; } elseif (mb_substr($meta, 0, 4) === 'JSON') { if ($json->{$field} === NULL) { $this->{$field} = NULL; } elseif (($class = Preg::qmatch($meta, '/^JSON<(.*)>$/', 1)) !== NULL) { $this->{$field} = $class::createFromJSON($json->{$field}); } } } return $this; }
public function parseFrom($string) { $fields = explode("\r\n", Preg::replace($string, '/\\x0D\\x0A[\\x09\\x20]+/', ' ')); $fields = explode("\r\n", $string); //Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF //HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT if (!Preg::match($statusLine = array_shift($fields), '|HTTP/([0-9]+\\.[0-9]+)\\s+([0-5][0-9]+)\\s+(.*)|', $match)) { throw new \Psc\Exception('Kann Header Status-Line nicht parsen: "' . $statusLine . '"'); } list($NULL, $this->version, $this->code, $this->reason) = $match; /* message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = <the OCTETs making up the field-value and consisting of either *TEXT or combinations of token, separators, and quoted-string> */ foreach ($fields as $field) { try { if (Preg::match($field, '/([^:]+): (.+)/m', $match)) { list($NULL, $name, $value) = $match; $name = Preg::replace_callback(mb_strtolower(trim($name)), '/(?<=^|[\\x09\\x20\\x2D])./', function ($m) { return mb_strtoupper($m[0]); }); if (isset($this->values[$name])) { if (is_array($this->values[$name])) { $this->values[$name][] = $value; } else { $this->values[$name] = array($this->values[$name], $value); } } else { $this->values[$name] = trim($value); } } } catch (\Psc\Exception $e) { if (mb_strpos($e->getMessage(), 'Bad UTF8') === FALSE) { throw $e; } } } }
protected function getLocalSubtitle($episode, $lang) { $episodesDir = $this->getEpisodesDir($episode); $this->logger->writeln('Suche Sub(' . $lang . ') für: ' . $episode . ' '); // wir holen uns alle releases (in allen Formaten) aus dem Episoden Verzeichnis und suchen uns einen heißen Kandidaten $episodeDir = $episodesDir->sub($episode->getNum()); // fastcheck if (!$episodeDir->exists()) { return NULL; } $subs = array(); foreach ($episodeDir->getFiles(array('srt', 'rar', 'zip')) as $sub) { //$this->logger->writeln(' Kandidat: '.$sub); // nach language filtern und dabei das release holen if (($subRelease = Preg::qmatch($sub->getName(File::WITHOUT_EXTENSION), '/^(.*)\\.' . $lang . '$/i')) == NULL) { continue; } $subRelease = preg_replace('/-?proper-?/i', NULL, $subRelease); //$this->logger->writeln(' Sub-Release: '.$subRelease); // "IMMERSE" in "IMMERSE-x264 720p" oder so $this->logger->writeln($subRelease . ' in ' . $episode->getRelease()); if (mb_stripos($episode->getRelease(), $subRelease) !== FALSE) { $subs[$sub->getExtension()] = $sub; } } if (count($subs) === 1) { $sub = current($subs); $this->logger->writeln(' Lokaler Subtitle: ' . $sub . ' gefunden'); return $sub; } elseif (count($subs) === 0) { $this->logger->writeln(' Kein passenden Subtitle(' . $lang . ') im Episodenverzeichnis gefunden.'); } else { if (isset($subs['srt'])) { return $subs['srt']; } else { $this->logger->writeln(' WARNING: Mehrere Subtitle im Episodenverzeichnis gefunden: ' . "\n" . implode("\n", $subs) . ' Nehme erstbesten, weil zu faul'); return current($subs); // ach verdammt, mir jetzt grad egal! (eigentlich wäre hier .srt auswählen toll } } }
public static function convertPDOException(\PDOException $e) { $exceptions = array('\\Psc\\Doctrine\\ForeignKeyConstraintException', '\\Psc\\Doctrine\\UniqueConstraintException', '\\Psc\\Doctrine\\TooManyConnectionsException', '\\Psc\\Doctrine\\UnknownColumnException'); /* grml. fix pdo */ if ($e->errorInfo === NULL && mb_strlen($msg = $e->getMessage()) > 0) { //SQLSTATE[08004] [1040] Too many connections if (\Psc\Preg::match($msg, '/SQLSTATE\\[([0-9]+)\\]\\s*\\[([0-9]+)\\]\\s*(.*)?/s', $m)) { $e->errorInfo[0] = $m[1]; $e->errorInfo[1] = $m[2]; $e->errorInfo[2] = $m[3]; } } foreach ($exceptions as $cname) { if ($cname::check($e)) { return new $cname($e); } } //throw new \Psc\Exception('unconverted PDO Exception: '.Code::varInfo($e->errorInfo),0,$e); print 'unconverted PDOException: ' . Code::varInfo($e->errorInfo); return $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; }
/** * @return list($phpCode, $methodNames) */ public function compile(GClass $gClass) { $this->methods = array(); $gClass->elevateClass(); $closures = array(); $methodNames = array(); foreach ($gClass->getAllMethods() as $method) { $closureName = $method->getName(); if ($method->hasDocBlock()) { $docBlock = $method->getDocBlock(); if (($ccAlias = \Psc\Preg::qmatch($docBlock->toString(), '/@cc-alias\\s+(.*?)([\\s]|$)/im', 1)) !== NULL) { $closureName = $ccAlias; } if (\Psc\Preg::match($docBlock->toString(), '/@cc-ignore/i')) { continue; } } $closures[$closureName] = $this->compileClosure($method, $closureName); $this->methods[$closureName] = $method; $methodNames[] = $closureName; } return array(\Webforge\Common\ArrayUtil::join($closures, "%s;\n\n"), $methodNames); }
public function validate($data) { if ($data === NULL) { throw new EmptyDataException(); } // date::parse schmeisst keine Exceptions für invalide Datum! Das ist kacke if ($this->format === 'd.m.') { /* Schaltjahrproblematik macht stress mit DateTime::parse */ if (($match = \Psc\Preg::qmatch($data, '/^([0-9]+)\\.([0-9]+)\\.$/', array(1, 2))) !== NULL) { list($d, $m) = $match; if ($d == 29 && $m == 2) { $date = new Date($d . '.' . $m . '.1972'); } else { $date = new Date($d . '.' . $m . '.1970'); } } else { throw new \Psc\DateTime\ParsingException('Aus ' . $data . ' kann kein Datum extrahiert werden. Erwartetes Format: ' . $this->format); } } else { $date = new Date($data); } return $date; }
public function routeController(ServiceRequest $request) { $r = $this->initRequestMatcher($request); $controller = $r->qmatchiRx('/^(tpl|excel|images|uploads|persona)$/i'); if ($controller === 'tpl') { $x = 0; $tpl = array(); while (!$r->isEmpty() && $x <= 10) { $tpl[] = $r->qmatchRx('/^([-a-zA-Z0-9_.]+)$/'); $x++; } $controller = new TPLController($this->project); return array($controller, 'get', array($tpl)); } elseif ($controller === 'excel') { $controller = new ExcelController($this->project); if ($request->getType() === Service::POST) { $body = $request->getBody(); if ($r->part() === 'convert') { // importieren // im body können dann options stehen oder sowas // der controller holt sich die excelFile selbst return array($controller, 'convert', array(is_object($body) ? $body : new \stdClass())); } else { // exportieren return array($controller, 'create', array($body, $r->part())); // nächste ist filename ohne endung } } } elseif ($controller === 'images') { $controller = new ImageController(ImageManager::createForProject($this->project, $this->getDoctrinePackage()->getEntityManager(), $this->getDoctrinePackage()->getModule()->getEntityName('Image'))); if ($r->isEmpty() && $request->getType() === Service::POST && $request->hasFiles()) { // nimmt nur eine file, weil moep return array($controller, 'insertImageFile', array(current($request->getFiles()), $request->getBody())); } else { $method = 'getImage'; $cacheAdapters = array('thumbnail'); $params = array($r->qmatchiRX('/([a-z0-9]+)/')); // id or hash // filename immer am ende und optional $filename = NULL; if (\Psc\Preg::match($r->getLastPart(), '/[a-z0-9]+\\.[a-z0-9]+/i')) { $filename = $r->pop(); } /* gucken ob es eine Version des Images werden soll */ if (in_array($r->part(), $cacheAdapters)) { $method = 'getImageVersion'; $params[] = $r->matchNES(); // type $params[] = $r->getLeftParts(); // parameter für den cache adapter } if ($filename) { $params[] = $filename; } return array($controller, $method, $params); } } elseif ($controller === 'uploads') { $controller = new FileUploadController(UploadManager::createForProject($this->project, $this->dc)); $this->log('upload-request method: ' . $request->getType()); $this->log(' has files: ' . ($request->hasFiles() ? 'true' : 'false'), 1); if ($r->isEmpty() && $request->getType() === Service::POST && $request->hasFiles()) { // nimmt nur eine file, weil moep return array($controller, 'insertFile', array(current($request->getFiles()), $request->getBody())); } elseif ($r->isEmpty() && $request->getType() === Service::GET) { $params = array(); // criterias $params[] = array(); $params[] = $r->matchOrderBy($r->qVar('orderby'), array('name' => 'originalName')); return array($controller, 'getFiles', $params); } else { $method = 'getFile'; $params = array($r->qmatchiRX('/([a-z0-9]+)/')); // id or hash // filename immer am ende und optional $filename = NULL; try { if (\Psc\Preg::match($r->getLastPart(), '/^(.+)\\.(.+)$/')) { $filename = $r->pop(); } } catch (\Webforge\Common\Exception $e) { if (mb_strpos('.', $r->getLastPart()) !== FALSE) { $filename = \Webforge\Common\System\File::safeName($r->pop()); $filename = Preg::replace($filename, '/_+/', '_'); } } if ($filename) { $params[] = $filename; } return array($controller, $method, $params); } } elseif ($controller === 'persona') { $controller = new \Webforge\Persona\Controller(); return array($controller, 'verify', array($r->bvar('assertion'))); } throw HTTPException::NotFound('Die Resource für cms ' . $request . ' existiert nicht.'); }
/** * * Die Werte des Arrays sind relative links zum attachment * @return array schlüssel ebene eins ist sowas wie 1 2 ... für die Episoden ebene 2 sind die formate der Releases (ASAP, IMMERSE, etc...) */ public function getSubs($threadLink) { $this->logger->writeln('Lade alle Subs aus ' . $threadLink); $this->req = new URLRequest($threadLink, $this->cookieJar); $html = $this->req->init()->process(); $dom = xml::doc($html); $tables = xml::query($dom, 'div#main div.threadStarterPost div.messageContent div.messageBody div.baseSC table'); if (count($tables) == 0) { $e = new SubcentralNoTablesException('Keine Tables: "div#main div.threadStarterPost div.messageContent div.messageBody div.baseSC table " gefunden in: ' . $this->req->getURL() . ' Wurde sich bedankt?'); $this->logger->writeln($e->getMessage()); $e->threadURL = $this->req->getURL(); throw $e; } $defTable = xml::doc(xml::export(array_shift($tables))); $titles = xml::query($defTable, 'td a.sclink'); $tabIds = array(); /* die Titel der Tables stehen oben in der Box */ foreach ($titles as $a) { $tabIds[Preg::qmatch($a->nodeValue, '/^\\s*(.*)\\*Klick\\*$/i')] = Preg::qmatch($a->getAttribute('id'), '/link(.*)/'); } $subs = array(); foreach ($tables as $table) { $subTable = xml::doc(xml::export($table)); $lang = NULL; foreach (xml::query($subTable, 'tr') as $row) { $tds = xml::query(xml::doc(xml::export($row)), 'td'); if (count($tds) > 0) { $episode = (int) Preg::qmatch($tds[0]->nodeValue, '/^\\s*E([0-9]+)/'); foreach (xml::query(xml::doc(xml::export($row)), 'td a') as $attachment) { $subs[$episode][$lang][$this->stringifyFormat($attachment->nodeValue)] = $attachment->getAttribute('href'); } } else { // in der th-row die sprache auswählen $usa = xml::query(xml::doc(xml::export($row)), 'th img[src*="flags/usa.png"]'); $de = xml::query(xml::doc(xml::export($row)), 'th img[src*="flags/de.png"]'); if (count($de) > 0) { $lang = 'de'; } elseif (count($usa) > 0) { $lang = 'en'; } else { $lang = 'en'; } } } } $this->logger->writeln(count($subs) . ' Subs gefunden'); return $subs; }
/** * Erstellt einen Request aus den Umgebungsvariablen * * wird eine Umgebungsvariable mit NULL übergeben (oder ausgelassen), wird die global Umgebungsvariable genommen * infer() ist also äquivalent mit: * infer($_GET, $_POST, $_COOKIE, $_SERVER) * * ist $_GET['mod_rewrite_request'] gesetzt wird dies als resource genommen * * @TODO Symfony hierfür nehmen (am besten ganz ersetzen) * * @deprecated das übergeben von Variablen ist strongly discouraged! */ public static function infer(SfRequest $sfRequest = NULL) { if (!isset($sfRequest)) { $sfRequest = SfRequest::createFromGlobals(); } // alternativ könnten wir den code aus sf kopieren oder sf mal patchen.. $method = NULL; switch ($sfRequest->getMethod()) { // wertet schon X-HTTP-METHOD-OVERRIDE aus case 'POST': $method = Request::POST; break; case 'PUT': $method = Request::PUT; break; case 'DELETE': $method = Request::DELETE; break; case 'PATCH': $method = Request::PATCH; break; case 'GET': default: $method = Request::GET; break; } $request = new Request($method, rawurldecode($sfRequest->getPathInfo())); $request->setQuery($sfRequest->query->all()); $request->setReferer($sfRequest->server->get('HTTP_REFERER')); $request->setUserAgent($sfRequest->server->get('HTTP_USER_AGENT')); $request->setPreferredLanguages($sfRequest->getLanguages()); $header = $request->getHeader(); foreach ($sfRequest->headers->all() as $key => $value) { // wir verschönern hier z.B. X_REQUESTED_WITH zu X-Requested-With $key = mb_strtolower($key); $key = \Psc\Preg::replace_callback($key, '/(^|-)([a-z]{1})/', function ($m) { return ($m[1] === '' ? NULL : '-') . mb_strtoupper($m[2]); }); // das ist voll doof, aber aus legacy gründen müssen wir das machen // schöner wäre auch die sf Requests / Header zu benutzen, dann wären wir durch if (count($value) === 1) { // unwrap arrays mit nur einem eintrag $value = current($value); } $header->setField($key, $value); } /* Body */ if (mb_strpos($request->getHeaderField('Content-Type'), 'application/x-www-form-urlencoded') === 0) { $request->setBody($sfRequest->request->all()); } elseif (mb_strpos($request->getHeaderField('Content-Type'), 'multipart/form-data') === 0) { $request->setBody($sfRequest->request->all()); $files = array(); foreach ($sfRequest->files->all() as $key => $sfFile) { if ($sfFile instanceof \Symfony\Component\HttpFoundation\File\UploadedFile) { if (!$sfFile->isValid()) { throw new \Psc\Exception('Cannot Upload File: ' . $sfFile->getClientOriginalName() . ' Error Code: ' . $sfFile->getErorr() . ' size: ' . $sfFile->getClientSize()); } else { $files[$key] = $f = new \Psc\System\UploadedFile($sfFile->getPathName()); $f->setOriginalName($sfFile->getClientOriginalName()); } $request->setFiles($files); } // FIXME else: kann auch ein array von files sein oder ein array von array ... // aber wie machen wir das in den files array rein? } } else { $request->setBody($sfRequest->getContent()); // really raw } return $request; }
public static function reformat($html, $withPFirst = TRUE) { /* compile regex */ $blockElements = array('h1', 'h2', 'h3', 'div', 'h3', 'table', 'tr', 'td', 'ol', 'li', 'ul', 'pre', 'p'); $blemRx = '(?:' . implode('|', $blockElements) . ')'; $blemStartRx = '<' . $blemRx . '[^>]*(?<!\\/)>'; // ignores self-closing $blemEndRx = '<\\/' . $blemRx . '[^>]*>'; $blemBothRx = '<\\/?' . $blemRx . '[^>]*>'; $debug = FALSE; $log = NULL; $log .= 'Starte mit Text: "' . $html . '"<br />' . "\n"; $level = 0; $pOpen = FALSE; $matching = NULL; $ret = NULL; $firstP = $withPFirst; $x = 0; while ($html != '' && $x <= 100000000) { $x++; $log .= "level: " . $level . ": "; /* $html abschneiden (schritt) */ if (isset($matching)) { $html = mb_substr($html, mb_strlen($matching)); $ret .= $matching; $matching = NULL; } /* normaler text */ $match = array(); if (Preg::match($html, '/^([^\\n<>]+)/', $match) > 0) { /* p öffnen, wenn es nicht offen ist */ if ($level == 0 && !$pOpen) { $pOpen = TRUE; $log .= "open p<br />\n"; if ($firstP && mb_strlen(trim($ret)) == 0) { $ret .= '<p class="first">'; $firstP = FALSE; } else { $ret .= '<p>'; } } $matching = $match[1]; $log .= "text(" . mb_strlen($matching) . "): " . str_replace(array("\n", "\r"), array("-n-\n", "-r-\r"), $matching) . "<br />\n"; continue; } /* absatz */ $match = array(); if (S::startsWith($html, "\n\n")) { $matching = "\n\n"; if ($level == 0 && $pOpen) { $log .= "Absatz (close p)<br />\n"; $pOpen = FALSE; $ret .= '</p>'; //$ret .= "\n"; // da matching hinzugefügt wird } continue; } /* zeilenumbruch */ if (S::startsWith($html, "\n")) { $matching = "\n"; $log .= "\\n gefunden<br />\n"; /* wir machen ein <br /> aus dem \n, wenn wir im p modus sind */ if ($pOpen) { $ret .= '<br />'; $log .= "in br umwandeln<br />\n"; } continue; } /* prüfen auf html tags (block start, block end, inline tag */ $match = array(); if (Preg::match($html, '/^<(\\/)?([^\\s>]+)((?>[^>])*)>/', $match) > 0) { list($full, $op, $tagName, $rest) = $match; if (in_array($tagName, $blockElements)) { $matching = $full; if ($op != '/') { /* block element start */ if ($pOpen) { $ret .= '</p>'; $log .= "close p<br />\n"; $pOpen = FALSE; } $log .= "block level(" . $level . ") start : '" . $matching . "'<br />\n"; $level++; } else { /* block element end */ $log .= "block level(" . $level . ") end: '" . $matching . "'<br />\n"; $level--; } } else { /* html tag (kein block element) */ $matching = $full; /* p öffnen, wenn es nicht offen ist */ if ($level == 0 && !$pOpen) { $pOpen = TRUE; $log .= "open p<br />\n"; if ($firstP && mb_strlen(trim($ret)) == 0) { $ret .= '<p class="first">'; $firstP = FALSE; } else { $ret .= '<p>'; } } $log .= "inline-tag: '" . $matching . "'<br />\n"; } continue; } /* kein fall hat gegriffen, wir verkürzen um 1 Zeichen */ $matching = HTML::esc(mb_substr($html, 0, 1)); $log .= "zeichen: " . $matching . "<br />\n"; } /* letztes <p> schließen */ if ($pOpen) { $ret .= '</p>' . "\n"; } if ($debug) { print $log; } return $ret; }
public function getRelease() { if (!isset($this->release) && !empty($this->info)) { /* wir holen uns das Release so: meist steht am Ende (xvid|h.264|web-ddl|..etc...)-$release */ // @TODO mal in en Parser auslagern // das ist <Format>-<ReleaseGroup> am Ende des Strings // sowas wie AVC-TVS oder XviD-RSG $this->release = Preg::qmatch($this->info, '/([a-z0-9A-Z]+-[a-zA-Z0-9&]+)$/', 1); /* group darf auch leer sein, dann versuchen wir das release anders zu bekommen */ if (!isset($this->release)) { if (($this->release = Preg::qmatch($this->info, '/S[0-9]+E[0-9]+\\.German\\.Dubbed\\.DL\\.(.*)$/', 1)) !== NULL) { $this->release = str_replace('.', ' ', $this->release); return $this->release; } try { // normalize $this->release = \Psc\Preg::matchArray(array('/(WEB.DL(.*)720p|720p(.*)WEB.DL)/i' => 'WEB-DL 720p', '/(WEB.DL(.*)1080|1080(.*)WEB.DL)/i' => 'WEB-DL 1080', '/720p.ITunesHD/' => 'ITunesHD 720p', '/WEB-DL/i' => 'WEB-DL', '/(dvdrip(.*)xvid|dvdrip(.*)xvid)/i' => 'XviD-DVDRip', '/dvdrip/i' => 'DVDRip'), $this->info); } catch (\Psc\NoMatchException $e) { } } /* jetzt suchen wir noch nach tags, die das Release besser kennzeichnen */ try { $tags = \Psc\Preg::matchFullArray(array('/ITunesHD/i' => 'ITunes', '/WEB.DL/i' => 'WEB-DL', '/dvdrip/i' => 'DVDRip', '/720p/i' => '720p', '/1080p/i' => '1080p', '/1080i/i' => '1080i', '/dvdscr/i' => 'DVDScr', '/blue?ray/i' => 'Bluray', '/xvid/i' => 'XviD'), $this->info); // merge foreach ($tags as $tag) { if (mb_stripos($this->release, $tag) === FALSE) { $this->release .= ' ' . $tag; } } } catch (\Psc\NoMatchException $e) { } $this->release = trim($this->release); if ($this->release === '') { $this->release = NULL; } } return $this->release; }
protected function buildQueryAutoCompleteTerm(array $fields, $term) { $qb = new QueryBuilder($this->_em); $qb->select('e')->from($this->_entityName, 'e'); if (count($fields) > 0 && $term != "") { // term in quotes bedeutet wörtliche suche if (\Psc\Preg::match($term, '/^\\s*("|\')(.*)("|\')\\s*$/', $m)) { $term = $m[2]; foreach ($fields as $field) { $qb->orWhere('e.' . $field . ' = ?1 '); } $qb->setParameter(1, $term); } else { /* normale suche */ foreach ($fields as $field) { $qb->orWhere('e.' . $field . ' = ?1 '); for ($i = 2; $i <= 4; $i++) { $qb->orWhere('e.' . $field . ' LIKE ?' . $i); } } $qb->setParameter(1, $term); $qb->setParameter(2, '%' . $term); $qb->setParameter(3, '%' . $term . '%'); $qb->setParameter(4, $term . '%'); } } return $qb; }
public function stripCommentAsteriks($body) { /* okay, also das Prinzip ist eigentlich: lösche alle Tokens am Anfang der Zeile (deshalb /m) bzw * / am Ende der Zeile da aber bei leeren Zeilen im Docblock bzw. Zeilen ohne * das multi-line-pattern kaputt geht überprüfen wir im callback ob die zeile "leer" ist und fügen dann einen Umbruch ein. Wir behalten quasi die Umbrüche zwischendrin */ //$body = preg_replace_callback('/(^\s*$|^\/\*\*($|\s*)|^\s*\*\/|^\s*\*($|\s*)|\*\/$)/mu', function ($m) { // return (mb_strpos($m[0], '*') !== FALSE) ? NULL : "\n"; //}, $body); $lines = array(); $debug = "\n"; foreach (explode("\n", ltrim($body)) as $line) { $tline = trim($line); $debug .= "'{$tline}'"; $debug .= "\n "; if ($tline === '*') { // nur ein sternchen bedeutet eine gewollte Leerzeile dazwischen $lines[] = NULL; // means zeilenumbruch $debug .= "newline"; } elseif ($tline === '/**' || $tline === '/*' || $tline === '*/') { // top und bottom wollen wir nicht in unserem docBlock haben $debug .= "discard"; } elseif (($content = Preg::qmatch($line, '/^\\s*\\/?\\*+\\s?(.*?)\\s*$/')) !== NULL) { // eine Zeile mit * am Anfang => wir nehmen den $content (Einrückungssafe) // eine Zeile mit /*+ am Anfang => wir nehmen den content (Einrückungssafe) $content = rtrim($content, ' /*'); // read carefully $lines[] = $content; $debug .= "content: '" . $content . "'"; } else { // dies kann jetzt nur noch eine Zeile ohne * sein (also ein kaputter Docblock). Den machen wir heile $lines[] = $line; // preservewhitespace davor? $debug .= "fix: '{$line}'"; } $debug .= "\n"; } $debug .= "ergebnis:\n"; //$debug .= print_r($lines,true); $debug .= "\n\n"; //print $debug; // mit rtrim die leerzeilen nach dem letzten Text entfernen return rtrim(implode("\n", $lines)); // while array_peek(lines) === NULL : array_pop($lines) }
public function parseFrom($string) { $fields = explode("\r\n", Preg::replace($string, '/\\x0D\\x0A[\\x09\\x20]+/', ' ')); array_shift($fields); // status line wegnehmen, denn das wird in den ableitenden geparsed /* message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = <the OCTETs making up the field-value and consisting of either *TEXT or combinations of token, separators, and quoted-string> */ foreach ($fields as $field) { if (Preg::match($field, '/([^:]+): (.+)/m', $match)) { list($NULL, $name, $value) = $match; $name = Preg::replace_callback(mb_strtolower(trim($name)), '/(?<=^|[\\x09\\x20\\x2D])./', function ($m) { return mb_strtoupper($m[0]); }); $this->setField($name, $value); } } }
public static function replaceLinksMarkup($text) { $link = function ($url, $label) { // label is already escaped if (Preg::match($url, '~^([a-zA-Z0-9]+://|www\\.)~')) { return HTML::tag('a', $label, array('href' => $url, 'class' => 'external', 'target' => '_blank')); } else { return HTML::tag('a', $label, array('href' => $url, 'class' => 'internal')); } }; $openLink = preg_quote('[['); $closeLink = preg_quote(']]'); $sepLink = preg_quote('|'); // [[http://www.google.com|This Link points to google]] $text = \Psc\Preg::replace_callback($text, '/' . $openLink . '(.*?)' . $sepLink . '(.*?)' . $closeLink . '/', function ($match) use($link) { return $link($match[1], $match[2]); }); // [[http://www.google.com]] $text = \Psc\Preg::replace_callback($text, '/' . $openLink . '(.*?)' . $closeLink . '/', function ($match) use($link) { return $link($match[1], $match[1]); }); return $text; }
/** * * @param string $source der PHP Code als String */ protected function scan($source) { $source = str_replace(array("\r\n", "\r"), "\n", $source); if ($this->eol != "\n") { $source = str_replace("\n", $this->eol, $source); } /* token get all ist php intern */ $currentLine = 1; foreach (token_get_all($source) as $token) { if (is_string($token)) { switch ($token) { default: $type = self::LITERAL; break; case ',': $type = self::T_COMMA; break; case '.': $type = self::T_DOT; break; case '{': $type = self::T_CBRACE_OPEN; break; case '}': $type = self::T_CBRACE_CLOSE; break; case '(': $type = self::T_BRACE_OPEN; break; case ')': $type = self::T_BRACE_CLOSE; break; case '=': $type = self::T_EQUAL; break; case '&': $type = self::T_AMPERSAND; break; case ';': $type = self::T_SEMICOLON; break; case '+': $type = self::T_PLUS; break; case '-': $type = self::T_MINUS; break; } $t = array('value' => $token, 'type' => $type, 'line' => $currentLine); } else { $t = array('value' => $token[1], 'type' => token_name($token[0]), 'line' => $token[2]); /* fix */ if ($t['type'] == 'T_DOUBLE_COLON') { $t['type'] = 'T_PAAMAYIM_NEKUDOTAYIM'; } $currentLine = $t['line']; } /* whitespace analyisieren */ if ($t['type'] == 'T_WHITESPACE' && $this->parseWhitespace) { Preg::match($t['value'], '/([^\\n]+|\\n)/g', $matches); foreach ($matches as $m) { // das geht kaputt mit $this->eol anders als "\n" list($NULL, $white) = $m; if ($white === "\n") { $currentLine++; $type = self::T_EOL; } else { $type = self::T_PLAIN_WHITESPACE; } $this->tokens[] = array('value' => $white, 'type' => $type, 'line' => $currentLine); } } elseif ($t['type'] == 'T_COMMENT' && $this->parseWhitespace) { // EOL abschneiden und als einzelnes T_EOL dahinter machen if (S::endsWith($t['value'], $this->eol)) { $t['value'] = mb_substr($t['value'], 0, -1); $this->tokens[] = $t; // comment hinzufügen $currentLine++; $this->tokens[] = array('value' => "\n", 'type' => self::T_EOL, 'line' => $currentLine); } else { $this->tokens[] = $t; // comment hinzufügen, auch wenn er kein EOL hata } } else { if (trim($t['value']) == '' && mb_strpos($t['value'], $this->eol) !== FALSE) { // leer und mit umbruch $currentLine += mb_substr_count($t['value'], $this->eol); } $this->tokens[] = $t; } } return $this; }