<?php

namespace Orchestra\View\Console;

use Illuminate\Support\Str;
use InvalidArgumentException;
use Orchestra\View\Theme\Finder;
use Illuminate\Support\Collection;
use Orchestra\View\Theme\Manifest;
use Illuminate\Console\ConfirmableTrait;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;

class ActivateCommand extends Command
{
    use ConfirmableTrait;

    /**
     * Theme finder instance.
     *
     * @var \Orchestra\View\Theme\Finder
     */
    protected $finder;

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'theme:activate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Set active themes in the application.';

    /**
     * Available themes type.
     *
     * @var array
     */
    protected $type = ['frontend', 'backend'];

    /**
     * Construct a new status command.
     *
     * @param  \Orchestra\View\Theme\Finder $finder
     */
    public function __construct(Finder $finder)
    {
        $this->finder = $finder;

        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        if (! $this->confirmToProceed()) {
            return;
        }

        $group = Str::lower($this->argument('group'));
        $id = Str::lower($this->argument('id'));

        $theme = $this->getAvailableTheme($group)->get($id);

        if ($this->validateProvidedTheme($group, $id, $theme)) {
            $this->laravel['orchestra.memory']->set("site.theme.{$group}", $theme->get('uid'));

            $this->info("Theme [{$theme->get('name')}] activated on group [{$group}].");
        }
    }

    /**
     * Validate provided theme.
     *
     * @param  string  $group
     * @param  string|int  $id
     * @param  object|null  $theme
     *
     * @throws \InvalidArgumentException
     *
     * @return bool
     */
    protected function validateProvidedTheme(string $group, $id, $theme): bool
    {
        if (! \in_array($group, $this->type)) {
            throw new InvalidArgumentException("Invalid theme name [{$group}], should either be 'frontend' or 'backend'.");
        }

        if (\is_null($theme)) {
            throw new InvalidArgumentException("Invalid Theme ID [{$id}], or is not available for '{$group}'.");
        }

        return true;
    }

    /**
     * Get all available theme by type.
     *
     * @param  string  $type
     *
     * @return \Illuminate\Support\Collection
     */
    protected function getAvailableTheme(string $type): Collection
    {
        $themes = $this->finder->detect();

        return $themes->filter(function (Manifest $manifest) use ($type) {
            $group = $manifest->get('type');

            if (! empty($group) && ! \in_array($type, $group)) {
                return;
            }

            return $manifest;
        });
    }

    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return [
            ['group', InputArgument::REQUIRED, 'Either frontend or backend.'],
            ['id', InputArgument::REQUIRED, 'Theme ID.'],
        ];
    }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return [
            ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production.'],
        ];
    }
}


<?php
/*
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

namespace MpaCustomDoctrineHydrator\Form\Annotation;

use Doctrine\Common\Persistence\ObjectManager;
use DoctrineORMModule\Form\Annotation\AnnotationBuilder as DoctrineAnnotationBuilder;
use Zend\EventManager\EventManagerInterface;
use Zend\Form\Annotation\AnnotationBuilder as ZendAnnotationBuilder;
use Zend\Form\Factory;
use Zend\Form\FormElementManager;

class AnnotationBuilder extends DoctrineAnnotationBuilder
{
    protected $formElementManager;

    /**
     * @param ObjectManager      $objectManager
     * @param FormElementManager $formElementManager
     */
    public function __construct(ObjectManager $objectManager, FormElementManager $formElementManager)
    {
        $this->objectManager      = $objectManager;
        $this->formElementManager = $formElementManager;
        /**
         * We set the FEM as form factory so the ZF2 AnnotationBuilder
         * is aware of custom form elements names
         */
        $this->formFactory = new Factory($this->formElementManager);
    }

    /**
     * {@inheritDoc}
     */
    public function setEventManager(EventManagerInterface $events)
    {
        ZendAnnotationBuilder::setEventManager($events);

        $this->getEventManager()
            ->attach(new ElementAnnotationsListener($this->objectManager, $this->formElementManager));

        return $this;
    }
}


<?php

namespace Orchestra\View;

use BadMethodCallException;

class Decorator
{
    /**
     * The registered custom macros.
     *
     * @var array
     */
    protected $macros = [];

    /**
     * Registers a custom macro.
     *
     * @param  string  $name
     * @param  \Closure  $macro
     *
     * @return void
     */
    public function macro(string $name, callable $macro): void
    {
        $this->macros[$name] = $macro;
    }

    /**
     * Render the macro.
     *
     * @param  string  $name
     * @param  mixed  $parameters
     *
     * @throws \BadMethodCallException
     *
     * @return string
     */
    public function render(string $name, ...$parameters)
    {
        if (! isset($this->macros[$name])) {
            throw new BadMethodCallException("Method [$name] does not exist.");
        }

        return $this->macros[$name](...$parameters);
    }

    /**
     * Dynamically handle calls to custom macros.
     *
     * @param  string  $method
     * @param  array   $parameters
     *
     * @return mixed
     */
    public function __call(string $method, array $parameters)
    {
        \array_unshift($parameters, $method);

        return $this->render($method, ...$parameters);
    }
}


<?php

namespace Orchestra\View;

use Orchestra\View\Console\DetectCommand;
use Orchestra\View\Console\ActivateCommand;
use Orchestra\View\Console\OptimizeCommand;
use Illuminate\Contracts\Foundation\Application;
use Orchestra\Support\Providers\CommandServiceProvider as ServiceProvider;

class CommandServiceProvider extends ServiceProvider
{
    /**
     * The commands to be registered.
     *
     * @var array
     */
    protected $commands = [
        'Activate' => 'orchestra.view.command.activate',
        'Detect' => 'orchestra.view.command.detect',
        'Optimize' => 'orchestra.view.command.optimize',
    ];

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function registerActivateCommand(): void
    {
        $this->app->singleton('orchestra.view.command.activate', function (Application $app) {
            return new ActivateCommand($app->make('orchestra.theme.finder'));
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function registerDetectCommand(): void
    {
        $this->app->singleton('orchestra.view.command.detect', function (Application $app) {
            return new DetectCommand($app->make('orchestra.theme.finder'));
        });
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function registerOptimizeCommand(): void
    {
        $this->app->singleton('orchestra.view.command.optimize', function () {
            return new OptimizeCommand();
        });
    }
}


<?php
/*
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

namespace MpaCustomDoctrineHydrator\Filter;

use DateTime;
use Zend\Filter\AbstractFilter;
use Zend\Filter\FilterInterface;

class DateToDateTime extends AbstractFilter implements FilterInterface
{
    protected $format = 'Y.m.d';

    /**
     * @param  array|null $options
     * @return self
     */
    public function __construct($options = null)
    {
        if (null !== $options && self::isOptions($options)) {
            $this->setOptions($options);
        }
    }

    /**
     * @param  string $format
     * @return self
     */
    public function setFormat($format)
    {
        $this->format = $format;

        return $this;
    }

    /**
     * @return string
     */
    public function getFormat()
    {
        return $this->format;
    }

    /**
     * Allow the format key to be format and date_format
     * For consistency with the ZF2 Date Element
     *
     * @param  array $options
     * @return self
     */
    public function setOptions($options)
    {
        $this->format = isset($options['date_format']) ? $options['date_format'] : $options['format'];

        return $this;
    }

    /**
     * Converts a date string to a \DateTime
     * according to the date format given
     *
     * @param  string $value
     * @return \DateTime|string
     */
    public function filter($value)
    {
        /**
         * We try to create a \DateTime according to the format
         * If the creation fails, we return the string itself
         * so it's treated by Validate\Date
         */

        $date = (is_int($value))
            ? date_create("@$value") // from timestamp
            : DateTime::createFromFormat($this->format, $value);

        // Invalid dates can show up as warnings (ie. "2007-02-99")
        // and still return a DateTime object
        $errors = DateTime::getLastErrors();

        if ($errors['warning_count'] > 0 || $date === false) {
            return $value;
        }

        return $date;
    }
}


<?php

namespace Orchestra\Extension\Console;

use Illuminate\Support\Fluent;
use Illuminate\Console\ConfirmableTrait;
use Orchestra\Extension\Processors\Migrator as Processor;
use Orchestra\Contracts\Extension\Listener\Migrator as Listener;

class PublishCommand extends ExtensionCommand implements Listener
{
    use ConfirmableTrait;

    /**
     * The console command signature.
     *
     * @var string
     */
    protected $signature = 'extension:update
        {name : Extension name.}
        {--force : Force the operation to run when in production.}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Run migration and asset publishing for an extension.';

    /**
     * Execute the console command.
     *
     * @param  \Orchestra\Extension\Processor\Migrator  $migrator
     *
     * @return void
     */
    public function handle(Processor $migrator)
    {
        if (! $this->confirmToProceed()) {
            return;
        }

        return $migrator($this, new Fluent(['name' => $this->argument('name')]));
    }

    /**
     * Response when extension migration has failed.
     *
     * @param  \Illuminate\Support\Fluent  $extension
     * @param  array  $errors
     *
     * @return mixed
     */
    public function migrationHasFailed(Fluent $extension, array $errors)
    {
        $this->error("Extension [{$extension->get('name')}] update has failed.");
    }

    /**
     * Response when extension migration has succeed.
     *
     * @param  \Illuminate\Support\Fluent  $extension
     *
     * @return mixed
     */
    public function migrationHasSucceed(Fluent $extension)
    {
        $this->info("Extension [{$extension->get('name')}] updated.");
    }
}


<?php

namespace PhpDocReader;

/**
 * Class Reflector
 * @author  Lucas A. de Araújo <lucas@painapp.com.br>
 * @package PhpDocReader
 */
class Reflector
{
    /**
     * Retorna a documentação de uma classe ou propriedade.
     * @param string $class
     * @param null $property
     * @return string
     */
    public static function getDoc($class, $property = null)
    {
        if(!is_null($property))
            return self::getPropertyDoc($class, $property);

        return self::getClassDoc($class);
    }

    /**
     * Retorna a documentação de classe
     * @param $class
     * @return string
     */
    private static function getClassDoc($class)
    {
        $reflection = new \ReflectionClass($class);
        return $reflection->getDocComment();
    }

    /**
     * Retorna a documentação da propriedade.
     * @param $class
     * @param $property
     * @return string
     */
    private static function getPropertyDoc($class, $property)
    {
        $reflection = new \ReflectionProperty($class, $property);
        return $reflection->getDocComment();
    }
}


<?php

namespace Orchestra\View\Console;

use Orchestra\View\Theme\Finder;
use Orchestra\View\Theme\Manifest;

class DetectCommand extends Command
{
    /**
     * Theme finder instance.
     *
     * @var \Orchestra\View\Theme\Finder
     */
    protected $finder;

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'theme:detect';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Detect available themes in the application.';

    /**
     * Construct a new status command.
     *
     * @param  \Orchestra\View\Theme\Finder $finder
     */
    public function __construct(Finder $finder)
    {
        $this->finder = $finder;

        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function handle()
    {
        $memory = $this->laravel['orchestra.memory'];

        $themes = $this->finder->detect();
        $frontend = $memory->get('site.theme.frontend');
        $backend = $memory->get('site.theme.backend');

        $header = ['ID', 'Theme Name', 'Frontend', 'Backend'];

        $this->table($header, $themes->map(function ($theme, $id) use ($backend, $frontend) {
            return [
                $id,
                $theme->get('name'),
                $this->getThemeStatus('frontend', $theme, ($id == $frontend)),
                $this->getThemeStatus('backend', $theme, ($id == $backend)),
            ];
        })->all());
    }

    /**
     * Get theme status.
     *
     * @param  string  $type
     * @param  \Orchestra\View\Theme\Manifest  $theme
     * @param  bool  $active
     *
     * @return string
     */
    protected function getThemeStatus(string $type, Manifest $theme, bool $active = false): string
    {
        if ($active === true) {
            return '   ✓';
        }

        $group = $theme->get('type');

        if (! empty($group) && ! in_array($type, $group)) {
            return '   ✗';
        }

        return '';
    }
}


<?php

namespace Orchestra\Extension;

use Illuminate\Http\Request;
use Illuminate\Contracts\Config\Repository;
use Orchestra\Contracts\Extension\StatusChecker as StatusCheckerContract;

class StatusChecker implements StatusCheckerContract
{
    /**
     * Config instance.
     *
     * @var \Illuminate\Contracts\Config\Repository
     */
    protected $config;

    /**
     * Request instance.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * Mode status.
     *
     * @var string|null
     */
    protected $status;

    /**
     * Construct a new Application instance.
     *
     * @param  \Illuminate\Contracts\Config\Repository  $config
     * @param  \Illuminate\Http\Request  $request
     */
    public function __construct(Repository $config, Request $request)
    {
        $this->config = $config;
        $this->request = $request;
    }

    /**
     * Check current mode is equal given $mode.
     *
     * @param  string  $mode
     *
     * @return bool
     */
    public function is(string $mode): bool
    {
        return $this->mode() === $mode;
    }

    /**
     * Check current mode is not equal given $mode.
     *
     * @param  string  $mode
     *
     * @return bool
     */
    public function isNot(string $mode): bool
    {
        return $this->mode() !== $mode;
    }

    /**
     * Get current mode.
     *
     * @return string
     */
    public function mode(): string
    {
        if (\is_null($this->status)) {
            $this->verifyStatus();
        }

        return $this->status;
    }

    /**
     * Verify safe mode status.
     *
     * @return void
     */
    protected function verifyStatus(): void
    {
        $config = $this->config->get('orchestra/extension::mode', 'normal');
        $input = $this->request->input('_mode', $config);

        if ($input == 'safe') {
            $this->enableSafeMode();
        } else {
            $this->disableSafeMode();
        }
    }

    /**
     * Disable safe mode.
     *
     * @return void
     */
    protected function disableSafeMode(): void
    {
        $this->config->set('orchestra/extension::mode', $this->status = 'normal');
    }

    /**
     * Enable safe mode.
     *
     * @return void
     */
    protected function enableSafeMode(): void
    {
        $this->config->set('orchestra/extension::mode', $this->status = 'safe');
    }
}


<?php

namespace Orchestra\Extension;

use RuntimeException;
use Illuminate\Support\Collection;
use Illuminate\Filesystem\Filesystem;
use Orchestra\Contracts\Support\ManifestRuntimeException;
use Orchestra\Contracts\Extension\Finder as FinderContract;

class Finder implements FinderContract
{
    /**
     * Filesystem instance.
     *
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $files;

    /**
     * Application and base path configuration.
     *
     * @var array
     */
    protected $config = [];

    /**
     * List of paths.
     *
     * @var array
     */
    protected $paths = [];

    /**
     * Default manifest options.
     *
     * @var array
     */
    protected $manifestOptions = [
        'name' => null,
        'description' => null,
        'author' => null,
        'url' => null,
        'version' => '*',
        'config' => [],
        'autoload' => [],
        'provides' => [],
        'plugin' => null,
    ];

    /**
     * List of reserved name.
     *
     * @var array
     */
    protected $reserved = [
        'orchestra',
        'resources',
        'orchestra/asset',
        'orchestra/auth',
        'orchestra/debug',
        'orchestra/extension',
        'orchestra/facile',
        'orchestra/foundation',
        'orchestra/html',
        'orchestra/memory',
        'orchestra/messages',
        'orchestra/model',
        'orchestra/notifier',
        'orchestra/optimize',
        'orchestra/platform',
        'orchestra/resources',
        'orchestra/support',
        'orchestra/testbench',
        'orchestra/view',
        'orchestra/widget',
    ];

    /**
     * Construct a new finder.
     *
     * @param  \Illuminate\Filesystem\Filesystem  $files
     * @param  array  $config
     */
    public function __construct(Filesystem $files, array $config)
    {
        $this->files = $files;
        $this->config = $config;

        $app = \rtrim($config['path.app'], '/');
        $base = \rtrim($config['path.base'], '/');

        // In most cases we would only need to concern with the following
        // path; application folder, vendor folders and workbench folders.
        $this->paths = [
            "{$app}",
            "{$base}/vendor/*/*",
        ];
    }

    /**
     * Add a new path to finder.
     *
     * @param  string  $path
     *
     * @return $this
     */
    public function addPath(string $path)
    {
        $path = \rtrim($path, '/');

        if (! \in_array($path, $this->paths)) {
            $this->paths[] = $path;
        }

        return $this;
    }

    /**
     * Detect available extensions.
     *
     * @return \Illuminate\Support\Collection
     */
    public function detect()
    {
        $extensions = [];
        $packages = $this->getComposerLockData();

        // Loop each path to check if there orchestra.json available within
        // the paths. We would only treat packages that include orchestra.json
        // as an Orchestra Platform extension.
        foreach ($this->paths as $key => $path) {
            $manifests = $this->files->glob($this->resolveExtensionPath("{$path}/orchestra.json"));

            // glob() method might return false if there an errors, convert
            // the result to an array.
            \is_array($manifests) || $manifests = [];

            foreach ($manifests as $manifest) {
                $name = \is_numeric($key)
                            ? $this->guessExtensionNameFromManifest($manifest, $path)
                            : $key;

                if (! \is_null($name)) {
                    $lockContent = $packages->firstWhere('name', $name);
                    $extensions[$name] = $this->getManifestContents($manifest, $lockContent);
                }
            }
        }

        return new Collection($extensions);
    }

    /**
     * Get manifest contents.
     *
     * @param  string  $manifest
     * @param  array|null  $lockContent
     *
     * @throws \Orchestra\Contracts\Support\ManifestRuntimeException
     *
     * @return array
     */
    protected function getManifestContents(string $manifest, ?array $lockContent): array
    {
        $path = $sourcePath = $this->guessExtensionPath($manifest);
        $jsonable = \json_decode($this->files->get($manifest), true);

        // If json_decode fail, due to invalid json format. We going to
        // throw an exception so this error can be fixed by the developer
        // instead of allowing the application to run with a buggy config.
        if (\is_null($jsonable)) {
            throw new ManifestRuntimeException("Cannot decode file [{$manifest}]");
        }

        if (\is_array($lockContent)) {
            foreach (['description', 'version'] as $type) {
                $jsonable[$type] = $lockContent[$type] ?? $jsonable[$type] ?? null;
            }
        }

        $path = $jsonable['path'] ?? $path;

        $paths = [
            'path' => \rtrim($path, '/'),
            'source-path' => \rtrim($sourcePath, '/'),
        ];

        // Generate a proper manifest configuration for the extension. This
        // would allow other part of the application to use this configuration
        // to migrate, load service provider as well as preload some
        // configuration.
        return \array_merge($paths, $this->generateManifestConfig($jsonable));
    }

    /**
     * Generate a proper manifest configuration for the extension. This
     * would allow other part of the application to use this configuration
     * to migrate, load service provider as well as preload some
     * configuration.
     *
     * @param  array  $config
     *
     * @return array
     */
    protected function generateManifestConfig(array $config): array
    {
        // Assign extension manifest option or provide the default value.
        return Collection::make($this->manifestOptions)->mapWithKeys(function ($default, $key) use ($config) {
            return [$key => ($config[$key] ?? $default)];
        })->all();
    }

    /**
     * Get composer.lock data.
     *
     * @return \Illuminate\Support\Collection
     */
    protected function getComposerLockData(): Collection
    {
        $json = [];

        if ($this->files->exists($this->config['path.composer'])) {
            $json = \json_decode($this->files->get($this->config['path.composer']), true);
        }

        return Collection::make($json['packages'] ?? []);
    }

    /**
     * Guess extension name from manifest.
     *
     * @param  string  $manifest
     * @param  string  $path
     *
     * @throws \RuntimeException
     *
     * @return string|null
     */
    public function guessExtensionNameFromManifest(string $manifest, string $path): ?string
    {
        if (\rtrim($this->config['path.app'], '/') === \rtrim($path, '/')) {
            return 'app';
        }

        list($vendor, $package) = $namespace = $this->resolveExtensionNamespace($manifest);

        if (\is_null($vendor) && \is_null($package)) {
            return null;
        }

        // Each package should have vendor/package name pattern.
        $name = \trim(\implode('/', $namespace));

        return $this->validateExtensionName($name);
    }

    /**
     * Guess extension path from manifest file.
     *
     * @param  string  $path
     *
     * @return string
     */
    public function guessExtensionPath(string $path): string
    {
        $path = \str_replace('orchestra.json', '', $path);
        $app = \rtrim($this->config['path.app'], '/');
        $base = \rtrim($this->config['path.base'], '/');

        return \str_replace(
            ["{$app}/", "{$base}/vendor/", "{$base}/"],
            ['app::', 'vendor::', 'base::'],
            $path
        );
    }

    /**
     * Register the extension.
     *
     * @param  string  $name
     * @param  string  $path
     *
     * @return bool
     */
    public function registerExtension(string $name, string $path): bool
    {
        $this->paths[$name] = \rtrim($path, '/');

        return true;
    }

    /**
     * Resolve extension namespace name from manifest.
     *
     * @param  string  $manifest
     *
     * @return array
     */
    public function resolveExtensionNamespace(string $manifest): array
    {
        $vendor = null;
        $package = null;
        $manifest = \str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $manifest);
        $fragment = \explode(DIRECTORY_SEPARATOR, $manifest);

        // Remove orchestra.json from fragment as we are only interested with
        // the two segment before it.
        if (\array_pop($fragment) == 'orchestra.json') {
            $package = \array_pop($fragment);
            $vendor = \array_pop($fragment);
        }

        return [$vendor, $package];
    }

    /**
     * Resolve extension path.
     *
     * @param  string  $path
     *
     * @return string
     */
    public function resolveExtensionPath(string $path): string
    {
        $app = \rtrim($this->config['path.app'], '/');
        $base = \rtrim($this->config['path.base'], '/');

        return \str_replace(
            ['app::', 'vendor::', 'base::'], ["{$app}/", "{$base}/vendor/", "{$base}/"], $path
        );
    }

    /**
     * Validate extension name.
     *
     * @param  string  $name
     *
     * @throws \RuntimeException
     *
     * @return string
     */
    public function validateExtensionName(string $name): string
    {
        if (\in_array($name, $this->reserved)) {
            throw new RuntimeException("Unable to register reserved name [{$name}] as extension.");
        }

        return $name;
    }
}


<?php

namespace Orchestra\View;

use Orchestra\View\Theme\Finder;
use Orchestra\View\Theme\ThemeManager;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\View\ViewServiceProvider as ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        parent::register();

        $this->registerTheme();
    }

    /**
     * Register the service provider for view finder.
     *
     * @return void
     */
    public function registerViewFinder()
    {
        $this->app->bind('view.finder', function (Application $app) {
            $paths = $app->make('config')->get('view.paths', []);

            return new FileViewFinder($app->make('files'), $paths);
        });
    }

    /**
     * Register the service provider for theme.
     *
     * @return void
     */
    protected function registerTheme(): void
    {
        $this->app->singleton('orchestra.theme', function (Application $app) {
            return new ThemeManager($app);
        });

        $this->app->singleton('orchestra.theme.finder', function (Application $app) {
            return new Finder($app->make('files'), $app->publicPath());
        });
    }
}


<?php

namespace Orchestra\View\Theme;

use Illuminate\Support\Collection;
use Illuminate\Filesystem\Filesystem;
use Orchestra\Contracts\Theme\Finder as FinderContract;

class Finder implements FinderContract
{
    /**
     * The filesystem implementation.
     *
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $files;

    /**
     * Public path.
     *
     * @var string
     */
    protected $publicPath;

    /**
     * Construct a new finder.
     *
     * @param  \Illuminate\Filesystem\Filesystem  $files
     */
    public function __construct(Filesystem $files, string $publicPath)
    {
        $this->files = $files;
        $this->publicPath = $publicPath;
    }

    /**
     * Detect available themes.
     *
     * @throws \RuntimeException
     *
     * @return \Illuminate\Support\Collection
     */
    public function detect(): Collection
    {
        $path = \rtrim($this->publicPath, '/').'/themes/';

        return Collection::make($this->files->directories($path))->mapWithKeys(function ($folder) {
            return [
                $this->parseThemeNameFromPath($folder) => new Manifest($this->files, \rtrim($folder, '/').'/'),
            ];
        });
    }

    /**
     * Get folder name from full path.
     *
     * @param  string   $path
     *
     * @return string
     */
    protected function parseThemeNameFromPath(string $path): string
    {
        $path = \str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);
        $path = \explode(DIRECTORY_SEPARATOR, $path);

        return \array_pop($path);
    }
}


<?php

namespace Orchestra\View\Bootstrap;

use Orchestra\Contracts\Theme\Theme;
use Illuminate\Contracts\Foundation\Application;

class LoadCurrentTheme
{
    /**
     * Bootstrap the given application.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     *
     * @return void
     */
    public function bootstrap(Application $app): void
    {
        $theme = $app->make('orchestra.theme')->driver();

        $this->setCurrentTheme($app, $theme);
        $this->setThemeResolver($app, $theme);
    }

    /**
     * Set current theme for request.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  \Orchestra\Contracts\Theme\Theme  $theme
     *
     * @return void
     */
    protected function setCurrentTheme(Application $app, Theme $theme): void
    {
        $memory = $app->make('orchestra.memory')->makeOrFallback();
        $events = $app->make('events');

        // By default, we should consider all request to use "frontend"
        // theme and only convert to use "backend" routing when certain
        // event is fired.
        $theme->setTheme($memory->get('site.theme.frontend'));

        $events->listen('orchestra.started: admin', function () use ($theme, $memory) {
            $theme->setTheme($memory->get('site.theme.backend'));
        });

        $events->listen('composing: *', function () use ($theme) {
            $theme->boot();
        });
    }

    /**
     * Boot theme resolver.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  \Orchestra\Contracts\Theme\Theme  $theme
     *
     * @return void
     */
    protected function setThemeResolver(Application $app, Theme $theme): void
    {
        // The theme is only booted when the first view is being composed.
        // This would prevent multiple theme being booted in the same
        // request.
        if ($app->resolved('view')) {
            $theme->resolving();
        } else {
            $app->resolving('view', function () use ($theme) {
                $theme->resolving();
            });
        }
    }
}


<?php

namespace Orchestra\Extension;

use Illuminate\Contracts\Foundation\Application;
use Orchestra\Support\Providers\ServiceProvider;

class ExtensionServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerExtensionConfigManager();

        $this->registerExtensionFinder();

        $this->registerExtensionProvider();

        $this->registerExtensionStatusChecker();

        $this->registerExtensionUrlGenerator();

        $this->registerExtension();

        $this->registerExtensionEvents();
    }

    /**
     * Register the service provider for Extension.
     *
     * @return void
     */
    protected function registerExtension(): void
    {
        $this->app->singleton('orchestra.extension', function (Application $app) {
            $config = $app->make('config');
            $events = $app->make('events');
            $files = $app->make('files');
            $finder = $app->make('orchestra.extension.finder');
            $status = $app->make('orchestra.extension.status');
            $provider = $app->make('orchestra.extension.provider');

            return new Factory(
                $app, new Dispatcher($app, $config, $events, $files, $finder, $provider), $status
            );
        });
    }

    /**
     * Register the service provider for Extension Config Manager.
     *
     * @return void
     */
    protected function registerExtensionConfigManager(): void
    {
        $this->app->singleton('orchestra.extension.config', function (Application $app) {
            return new Config\Repository($app->make('config'), $app->make('orchestra.memory'));
        });
    }

    /**
     * Register the service provider for Extension Finder.
     *
     * @return void
     */
    protected function registerExtensionFinder(): void
    {
        $this->app->singleton('orchestra.extension.finder', function (Application $app) {
            $config = [
                'path.app' => $app->path(),
                'path.base' => $app->basePath(),
                'path.composer' => $app->basePath('/composer.lock'),
            ];

            return new Finder($app->make('files'), $config);
        });
    }

    /**
     * Register the service provider for Extension Provider.
     *
     * @return void
     */
    protected function registerExtensionProvider(): void
    {
        $this->app->singleton('orchestra.extension.provider', function (Application $app) {
            $provider = new ProviderRepository($app, $app->make('events'), $app->make('files'));

            $provider->loadManifest();

            return $provider;
        });
    }

    /**
     * Register the service provider for Extension Safe Mode Checker.
     *
     * @return void
     */
    protected function registerExtensionStatusChecker(): void
    {
        $this->app->singleton('orchestra.extension.status', function (Application $app) {
            return new StatusChecker($app->make('config'), $app->make('request'));
        });
    }

    /**
     * Register the service provider for Extension Provider.
     *
     * @return void
     */
    protected function registerExtensionUrlGenerator(): void
    {
        $this->app->bind('orchestra.extension.url', function (Application $app) {
            return new UrlGenerator($app->make('request'));
        });
    }

    /**
     * Register extension events.
     *
     * @return void
     */
    protected function registerExtensionEvents(): void
    {
        $this->app->terminating(function () {
            $this->app->make('orchestra.extension')->finish();
        });
    }

    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        $path = \realpath(__DIR__.'/../');

        $this->addConfigComponent('orchestra/extension', 'orchestra/extension', "{$path}/config");
    }
}


<?php

namespace Uerka\TranslationFormBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class TranslationItemType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($options['fields'] as $fieldName => $fieldSettings) {
            $fieldWidget = !empty($fieldSettings['widget_class']) ? $fieldSettings['widget_class'] : TextType::class;
            $fieldOptions = !empty($fieldSettings['options']) ? $fieldSettings['options'] : [];

            $builder->add($fieldName, $fieldWidget, $fieldOptions);
        }
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'fields' => [],
        ]);
    }
}


<?php

namespace Orchestra\Extension\Processors;

use Closure;
use Illuminate\Support\Fluent;
use Orchestra\Contracts\Extension\Factory;
use Orchestra\Contracts\Publisher\FilePermissionException;

abstract class Processor
{
    /**
     * The extension factory implementation.
     *
     * @var \Orchestra\Contracts\Extension\Factory
     */
    protected $factory;

    /**
     * Construct a new processor instance.
     *
     * @param \Orchestra\Contracts\Extension\Factory  $factory
     */
    public function __construct(Factory $factory)
    {
        $this->factory = $factory;
    }

    /**
     * Execute extension processing.
     *
     * @param  object  $listener
     * @param  string  $type
     * @param  \Illuminate\Support\Fluent  $extension
     * @param  \Closure  $callback
     *
     * @return mixed
     */
    protected function execute($listener, $type, Fluent $extension, Closure $callback)
    {
        $name = $extension->get('name');

        try {
            // Check if folder is writable via the web instance, this would
            // avoid issue running Orchestra Platform with debug as true where
            // creating/copying the directory would throw an ErrorException.
            if (! $this->factory->permission($name)) {
                throw new FilePermissionException("[{$name}] is not writable.");
            }

            $callback($this->factory, $name);
        } catch (FilePermissionException $e) {
            return $listener->{"{$type}HasFailed"}($extension, ['error' => $e->getMessage()]);
        }

        return $listener->{"{$type}HasSucceed"}($extension);
    }
}


<?php

namespace Orchestra\Extension;

use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Orchestra\Contracts\Extension\UrlGenerator as UrlGeneratorContract;

class UrlGenerator implements UrlGeneratorContract
{
    /**
     * Request instance.
     *
     * @var \Illuminate\Http\Request
     */
    protected $request;

    /**
     * Domain name.
     *
     * @var string|null
     */
    protected $domain;

    /**
     * Handles path.
     *
     * @var string|null
     */
    protected $prefix;

    /**
     * Base URL.
     *
     * @var string|null
     */
    protected $baseUrl;

    /**
     * Base URL prefix.
     *
     * @var string|null
     */
    protected $basePrefix;

    /**
     * The URL schema to be forced on all generated URLs.
     *
     * @var string|null
     */
    protected $forceSchema;

    /**
     * Construct a new instance.
     *
     * @param \Illuminate\Http\Request  $request
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Get the scheme for a raw URL.
     *
     * @param  bool|null  $secure
     *
     * @return string
     */
    protected function getScheme(?bool $secure): string
    {
        if (\is_null($secure)) {
            return $this->forceSchema ?: $this->request->getScheme().'://';
        }

        return $secure ? 'https://' : 'http://';
    }

    /**
     * Force the schema for URLs.
     *
     * @param  string  $schema
     *
     * @return void
     */
    public function forceScheme(string $schema): void
    {
        $this->forceSchema = $schema.'://';
    }

    /**
     * Build route.
     *
     * @param  string  $handles
     *
     * @return $this
     */
    public function handle(string $handles)
    {
        // If the handles doesn't start as "//some.domain.com/foo" we should
        // assume that it doesn't belong to any subdomain, otherwise we
        // need to split the value to "some.domain.com" and "foo".
        if (\is_null($handles) || ! Str::startsWith($handles, ['//', 'http://', 'https://'])) {
            $this->prefix = $handles;
        } else {
            $handles = \substr(\str_replace(['http://', 'https://'], '//', $handles), 2);
            $fragments = \explode('/', $handles, 2);
            $this->domain = \array_shift($fragments);
            $this->prefix = \array_shift($fragments);
        }

        // It is possible that prefix would be null, in this case assume
        // it handle the main path under the domain.
        ! \is_null($this->prefix) || $this->prefix = '/';

        return $this;
    }

    /**
     * Get route domain.
     *
     * @param  bool  $forceBase
     *
     * @return string|null
     */
    public function domain(bool $forceBase = false): ?string
    {
        $pattern = $this->domain;
        $baseUrl = $this->getBaseUrl();

        if (\is_null($pattern) && $forceBase === true) {
            $pattern = $baseUrl;
        } elseif (Str::contains($pattern, '{{domain}}')) {
            $pattern = \str_replace('{{domain}}', $baseUrl, $pattern);
        }

        return $pattern;
    }

    /**
     * Get route group.
     *
     * @param  bool  $forceBase
     *
     * @return array
     */
    public function group(bool $forceBase = false): array
    {
        $group = [
            'prefix' => $this->prefix($forceBase),
        ];

        if (! \is_null($domain = $this->domain($forceBase))) {
            $group['domain'] = $domain;
        }

        return $group;
    }

    /**
     * Determine if the current request URI matches a pattern.
     *
     * @param  string  $pattern
     *
     * @return bool
     */
    public function is(string $pattern): bool
    {
        $path = $this->path();
        $prefix = $this->prefix();

        foreach (\func_get_args() as $pattern) {
            $pattern = ($pattern === '*' ? "{$prefix}*" : "{$prefix}/{$pattern}");
            $pattern = \trim($pattern, '/');

            empty($pattern) && $pattern = '/';

            if (Str::is($pattern, $path)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Get the current path info for the request.
     *
     * @return string
     */
    public function path(): string
    {
        $pattern = \trim($this->request->path(), '/');

        return $pattern === '' ? '/' : $pattern;
    }

    /**
     * Get route prefix.
     *
     * @param  bool  $forceBase
     *
     * @return string
     */
    public function prefix(bool $forceBase = false): string
    {
        $pattern = \trim($this->prefix, '/');

        if (\is_null($this->domain) && $forceBase === true) {
            $pattern = \trim($this->basePrefix, '/')."/{$pattern}";
            $pattern = \trim($pattern, '/');
        }

        empty($pattern) && $pattern = '/';

        return $pattern;
    }

    /**
     * Get route root.
     *
     * @return string
     */
    public function root(): string
    {
        $scheme = $this->getScheme(null);
        $domain = \trim($this->domain(true), '/');
        $prefix = $this->prefix(true);

        return \trim("{$scheme}{$domain}/{$prefix}", '/');
    }

    /**
     * Get base url.
     *
     * @return string
     */
    public function getBaseUrl(): string
    {
        if (\is_null($this->baseUrl)) {
            $this->resolveBaseUrlFrom($this->request->root());
        }

        return $this->baseUrl;
    }

    /**
     * Set base URL.
     *
     * @param  string  $root
     *
     * @return $this
     */
    public function setBaseUrl(string $root)
    {
        if (! empty($root)) {
            $this->resolveBaseUrlFrom($root);
        }

        return $this;
    }

    /**
     * Get route to.
     *
     * @param  string  $to
     *
     * @return string
     */
    public function to(string $to): string
    {
        $root = $this->root();
        $to = \trim($to, '/');
        $pattern = \trim("{$root}/{$to}", '/');

        return $pattern !== '/' ? $pattern : '';
    }

    /**
     * Magic method to parse as string.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->prefix();
    }

    /**
     * Resolve base url from given path.
     *
     * @param  string|null  $root
     *
     * @return void
     */
    protected function resolveBaseUrlFrom(?string $root): void
    {
        // Build base URL and prefix.
        $baseUrl = \ltrim(\str_replace(['https://', 'http://'], '', $root), '/');
        $base = \explode('/', $baseUrl, 2);

        if (\count($base) > 1) {
            $this->basePrefix = \array_pop($base);
        }

        $this->baseUrl = \array_shift($base);
    }
}


<?php

namespace PhpDocReader;

/**
 * Class Reader
 * @author  Lucas A. de Araújo <lucas@painapp.com.br>
 * @package PhpDocReader
 */
class Reader
{
    /**
     * Obtém a configuração de uma classe ou propriedade.
     * @param $class
     * @param null $property
     * @return array
     */
    public static function getConfig($class, $property = null)
    {
        $doc = Reflector::getDoc($class, $property);
        $cfg = ConfigurationBuilder::build($doc);
        return $cfg;
    }
}


<?php

namespace Scrutinizer\Util;

use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Yaml;

class YamlUtils
{
    /**
     * Safely parses the input string.
     *
     * In contrast to the original Yaml class, we do not try to resolve the input to a filename first. Consequentially,
     * there is no need to sanitize the input prior to calling this method.
     *
     * @param string $input
     *
     * @return mixed
     */
    public static function safeParse($input, $validateDuplicateKeys = true)
    {
        if (method_exists('Symfony\Component\Yaml\Yaml', 'setPhpParsing')) {
            Yaml::setPhpParsing(false);
        }

        if ($validateDuplicateKeys) {
            self::validateDuplicatedKey($input);
        }

        return (new Parser())->parse($input, true, false);
    }

    /**
     * Validate if there is duplicated keys in the input yml string
     *
     * @param string $input
     * @return bool
     */
    private static function validateDuplicatedKey($input)
    {
        $lines = explode("\n", $input);
        $data = array();
        $nbSpacesOfLastLine = 0;

        foreach ($lines as $linenumber => $line) {
            $trimmedLine = ltrim($line, ' ');
            if ($trimmedLine === '' || $trimmedLine[0] === '#') {
                continue;
            }

            $nbSpacesOfCurrentLine = strlen($line) - strlen($trimmedLine);

            if ($nbSpacesOfCurrentLine < $nbSpacesOfLastLine) {
                foreach ($data as $nbSpaces => $keys) {
                    if ($nbSpaces > $nbSpacesOfCurrentLine) {
                        unset($data[$nbSpaces]);
                    }
                }
            }

            if ($trimmedLine[0] === '-' || false === $pos = strpos($trimmedLine, ':')) {
                continue;
            }

            $key = substr($trimmedLine, 0, $pos);

            if (isset($data[$nbSpacesOfCurrentLine][$key])) {
                throw new ParseException(sprintf('Duplicate key "%s" detected on line %s whilst parsing YAML.', $key, $linenumber));
            }

            $data[$nbSpacesOfCurrentLine][$key] = array();
            $nbSpacesOfLastLine = $nbSpacesOfCurrentLine;
        }
    }
}


<?php

namespace Orchestra\Extension\Console;

use Illuminate\Support\Fluent;
use Illuminate\Console\ConfirmableTrait;
use Orchestra\Extension\Processors\Deactivator as Processor;
use Orchestra\Contracts\Extension\Listener\Deactivator as Listener;

class DeactivateCommand extends ExtensionCommand implements Listener
{
    use ConfirmableTrait;

    /**
     * The console command signature.
     *
     * @var string
     */
    protected $signature = 'extension:deactivate
        {name : Extension name.}
        {--force : Force the operation to run when in production.}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Deactivate an extension.';

    /**
     * Execute the console command.
     *
     * @param  \Orchestra\Extension\Processor\Deactivator  $deactivator
     *
     * @return void
     */
    public function handle(Processor $deactivator)
    {
        if (! $this->confirmToProceed()) {
            return;
        }

        return $deactivator($this, new Fluent(['name' => $this->argument('name')]));
    }

    /**
     * Response when extension deactivation has succeed.
     *
     * @param  \Illuminate\Support\Fluent  $extension
     *
     * @return mixed
     */
    public function deactivationHasSucceed(Fluent $extension)
    {
        $this->refreshRouteCache();

        $this->info("Extension [{$extension->get('name')}] deactivated.");
    }
}


<?php

namespace Orchestra\Extension;

use Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Config\Repository as Config;
use Orchestra\Contracts\Extension\Finder as FinderContract;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use Orchestra\Contracts\Extension\Dispatcher as DispatcherContract;

class Dispatcher implements DispatcherContract
{
    /**
     * The Application implementation.
     *
     * @var \Illuminate\Contracts\Foundation\Application
     */
    protected $app;

    /**
     * Config Repository instance.
     *
     * @var \Illuminate\Contracts\Config\Repository
     */
    protected $config;

    /**
     * Filesystem instance.
     *
     * @var \Illuminate\Contracts\Events\Dispatcher
     */
    protected $dispatcher;

    /**
     * Filesystem instance.
     *
     * @var \Illuminate\Filesystem\Filesystem
     */
    protected $files;

    /**
     * Finder instance.
     *
     * @var \Orchestra\Contracts\Extension\Finder
     */
    protected $finder;

    /**
     * Provider instance.
     *
     * @var \Orchestra\Extension\ProviderRepository
     */
    protected $provider;

    /**
     * List of extensions to be boot.
     *
     * @var array
     */
    protected $extensions = [];

    /**
     * Construct a new Application instance.
     *
     * @param  \Illuminate\Contracts\Foundation\Application  $app
     * @param  \Illuminate\Contracts\Config\Repository  $config
     * @param  \Illuminate\Contracts\Events\Dispatcher  $dispatcher
     * @param  \Illuminate\Filesystem\Filesystem  $files
     * @param  \Orchestra\Contracts\Extension\Finder  $finder
     * @param  \Orchestra\Extension\ProviderRepository  $provider
     */
    public function __construct(
        Application $app,
        Config $config,
        EventDispatcher $dispatcher,
        Filesystem $files,
        FinderContract $finder,
        ProviderRepository $provider
    ) {
        $this->app = $app;
        $this->config = $config;
        $this->dispatcher = $dispatcher;
        $this->files = $files;
        $this->finder = $finder;
        $this->provider = $provider;
    }

    /**
     * Register the extension.
     *
     * @param  string  $name
     * @param  array   $options
     *
     * @return void
     */
    public function register(string $name, array $options): void
    {
        $this->registerExtensionHandles($name, $options);

        // Get available service providers from orchestra.json and register
        // it to Laravel. In this case all service provider would be eager
        // loaded since the application would require it from any action.
        $this->registerExtensionProviders($options);

        $this->registerExtensionPlugin($options);

        // Register the extension so we can boot it later, this action is
        // to allow all service providers to be registered first before we
        // start the extension. An extension might be using another extension
        // to work.
        $this->extensions[$name] = $options;

        $this->start($name, $options);
    }

    /**
     * Activating the extension.
     *
     * @param  string  $name
     * @param  array   $options
     *
     * @return void
     */
    public function activating(string $name, array $options): void
    {
        $this->register($name, $options);

        $this->fireEvent($name, $options, 'activating');

        $this->provider->writeFreshManifest();
    }

    /**
     * Deactivating the extension.
     *
     * @param  string  $name
     * @param  array   $options
     *
     * @return void
     */
    public function deactivating(string $name, array $options): void
    {
        $this->fireEvent($name, $options, 'deactivating');

        $this->provider->writeFreshManifest();
    }

    /**
     * Set the handles to orchestra/extension package config (if available).
     *
     * @param  string  $name
     * @param  array   $options
     *
     * @return void
     */
    protected function registerExtensionHandles(string $name, array $options): void
    {
        $handles = $options['config']['handles'] ?? null;

        if (! \is_null($handles)) {
            $this->config->set("orchestra/extension::handles.{$name}", $handles);
        }
    }

    /**
     * Register extension service providers.
     *
     * @param  array  $options
     *
     * @return void
     */
    protected function registerExtensionProviders(array $options): void
    {
        $services = $options['provides'] ?? [];

        ! empty($services) && $this->provider->provides($services);
    }

    /**
     * Register extension plugin.
     *
     * @param  array  $options
     *
     * @return void
     */
    protected function registerExtensionPlugin(array $options): void
    {
        $plugin = $options['plugin'] ?? null;

        ! \is_null($plugin) && $this->app->make($plugin)->bootstrap($this->app);
    }

    /**
     * Boot all extensions.
     *
     * @return void
     */
    public function boot(): void
    {
        foreach ($this->extensions as $name => $options) {
            $this->fireEvent($name, $options, 'booted');
        }

        $this->provider->writeManifest();
    }

    /**
     * Start the extension.
     *
     * @param  string  $name
     * @param  array   $options
     *
     * @return void
     */
    public function start(string $name, array $options): void
    {
        $basePath = \rtrim($options['path'], '/');
        $sourcePath = \rtrim($options['source-path'] ?? $basePath, '/');

        $search = ['source-path::', 'app::/'];
        $replacement = ["{$sourcePath}/", 'app::'];

        // By now, extension should already exist as an extension. We should
        // be able start orchestra.php start file on each package.
        $this->getAutoloadFiles(Collection::make($options['autoload'] ?? []))
            ->each(function ($path) use ($search, $replacement) {
                $this->loadAutoloaderFile(\str_replace($search, $replacement, $path));
            });

        $this->fireEvent($name, $options, 'started');
    }

    /**
     * Shutdown an extension.
     *
     * @param  string  $name
     * @param  array   $options
     *
     * @return void
     */
    public function finish(string $name, array $options): void
    {
        $this->fireEvent($name, $options, 'done');
    }

    /**
     * Fire events.
     *
     * @param  string  $name
     * @param  array   $options
     * @param  string  $type
     *
     * @return void
     */
    protected function fireEvent(string $name, array $options, string $type = 'started'): void
    {
        $this->dispatcher->dispatch("extension.{$type}", [$name, $options]);
        $this->dispatcher->dispatch("extension.{$type}: {$name}", [$options]);
    }

    /**
     * Get list of available paths for the extension.
     *
     * @param  array  $autoload
     *
     * @return \Illuminate\Support\Collection
     */
    protected function getAutoloadFiles(Collection $autoload): Collection
    {
        return $autoload->map(function ($path) {
            return Str::contains($path, '::') ? $path : 'source-path::'.\ltrim($path, '/');
        })->merge(['source-path::src/orchestra.php', 'source-path::orchestra.php']);
    }

    /**
     * Load autoloader file.
     *
     * @param  string  $filePath
     *
     * @return void
     */
    protected function loadAutoloaderFile(string $filePath): void
    {
        $filePath = $this->finder->resolveExtensionPath($filePath);

        if ($this->files->isFile($filePath)) {
            $this->files->getRequire($filePath);
        }
    }
}


<?php
/*
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

namespace MpaCustomDoctrineHydrator\Factory;

use Locale;
use MpaCustomDoctrineHydrator\Filter\TimeToDateTime;
use Zend\Filter\FilterPluginManager;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class TimeToDateTimeFilterFactory implements FactoryInterface
{
    /**
     * Create service
     *
     * @param  ServiceLocatorInterface $serviceLocator
     * @return TimeToDateTime
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        /** @var $serviceLocator FilterPluginManager */
        $parentLocator = $serviceLocator->getServiceLocator();

        $filter = new TimeToDateTime(
            $parentLocator->get('Config')['mpacustomdoctrinehydrator']['formats'][Locale::getDefault()]
        );

        return $filter;
    }
}


<?php
/**
 * Parses and verifies the variable doc comment.
 *
 * PHP version 5
 *
 * @category  PHP
 * @package   PHP_CodeSniffer
 * @author    Greg Sherwood <gsherwood@squiz.net>
 * @author    Marc McIntyre <mmcintyre@squiz.net>
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 * @link      http://pear.php.net/package/PHP_CodeSniffer
 */

if (class_exists('PHP_CodeSniffer_Standards_AbstractVariableSniff', true) === false) {
    throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found');
}

/**
 * Parses and verifies the variable doc comment.
 *
 * @category  PHP
 * @package   PHP_CodeSniffer
 * @author    Greg Sherwood <gsherwood@squiz.net>
 * @author    Marc McIntyre <mmcintyre@squiz.net>
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 * @version   Release: @package_version@
 * @link      http://pear.php.net/package/PHP_CodeSniffer
 */

class Ongr_Sniffs_Commenting_VariableCommentSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff
{

    /**
     * Called to process class member vars.
     *
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
     * @param int                  $stackPtr  The position of the current token
     *                                        in the stack passed in $tokens.
     *
     * @return void
     */
    public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens       = $phpcsFile->getTokens();
        $commentToken = array(
            T_COMMENT,
            T_DOC_COMMENT_CLOSE_TAG,
        );

        $commentEnd = $phpcsFile->findPrevious($commentToken, $stackPtr);
        if ($commentEnd === false) {
            $phpcsFile->addError('Missing member variable doc comment', $stackPtr, 'Missing');
            return;
        }

        if ($tokens[$commentEnd]['code'] === T_COMMENT) {
            $phpcsFile->addError('You must use "/**" style comments for a member variable comment', $stackPtr, 'WrongStyle');
            return;
        } else if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG) {
            $phpcsFile->addError('Missing member variable doc comment', $stackPtr, 'Missing');
            return;
        } else {
            // Make sure the comment we have found belongs to us.
            $commentFor = $phpcsFile->findNext(array(T_VARIABLE, T_CLASS, T_INTERFACE), ($commentEnd + 1));
            if ($commentFor !== $stackPtr) {
                $phpcsFile->addError('Missing member variable doc comment', $stackPtr, 'Missing');
                return;
            }
        }

        $commentStart = $tokens[$commentEnd]['comment_opener'];

        $foundVar = null;
        foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
            if ($tokens[$tag]['content'] === '@var') {
                if ($foundVar !== null) {
                    $error = 'Only one @var tag is allowed in a member variable comment';
                    $phpcsFile->addError($error, $tag, 'DuplicateVar');
                } else {
                    $foundVar = $tag;
                }
            } else if ($tokens[$tag]['content'] === '@see') {
                // Make sure the tag isn't empty.
                $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $tag, $commentEnd);
                if ($string === false || $tokens[$string]['line'] !== $tokens[$tag]['line']) {
                    $error = 'Content missing for @see tag in member variable comment';
                    $phpcsFile->addError($error, $tag, 'EmptySees');
                }
            }
            else {
                //ONGR We allow other property tags.
//                $error = '%s tag is not allowed in member variable comment';
//                $data  = array($tokens[$tag]['content']);
//                $phpcsFile->addWarning($error, $tag, 'TagNotAllowed', $data);
            }//end if
        }//end foreach

        // The @var tag is the only one we require.
        if ($foundVar === null) {
            $error = 'Missing @var tag in member variable comment';
            $phpcsFile->addError($error, $commentEnd, 'MissingVar');
            return;
        }

        $firstTag = $tokens[$commentStart]['comment_tags'][0];
        if ($foundVar !== null && $tokens[$firstTag]['content'] !== '@var') {
            $error = 'The @var tag must be the first tag in a member variable comment';
            $phpcsFile->addError($error, $foundVar, 'VarOrder');
        }

        // Make sure the tag isn't empty and has the correct padding.
        $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $foundVar, $commentEnd);
        if ($string === false || $tokens[$string]['line'] !== $tokens[$foundVar]['line']) {
            $error = 'Content missing for @var tag in member variable comment';
            $phpcsFile->addError($error, $foundVar, 'EmptyVar');
            return;
        }

        $varType       = $tokens[($foundVar + 2)]['content'];
//

        $suggestedType = PHP_CodeSniffer::suggestType($varType);

        if ($varType === 'bool') {
            $varType = 'boolean';
        } elseif ($varType === 'int') {
            $varType = 'integer';
        }
        if ($varType !== $suggestedType && strpos($varType, $suggestedType . ' ') === false) {
            $error = 'Expected "%s" but found "%s" for @var tag in member variable comment';
            $data  = array(
                $suggestedType,
                $varType,
            );
            $phpcsFile->addError($error, ($foundVar + 2), 'IncorrectVarType', $data);
        }

        //Ongr

        $comment = trim(preg_replace('/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i', '', $varType, 1, $count));
        if (!$count) {
            $space = strpos($comment, ' ');
            if ($space === false) {
                return;
            }
            $comment = substr($comment, $space + 1);
        }
        if ($comment === '') {
            return;
        }
        if (substr($comment, 0, 1) == '$') {
            $this->currentFile->addError(
                'Class field docs should not contain field name',
                $foundVar
            );
            return;
        }
        if (!in_array(substr($comment, -1, 1), ['.', '?', '!'])) {
            $this->currentFile->addError(
                'Variable comments must end in full-stops, exclamation marks, or question marks',
                $foundVar,
                'VariableComment'
            );
        }
        $firstLetter = substr($comment, 0, 1);
        if (strtoupper($firstLetter) !== $firstLetter) {
            $this->currentFile->addError(
                'Variable comments must must start with a capital letter',
                $foundVar,
                'VariableComment'
            );
        }

    }//end processMemberVar()

    /**
     * Called to process a normal variable.
     *
     * Not required for this sniff.
     *
     * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this token was found.
     * @param int                  $stackPtr  The position where the double quoted
     *                                        string was found.
     *
     * @return void
     */
    protected function processVariable(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {

    }//end processVariable()

    /**
     * Called to process variables found in double quoted strings.
     *
     * Not required for this sniff.
     *
     * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this token was found.
     * @param int                  $stackPtr  The position where the double quoted
     *                                        string was found.
     *
     * @return void
     */
    protected function processVariableInString(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {

    }//end processVariableInString()

}//end class


<?php

/**
 * This file is part of the Symfony2-coding-standard (phpcs standard)
 *
 * PHP version 5
 *
 * @category PHP
 * @package PHP_CodeSniffer-Symfony2
 * @author Symfony2-phpcs-authors <Symfony2-coding-standard@escapestudios.github.com>
 * @license http://spdx.org/licenses/MIT MIT License
 * @version GIT: master
 * @link https://github.com/escapestudios/Symfony2-coding-standard
 */

/**
 * Symfony2_Sniffs_NamingConventions_TraitSuffixSniff.
 *
 * Throws errors if trait names are not suffixed with "Trait".
 *
 * @category PHP
 * @package PHP_CodeSniffer
 * @author ONGR Team <info@ongr.io>
 * @copyright 2015 NFQ Technologies UAB
 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 */

class Ongr_Sniffs_NamingConventions_TraitSuffixSniff implements PHP_CodeSniffer_Sniff
{
    /**
     * @var array A list of tokenizers this sniff supports.
     */
    public $supportedTokenizers = [
        'PHP',
    ];

    /**
     * Returns an array of tokens this test wants to listen for.
     *
     * @return array
     */
    public function register()
    {
        return [T_TRAIT];
    }

    /**
     * Processes this test, when one of its tokens is encountered.
     *
     * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
     * @param int                  $stackPtr  The position of the current token in the stack passed in $tokens.
     *
     * @return void
     */
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
    {
        $tokens = $phpcsFile->getTokens();
        $line = $tokens[$stackPtr]['line'];
        while ($tokens[$stackPtr]['line'] == $line) {
            if ('T_STRING' == $tokens[$stackPtr]['type']) {
                if (substr($tokens[$stackPtr]['content'], -5) != 'Trait') {
                    $phpcsFile->addError(
                        'Trait name is not suffixed with "Trait"',
                        $stackPtr
                    );
                }
                break;
            }
            $stackPtr++;
        }
    }
}