/** * Handles an uploaded file by putting it in the $targetDir. * * @param UploadedFile $uploadedFile File object that has been uploaded - usually taken from Request object. * @param string $targetDir [optional] Where to (relatively to the storage root dir) put the file? * @param array $allowed [optional] What files are allowed? If not matching then will throw exception. * @param int $maxFileSize [optional] What is the maximum allowed file size for this file? * @return File */ public function handleUploadedFile(UploadedFile $uploadedFile, $targetDir = '/', array $allowed = array(), $maxFileSize = 0) { array_walk($allowed, function ($ext) { return strtolower($ext); }); $targetDir = trim($targetDir, '/'); $targetDir = $this->path . $targetDir . (empty($targetDir) ? '' : '/'); $filenameElements = explode('.', $uploadedFile->getClientOriginalName()); $extension = array_pop($filenameElements); $extension = strtolower($extension); $filename = implode('.', $filenameElements); $targetName = StringUtils::fileNameFriendly($filename . '-' . StringUtils::random() . '.' . $extension); $targetPath = $targetDir . $targetName; // create unique file name while (file_exists($targetPath)) { $targetName = StringUtils::fileNameFriendly($filename . '-' . StringUtils::random() . '.' . $extension); $targetPath = $targetDir . $targetName; } // basic check for allowed type if (!empty($allowed) && !in_array($extension, $allowed)) { throw new FileException('The uploaded file is not of a valid type (allowed: ' . implode(', ', $allowed) . ').'); } // basic check for max allowed size if ($maxFileSize && $uploadedFile->getSize() > $maxFileSize) { throw new FileException('The uploaded file is too big (max allowed size is ' . StringUtils::bytesToString($maxFileSize) . ').'); } try { $movedFile = $uploadedFile->move(rtrim($targetDir, '/'), $targetName); } catch (SfFileException $e) { // if exception thrown then convert it to our exception throw new FileException($e->getMessage(), $e->getCode()); } $file = $this->convertSfFileToStorageFile($movedFile); return $file; }
public function testHideCaller() { try { throw new InvalidArgumentException('string', new \stdClass(), 1, true); } catch (InvalidArgumentException $e) { $this->assertFalse(StringUtils::search($e->getMessage(), get_called_class() . '->testHideCaller()')); } }
/** * Logs with an arbitrary level. * * Also adds few items to the context array. * * @param mixed $level * @param string $message * @param array $context * @return null */ public function log($level, $message, array $context = array()) { $context = array_merge(array('_name' => $this->name, '_channel' => $this->name, '_uuid' => $this->uuid, '_tags' => isset($context['_tags']) ? is_array($context['_tags']) ? $context['_tags'] : explode(',', trim((string) $context['_tags'])) : array(), '_level' => $level, '_timestamp' => Timer::getMicroTime(), '_date' => new \DateTime()), $context); $message = StringUtils::interpolate((string) $message, $context); foreach ($this->writers as $writer) { $writer->log($level, $message, $context); } }
public function testFunctionIdentification() { try { throw new NotImplementedException(); } catch (NotImplementedException $e) { $this->assertTrue(StringUtils::search($e->getMessage(), get_called_class() . '->testFunctionIdentification()')); } }
/** * Constructor. * * @param string $expected Expected type. * @param mixed $actual Actual argument given. * @param int $number [optional] Argument number. * @param bool $hideCaller [optional] Should the function that has thrown this exception be hidden? Default: `false`. */ public function __construct($expected, $actual, $number = 1, $hideCaller = false) { $trace = Debugger::getPrettyTrace(debug_backtrace()); $type = Debugger::getType($actual); $type = $type === 'string' ? $type . ' ("' . StringUtils::truncate($actual, 50) . '")' : $type; if (!$hideCaller && isset($trace[1])) { $message = $trace[1]['function'] . ' expected argument ' . $number . ' to be ' . $expected . ', ' . $type . ' given.'; } else { $message = 'Expected argument ' . $number . ' to be ' . $expected . ', ' . $type . ' given.'; } parent::__construct($message); }
/** * Execute the command. */ public function execute() { $title = $this->ask('Article Title', null, array(), function ($answer) { if (empty($answer)) { throw new \InvalidArgumentException('The title cannot be empty'); } return $answer; }); $slug = $this->ask('Article Slug', StringUtils::urlFriendly($title)); $image = $this->ask('Article Cover Image Path'); $markdownFile = $this->get('blog.writer')->create($title, $slug, $image); $this->writeln('Created article <info>' . $title . '</info> in <comment>' . $markdownFile . '</comment>'); }
/** * Logs with an arbitrary level. * * @param mixed $level * @param string $message * @param array $context * @return null */ public function log($level, $message, array $context = array()) { if (!$this->isEnabled()) { return false; } $tags = array(); if (isset($context['_tags'])) { $tags = is_array($context['_tags']) ? $context['_tags'] : explode(',', trim((string) $context['_tags'])); unset($context['_tags']); } $timer = null; if (isset($context['_timer']) && $context['_timer'] instanceof Timer) { $timer = $context['_timer']; unset($context['_timer']); } $this->_log[] = array('message' => StringUtils::parseVariables((string) $message, $context), 'context' => $context, '_tags' => $tags, '_timestamp' => Timer::getMicroTime(), '_time' => new \DateTime(), '_level' => $level, '_timer' => $timer); }
/** * Constructor. * * @param string $key Criteria expression key that includes property name and an optional operator prefixed with `:` * e.g. `id:not`. * @param mixed $value Value for criteria filter. * * @throws InvalidOperatorException When invalid or unsupported operator given. */ public function __construct($key, $value) { // explode the key in search for an operator $explodedKey = explode(':', $key); // just specify the property name $this->property = $explodedKey[0]; if (empty($this->property)) { throw new \InvalidArgumentException(sprintf('Property name part of a key should not be empty in criteria expression, "%s" given.', $key)); } // if there was no operator specified then use the EQUALS operator by default $operator = isset($explodedKey[1]) ? strtolower($explodedKey[1]) : 'eq'; $operatorFn = StringUtils::toCamelCase($operator, '_') . 'Operator'; // if there is no function defined to handle this operator then throw an exception if (!method_exists($this, $operatorFn)) { throw new InvalidOperatorException(sprintf('Unrecognized operator passed in criteria, "%s" given.', $key)); } $this->{$operatorFn}($value); }
/** * Create an article. * * Returns path to the created markdown file. * * @param string $title Title of the article. * @param string $slug [optional] Slug of the article. If ommitted, it will be built based on the title. * @param string $image [optional] Path to cover image, relative to the web root folder. * * @return string */ public function create($title, $slug = null, $image = null) { $slug = $slug ? StringUtils::urlFriendly($slug) : StringUtils::urlFriendly($title); $articles = $this->reader->load(); // check if maybe there already is such article if (ArrayUtils::search($articles, 'slug', $slug) !== false) { throw new NotUniqueException('There already is a blog article with a slug "' . $slug . '".'); } // create a markdown post $markdown = $title . NL . '==========' . NL . date('Y-m-d') . NL . ($image ? '![cover](' . $image . ')' . NL : '') . NL; $markdownFile = $this->articlesDir . $slug . '.md'; // create the articles directory if doesn't exist $this->filesystem->dumpFile($markdownFile, $markdown); // add to articles array array_unshift($articles, array('slug' => $slug, 'title' => $title)); $this->writer->write($this->dataFile, $articles); return $markdownFile; }
/** * Logs with an arbitrary level. * * @param mixed $level * @param string $message * @param array $context * @return null */ public function log($level, $message, array $context = array()) { // add color to all injected variables $message = preg_replace_callback('/{([\\w\\d_\\.]+)}/is', function ($matches) { $var = $matches[1]; return '<info>{' . $var . '}</info>'; }, $message); $message = StringUtils::interpolate($message, $context); $alert = ''; switch ($level) { case LogLevel::ALERT: case LogLevel::CRITICAL: case LogLevel::EMERGENCY: case LogLevel::ERROR: $alert = '<error> ' . $level . ' </error> '; break; case LogLevel::NOTICE: case LogLevel::WARNING: $alert = '<fg=yellow;options=bold>' . $level . '</fg=yellow;options=bold> '; break; } $this->output->writeln($alert . $message . ' [@mem: ' . StringUtils::bytesToString(Timer::getCurrentMemory()) . ']'); }
/** * Handles invoking magic methods `::findBy*` and `::findOneBy*`. * * @param string $method Called method name. * @param array $arguments Array of arguments the method was called with. * * @return array|object|null * * @throws \InvalidArgumentException If any of the arguments is invalid. * @throws \BadMethodCallException When couldn't resolve to a valid method. */ public function __call($method, array $arguments) { if (!isset($arguments[0])) { throw new \InvalidArgumentException(sprintf('Missing 1st argument for method ::%s', $method)); } $params = []; if (isset($arguments[1])) { if (!is_array($arguments[1])) { throw new \InvalidArgumentException(sprintf('2nd argument for method ::%s must be an array, %s given.', $method, Debugger::getType($arguments[1]))); } $params = $arguments[1]; } if (strpos($method, 'findBy') === 0) { $property = StringUtils::toSeparated(substr($method, 6), '_'); return $this->find([$property => $arguments[0]], $params); } if (strpos($method, 'findOneBy') === 0) { $property = StringUtils::toSeparated(substr($method, 9), '_'); return $this->findOne([$property => $arguments[0]], $params); } throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s', __CLASS__, $method)); }
public function testGetMemoryUsage() { $timer = new Timer(); // fill a lot of memory $array = array(); for ($i = 0; $i < 99999; $i++) { $array[] = StringUtils::random(32); } $memory = $timer->getMemoryUsage(); $this->assertInternalType('int', $memory); $this->assertGreaterThan(0, $memory); }
/** * Parses arguments of a method call. * * @param array $arguments Arguments. * * @return array */ private function parseCallArguments(array $arguments) { $args = []; foreach ($arguments as $argument) { if (is_object($argument)) { $args[] = '<comment>(object)</comment> ' . StringUtils::truncate(Debugger::getClass($argument), 32, '...', StringUtils::TRUNCATE_MIDDLE); } elseif (is_array($argument)) { $args[] = '<comment>(array)</comment> ' . StringUtils::truncate(json_encode($argument), 32, '...', StringUtils::TRUNCATE_MIDDLE); } elseif (is_string($argument)) { $args[] = sprintf("'%s'", StringUtils::truncate($argument, 32, '...', StringUtils::TRUNCATE_MIDDLE)); } else { $args[] = $argument; } } return implode(', ', $args); }
public function testSearch() { $this->assertTrue(StringUtils::search('lorem ipsum dolor sit amet', 'sit')); $this->assertTrue(StringUtils::search('lorem ipsum dolor sit amet', array('undefined', 'ipsum'))); $this->assertTrue(StringUtils::search('LOREM ipsum DOLOR sit amet', array('undefined', 'ipsum'))); $this->assertFalse(StringUtils::search('lorem ipsum dolor sit amet', 'what')); $this->assertFalse(StringUtils::search('', array())); $this->assertFalse(StringUtils::search('lorem ipsum dolor sit amet', array('what', 'happened', 'to', 'us'))); }
/** * Runs the application in context of the given mode and using the given runner function. * * The last argument is a callback that will be invoked by this method and it should contain * execution logic specific to the given mode. * * Returns whatever the runner returns (which should be a result of running the application). * * @param AbstractApplication $application Application to be ran. * @param int $mode Mode in which the application should be ran. * One of the `Framework::MODE_*` constants. * @param callable $runner Closure that is responsible for actually running * the application in appropriate mode. * @return mixed */ protected function doRunApplication(AbstractApplication $application, $mode, $runner) { $timer = new Timer(); $container = $application->getContainer(); // container can now know in what mode its running $container->setParameter('mode', $mode); // run modules and the app foreach ($application->getModules() as $module) { $module->run(); } $application->run(); // run using the passed runner $result = call_user_func($runner); // log benchmark data $time = $timer->stop(); $memory = $timer->getMemoryUsage(); $container->get('splot.logger')->debug('Application run phase in mode "{mode}" finished in {time} ms and used {memory} memory.', array('mode' => self::modeName($mode), 'env' => $container->getParameter('env'), 'debug' => $container->getParameter('debug'), 'time' => $time, 'memory' => StringUtils::bytesToString($memory), '@stat' => 'splot.run.' . self::modeName($mode), '@time' => $time, '@memory' => $memory)); return $result; }
/** * Creates a setter name for the given object property name. * * Converts `snake_notation` to `camelCase`. * * Example: * * echo \MD\Foundation\Utils\ObjectUtils::setter('property_name'); * // -> `setPropertyName` * * @param string $property Property name. * @return string */ public static function setter($property) { return 'set' . ucfirst(StringUtils::toCamelCase($property, '_')); }
/** * Overload setters and getters and do what they would normally do. * * This enables "automatic"/"magic" setters and getters on an object. * * $object = new MD\Foundation\MagicObject(); * $object->setTitle('Lorem ipsum'); * echo $object->getTitle(); * // -> 'Lorem ipsum' * * $object->setSomeRandomAnotherProperty(true); * echo $object->getSomeRandomAnotherProperty(); * // -> true * * It also creates "issers" that always return `boolean` values. * * $object = new MD\Foundation\MagicObject(); * $object->setEnabled(true); * echo $object->isEnabled(); * // -> true * * If there is no property for the called getter then it will return `null`. * * @param string $method Method name. * @param array $arguments Array of arguments. * @return mixed|null */ public final function __call($method, $arguments) { $type = strtolower(substr($method, 0, 3)); // called a setter or a getter ? if ($type === 'set' || $type === 'get') { $property = lcfirst(substr($method, 3)); // decide on property name by checking if a camelCase exists first // and if not try the under_scored $property = isset($this->__properties[$property]) ? $property : StringUtils::toSeparated($property, '_'); if ($type === 'set') { // if a setter then require at least one argument if (!isset($arguments[0])) { return trigger_error('Function ' . get_called_class() . '::' . $method . '()" requires one argument, none given.', E_USER_ERROR); } return $this->__setProperty($property, $arguments[0]); } else { if ($type === 'get') { return $this->__getProperty($property); } } // @codeCoverageIgnoreStart } // @codeCoverageIgnoreEnd // called an isser? if (strtolower(substr($method, 0, 2)) === 'is') { $property = lcfirst(substr($method, 2)); $property = isset($this->__properties[$property]) ? $property : StringUtils::toSeparated($property, '_'); $value = $this->__getProperty($property); // cast '0' as false return !$value || $value == '0' ? false : true; } // undefined method called! return trigger_error('Call to undefined method ' . get_called_class() . '::' . $method . '().', E_USER_ERROR); }
/** * Renders the final response and sends it back to the client. * * @param Response $response HTTP Response to be sent. * @param Request $request The original HTTP request for context. */ public function sendResponse(Response $response, Request $request) { // prepare the response for sending (will tweak some headers based on the request) $response->prepare($request); // trigger WillSendResponse event for any last minute changes $this->container->get('event_manager')->trigger(new WillSendResponse($response, $request)); $timer = $this->container->get('splot.timer'); $time = $timer->getDuration(); $memory = $timer->getCurrentMemoryPeak(); $memoryString = StringUtils::bytesToString($memory); $this->logger->debug('Rendering response for {method} {uri} took {time} ms and used {memory} memory.', array('method' => $request->getMethod(), 'uri' => $request->getRequestUri(), 'memory' => $memoryString, 'time' => $time, '@stat' => 'splot.render', '@time' => $time, '@memory' => $memory)); // and finally send out the response $response->send(); }
/** * Verifies the given email address does it fit the patterns of email addresses for the Mailer. * * It can be an email string, an array of email strings or an array where keys are emails and values are names. * * @param string|array $address Address to verify. * @param bool $allowMulti Are multiple emails allowed? Default: true. * @return bool * * @throws InvalidArgumentException When $address is neither string nor array. */ public function verifyEmailAddress($address, $allowMulti = true) { if (!is_string($address) && !is_array($address)) { throw new InvalidArgumentException('string or array', $address); } if (is_string($address)) { return StringUtils::isEmail($address); } if (!$allowMulti && count($address) > 1) { return false; } foreach ($address as $key => $value) { if (is_string($key)) { if (!StringUtils::isEmail($key)) { return false; } } else { if (!StringUtils::isEmail($value)) { return false; } } } return true; }