Initial commit

This commit is contained in:
2018-08-23 16:44:53 +02:00
commit 1f06564778
115 changed files with 13984 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Analyzer\Base;
/**
* Interface for analyzable models
*
* @author magdev
*/
interface AnalyzableInterface
{
/**
* Get the data to analyze
*
* @return array
*/
public function getAnalyzerData(): array;
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Analyzer\Base;
use Symfony\Component\Console\Exception\RuntimeException;
class AnalyzerException extends RuntimeException
{
}

View File

@@ -0,0 +1,55 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Analyzer\Base;
/**
* Interface for analyzers
*
* @author magdev
*/
interface AnalyzerInterface
{
/**
* Get the name of the analyzer
*
* @return string
*/
public function getName(): string;
/**
* Analyze a model
*
* @param \Magdev\Dossier\Analyzer\Base\AnalyzableInterface $model
* @return mixed
*/
public function analyze(AnalyzableInterface $model);
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Analyzer;
use Magdev\Dossier\Analyzer\Base\AnalyzerInterface;
use Magdev\Dossier\Analyzer\Base\AnalyzableInterface;
/**
* Dossier status analyzer
*
* @author magdev
*/
class ModelStatusAnalyzer implements AnalyzerInterface
{
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Analyzer\Base\AnalyzerInterface::getName()
*/
public function getName(): string
{
return 'model.status';
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Analyzer\Base\AnalyzerInterface::analyze()
* @return int
*/
public function analyze(AnalyzableInterface $model)
{
$data = $model->getAnalyzerData();
$base = sizeof($data);
$counter = 0;
foreach ($data as $key => $value) {
if ($value) {
$counter++;
}
}
return ceil(($counter * 100) / $base);
}
}

132
src/Application.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Droath\ConsoleForm\FormHelper;
use Magdev\Dossier\Form\Extension\FormDiscovery;
use Magdev\Dossier\Helper\ExportHelper;
use Magdev\Dossier\Helper\OutputHelper;
use Magdev\Dossier\Analyzer\DossierStatusAnalyzer;
use Magdev\Dossier\Analyzer\ModelStatusAnalyzer;
use Magdev\Dossier\Helper\SectionManagerHelper;
/**
* ContainerAware Application
*
* @author magdev
*/
class Application extends BaseApplication
{
/**
* Store the di-container
* @var \Symfony\Component\DependencyInjection\ContainerBuilder
*/
protected $container = null;
/**
* Constructor
*
* @param string $name
* @param string $version
*/
public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN')
{
parent::__construct($name, $version);
$this->container = new ContainerBuilder();
$loader = new YamlFileLoader($this->container, new FileLocator(DOSSIER_ROOT.'/app/conf'));
$loader->load('services.yaml');
$formDiscovery = new FormDiscovery($this->container);
$forms = $formDiscovery->discover(DOSSIER_ROOT.'/src/Form', '\Magdev\Dossier\Form');
$helperSet = $this->getHelperSet();
$helperSet->set(new FormHelper($forms));
$helperSet->set(new ExportHelper());
$helperSet->set(new OutputHelper($this->getName(), $this->getVersion()));
$helperSet->set(new SectionManagerHelper($this->container->get('config')));
$this->container->get('analyzer')
->addAnalyzer(new ModelStatusAnalyzer());
}
/**
* Get the service-contianer
*
* @return \Symfony\Component\DependencyInjection\ContainerBuilder
*/
public function getContainer(): ContainerBuilder
{
return $this->container;
}
/**
* Get a service by its name
*
* @param string $name
* @param int $invalidBehavior
* @return object|\Symfony\Component\DependencyInjection\Container|mixed|void|unknown
*/
public function getService(string $name, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
{
return $this->getContainer()->get($name, $invalidBehavior);
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Application::getLongVersion()
*/
public function getLongVersion()
{
$code = '<fg=magenta;options=bold>'.base64_decode(DOSSIER_LOGO).PHP_EOL;
$header = $this->getService('translator')->trans('app.header');
if ('UNKNOWN' !== $this->getName()) {
if ('UNKNOWN' !== $this->getVersion()) {
$code .= ' '.$this->getName().' '.$this->getVersion().PHP_EOL;
} else {
$code .= ' '.$this->getName().PHP_EOL;
}
}
$code .= ' '.$header.'</>';
return $code;
}
}

View File

@@ -0,0 +1,174 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Base;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
/**
* Base command
*
* @author magdev
*/
class BaseCommand extends Command
{
/**
* Configuration service
* @var \Magdev\Dossier\Service\ConfigService
*/
protected $config = null;
/**
* Translator service
* @var \Magdev\Dossier\Service\TranslatorService
*/
protected $translator = null;
/**
* Monolog Service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* The IO-Style object
* @var \Magdev\Dossier\Style\DossierStyle
*/
protected $io = null;
/**
* Write the application header
*
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return \Magdev\Dossier\BaseCommand\Base\BaseCommand
* @deprecated
*/
protected function writeHeader(OutputInterface $output): BaseCommand
{
$this->getService('output_helper')
->setOutput($output)
->writeApplicationHeader();
return $this;
}
/**
* Get a service from the container
*
* @param string $name
* @return mixed
*/
protected function getService(string $name)
{
return $this->getApplication()->getService($name);
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->addOption('no-header', 'N', InputOption::VALUE_NONE, 'Suppress header <option>(format=table)</>');
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\BaseCommand\Command::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->config = $this->getService('config');
$this->logger = $this->getService('monolog');
$locale = $this->config->get('translator.locale', 'en');
if ($input->hasOption('locale')) {
$locale = $input->getOption('locale');
}
$this->translator = $this->getService('translator')->setLocale($locale);
$this->io = $this->getHelper('output')
->getIoStyle($input, $output);
if (!$input->hasOption('no-header') || !$input->getOption('no-header')) {
$this->io->header($this->translator->trans('app.header'));
}
}
/**
* Log and output debug messages
*
* @param string $message
* @return \Magdev\Dossier\Command\Base\BaseCommand
*/
protected function debugLog(string $message): BaseCommand
{
$this->logger->debug($message);
$this->io->debug($message);
return $this;
}
/**
* Log and output error messages
*
* @param string $message
* @return \Magdev\Dossier\Command\Base\BaseCommand
*/
protected function errorLog(string $message): BaseCommand
{
$this->logger->error($message);
$this->io->error($message);
return $this;
}
/**
* Log and output warnings
*
* @param string $message
* @return \Magdev\Dossier\Command\Base\BaseCommand
*/
protected function warningLog(string $message): BaseCommand
{
$this->logger->warning($message);
$this->io->warning($message);
return $this;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Cache;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magdev\Dossier\Command\Base\BaseCommand;
class CacheClearCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('cache:clear')
->setDescription('Clear the cache');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Command\Base\BaseCommand::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$input->setOption('no-header', true);
parent::initialize($input, $output);
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if (DOSSIER_CACHE && DOSSIER_CACHE != '/' && is_dir(DOSSIER_CACHE)) {
system('rm -rf '.DOSSIER_CACHE.' 2>&1 >> /dev/null');
}
}
}

View File

@@ -0,0 +1,139 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Config;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Helper\Table;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Get a configuration value
*
* @author magdev
*/
class ConfigGetCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('config:get')
->setDescription('Get a configuration value')
->addArgument('path', InputArgument::REQUIRED, 'Configuration path')
->addOption('format', 'f', InputOption::VALUE_OPTIONAL, 'Output format (table|yaml|json|php)', 'table')
->addOption('plain', 'p', InputOption::VALUE_NONE, 'Show the value only <option>(implies --no-header)</>')
->addOption('include-return', 'R', InputOption::VALUE_NONE, 'Include return statement <option>(format=php)</>')
->addOption('include-tags', 'T', InputOption::VALUE_NONE, 'Include PHP tags <option>(format=php)</>')
->addOption('pretty', 'P', InputOption::VALUE_NONE, 'JSON pretty print <option>(format=json)</>')
->addOption('indent', 'i', InputOption::VALUE_OPTIONAL, 'Indentation width <option>(format=yaml)</>', 2)
->addOption('depth', 'd', InputOption::VALUE_OPTIONAL, 'Render depth before switching to inline YAML <option>(format=yaml)</>', 3);
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$input->setOption('no-header', $input->getOption('plain'));
parent::initialize($input, $output);
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$export = $this->getHelper('export');
/* @var $export \Magdev\Dossier\Helper\ExportHelper */
$path = $input->getArgument('path');
$value = $this->config->get($path);
if ($input->getOption('plain')) {
$this->io->write($value);
exit;
}
switch ($input->getOption('format')) {
case 'yaml':
$this->io->write($export->toYAML(
$this->config->getConfig()->all(),
(int) $input->getOption('depth'),
(int) $input->getOption('indent')
));
break;
case 'json':
$this->io->write($export->toJSON(
$this->config->getConfig()->all(),
(bool) $input->getOption('pretty')
));
break;
case 'php':
$this->io->write($export->toPHP(
$this->config->getConfig()->all(),
(bool) $input->getOption('include-return'),
(bool) $input->getOption('include-tags')
));
break;
default:
$global = $this->io->bool($this->config->isGlobalConfig($path, $value));
$this->io->writeln(array(
' '.$this->translator->trans('info.debug_mode').': '.$this->io->debugStatus(),
' '.$this->translator->trans('info.environment').': '.$this->io->environment()
));
$this->io->newLine();
$this->io->table(
array('Path', 'Value', 'Global'),
array(array($path, $value, $this->io->align($global, 6)))
);
break;
}
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Config;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Set a configuration value
*
* @author magdev
*/
class ConfigSetCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('config:set')
->setDescription('Set a configuration value')
->addOption('global', 'g', InputOption::VALUE_NONE, 'Set in global configuration')
->addArgument('path', InputArgument::REQUIRED, 'Configuration path in dot-notation')
->addArgument('value', InputArgument::REQUIRED, 'Configuration value');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$global = (bool) $input->getOption('global');
$path = $input->getArgument('path');
$value = $input->getArgument('value');
$this->config->set($path, $value, $global)->save();
$this->io->table(array('Path', 'Value', 'Global'), array(
array(
$path,
$this->config->get($path),
$this->io->align($this->io->bool($this->config->isGlobalConfig($path, $value)), 6)
)
));
}
}

View File

@@ -0,0 +1,131 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Config;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use Magdev\Dossier\Service\ConfigService;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Show the full configuration
*
* @author magdev
*/
class ConfigShowCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('config:show')
->setDescription('Show or export the full configuration')
->addOption('format', 'f', InputOption::VALUE_OPTIONAL, 'Output format (table|yaml|json|php)', 'table')
->addOption('return', 'r', InputOption::VALUE_NONE, 'PHP: Include return statement')
->addOption('tags', 't', InputOption::VALUE_NONE, 'PHP: Include PHP tags')
->addOption('pretty', 'p', InputOption::VALUE_NONE, 'JSON: Output pretty printed')
->addOption('indent', 'i', InputOption::VALUE_OPTIONAL, 'YAML: Indentation width', 2)
->addOption('depth', 'd', InputOption::VALUE_OPTIONAL, 'YAML: Render depth before switching to inline YAML', 3);
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
if ($input->getOption('format') != 'table') {
$input->setOption('no-header', true);
}
parent::initialize($input, $output);
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$export = $this->getHelper('export');
/* @var $export \Magdev\Dossier\Helper\ExportHelper */
switch ($input->getOption('format')) {
case 'yaml':
$this->io->write($export->toYAML(
$this->config->getConfig()->all(),
(int) $input->getOption('depth'),
(int) $input->getOption('indent')
));
break;
case 'json':
$this->io->write($export->toJSON(
$this->config->getConfig()->all(),
(bool) $input->getOption('pretty')
));
break;
case 'php':
$this->io->write($export->toPHP(
$this->config->getConfig()->all(),
(bool) $input->getOption('include-return'),
(bool) $input->getOption('include-tags')
));
break;
default:
$outHelper = $this->getHelper('output');
/* @var $outHelper \Magdev\Dossier\Helper\OutputHelper */
$this->io->newLine();
$this->io->writeln(array(
' '.$this->translator->trans('info.debug_mode').': '.$this->io->debugStatus(),
' '.$this->translator->trans('info.environment').': '.$this->io->environment()
));
$this->io->newLine();
$this->io->table(
array('Path', 'Value', 'Global'),
$this->config->allTable($this->io, 6)
);
break;
}
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Config;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Set a configuration value
*
* @author magdev
*/
class ConfigUnsetCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('config:unset')
->setDescription('Unset a configuration value')
->addArgument('path', InputArgument::REQUIRED, 'Configuration path in dot-notation');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$path = $input->getArgument('path');
$this->config->unset($path)->save();
$this->io->success($this->translator->trans('message.config.deleted', array('%path%' => $path)));
}
}

View File

@@ -0,0 +1,124 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Cv;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\RuntimeException;
use Droath\ConsoleForm\Exception\FormException;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Write a new CV entry
*
* @author magdev
*/
final class CvAddCommand extends BaseCommand
{
/**
* TheCV Form
* @var \Magdev\Dossier\Form\Extension\Form
*/
protected $form = null;
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('cv:add')
->setDescription('Write a new CV entry')
->addArgument('name', InputArgument::REQUIRED, 'Choose the name of the entry')
->addOption('review', 'r', InputOption::VALUE_NONE, 'Review file in editor');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Command\BaseCommand::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
try {
$this->form = $this->getHelper('form')->getFormByName('form.cv', $input, $output);
parent::initialize($input, $output);
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::interact()
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$this->io->title($this->translator->trans('form.cv.header.add'));
$this->io->newLine();
$this->form->process();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($this->form->isProcessed()) {
$markdown = $this->getService('markdown');
/* @var $markdown \Magdev\Dossier\Service\MarkdownService */
try {
$text = $this->form->stripData('text', '');
$name = $input->getArgument('name');
$markdown->save(PROJECT_ROOT.'/cv/'.$name.'.md', $this->form->getResults(), $text, false);
$this->io->success($this->translator->trans('message.write.success', array(
'%name%' => 'CV/'.ucfirst($name)
)));
if ($input->getOption('review') != false) {
$this->getService('uri_helper')->openFileInEditor(PROJECT_ROOT.'/cv/'.$name.'.md');
}
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Cv;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Exception\RuntimeException;
use Magdev\Dossier\Command\Base\BaseCommand;
class CvEditCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('cv:edit')
->setDescription('Edit a CV entry in your default editor')
->addArgument('file', InputArgument::REQUIRED, 'Filename of the entry w/o extension');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$file = PROJECT_ROOT.'/cv/'.$input->getArgument('file').'.md';
if (!file_exists($file)) {
throw new RuntimeException('File '.$file.' not found');
}
$this->getService('uri_helper')->openFileInEditor($file);
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Dev;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Magdev\Dossier\Command\Base\BaseCommand;
class PharExtractCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('dev:phar:extract')
->setHidden(!getenv('APP_DEBUG'))
->setDescription('Extract the Phar archive')
->addOption('target', 'd', InputOption::VALUE_OPTIONAL, 'Target directory', getcwd().'/_phar');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$targetDir = $input->getOption('target');
$this->getService('phar_helper')->extractArchive($targetDir);
}
}

View File

@@ -0,0 +1,133 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Dossier;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magdev\Dossier\Model\CurriculumVitae;
use Magdev\Dossier\Model\Person;
use Magdev\Dossier\Model\Intro;
use Magdev\Dossier\Model\Letter;
use Magdev\Dossier\Command\Base\BaseCommand;
use Magdev\Dossier\Util\DataCollector;
/**
* Generate your dossier
*
* @author magdev
*/
final class DossierBuildCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('dossier:build')
->setDescription('Create a dossier from a set of Markdown files')
->addOption('review', 'r', InputOption::VALUE_NONE, 'Review created file')
->addOption('pdf', 'p', InputOption::VALUE_NONE, 'Convert to PDF (requires PDFShift API-Key)')
->addOption('locale', 'l', InputOption::VALUE_OPTIONAL, 'Set the locale', 'de')
->addOption('sort', 's', InputOption::VALUE_OPTIONAL, 'Set the sort direction for the CV', CurriculumVitae::SORT_DESC)
->addOption('theme', 't', InputOption::VALUE_OPTIONAL, 'Select the theme', 'print')
->addOption('docname', 'd', InputOption::VALUE_OPTIONAL, 'Set the name for the output document (w/o extension)', 'dossier')
->addOption('no-cover', null, InputOption::VALUE_NONE, 'Suppress the cover')
->addOption('no-intro', null, InputOption::VALUE_NONE, 'Suppress the introduction')
->addOption('no-resume', null, InputOption::VALUE_NONE, 'Suppress the resume')
->addOption('no-cv', null, InputOption::VALUE_NONE, 'Suppress the curriculum vitae')
->addOption('no-projects', null, InputOption::VALUE_NONE, 'Suppress the projects page')
->addOption('no-certs', null, InputOption::VALUE_NONE, 'Suppress the certificates')
->addOption('no-toc', null, InputOption::VALUE_NONE, 'Suppress the table of contents')
->addOption('no-quotes', null, InputOption::VALUE_NONE, 'Suppress the quotes');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($input->getOption('theme') == 'server') {
$this->warningLog('Template server cannot be used to render dossiers, using print theme');
$input->setOption('theme', 'print');
}
$uriHelper = $this->getService('uri_helper');
/* @var $uriHelper \Magdev\Dossier\Service\UriHelperService */
$tpl = $this->getService('template')->setTheme($input->getOption('theme'));
/* @var $tpl \Magdev\Dossier\Service\TemplateService */
$cssproc = $this->getService('cssproc');
/* @var $cssroc \Magdev\Dossier\Service\StylesheetProcessorService */
try {
$data = new DataCollector(array(
'disabled' => $this->getHelper('section_manager')->getDisabledSections($input),
'theme' => $input->getOption('theme'),
'name' => $input->getOption('docname'),
'tags' => $this->config->get('cv.tags'),
'locale' => $this->translator->getTranslator()->getLocale(),
'stylesheet' => $cssproc->parseThemeStyles(),
'userstyles' => $cssproc->parseUserstyles(),
'favicon' => $uriHelper->getDataUriFromFile($tpl->getThemeFile('favicon.ico')),
));
$models = $this->getService('markdown')->getFileSet($input->getOption('sort'));
$data->merge($models);
$outputFile = $tpl->render('document.html.twig', $data, PROJECT_ROOT.'/_output');
if ($input->getOption('pdf')) {
$outputFile = $this->getService('pdf')->createPdf($outputFile);
}
$this->io->result($this->translator->trans('message.output_file').': '.$uriHelper->getRelativePath($outputFile));
$this->io->newLine();
$this->io->success($this->translator->trans('message.build.success'));
$this->io->newLine();
if ($input->getOption('review')) {
$uriHelper->openFileInEditor($outputFile);
}
} catch (\Exception $e) {
$this->errorLog($e->getMessage());
}
}
}

View File

@@ -0,0 +1,205 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Dossier;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\RuntimeException;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Initialize a new project directory
*
* @author magdev
*/
final class DossierInitCommand extends BaseCommand
{
/**
* The InitForm
* @var \Magdev\Dossier\Form\Extension\Form
*/
protected $form = null;
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('dossier:init')
->setDescription('Initialize a directory as dossier project')
->setHelp('Initialize a new project. Creates the folder structure and some example markdown files')
->addOption('directory', 'd', InputOption::VALUE_OPTIONAL, 'Set the output directory', getcwd());
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
parent::initialize($input, $output);
try {
$this->form = $this->getHelper('form')
->getFormByName('form.init', $input, $output);
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::interact()
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$this->io->title($this->translator->trans('form.init.header'));
$this->io->newLine();
$this->form->process();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$targetDir = $input->getOption('directory');
if ($this->isDossierProjectDirectory($targetDir)) {
throw new RuntimeException('Directory '.$targetDir.' seems to be an existing dossier project');
}
$this->initTargetDirectory($targetDir);
if ($this->form->isProcessed()) {
if ($this->form->hasData('userstyle_type')) {
$type = strtolower($this->form->getData('userstyle_type'));
$file = $targetDir.'/.conf/'.$type.'/userstyles.'.$type;
if (!is_dir(dirname($file))) {
mkdir(dirname($file), 0755, true);
}
file_put_contents($file, '');
}
$formatter = $this->getHelper('formatter');
$output->writeln($formatter->formatBlock(array(
' $ dossier.phar add:person',
' $ dossier.phar add:intro',
' $ dossier.phar add:cv',
), 'cmd', true));
}
}
/**
* Check if the path is a valid dossier project
*
* @param string $path
* @return bool
*/
private function isDossierProjectDirectory(string $path): bool
{
if (!is_dir($path)) {
return false;
}
if (!is_dir($path.'/cv')) {
return false;
}
if (!is_dir($path.'/certs')) {
return false;
}
if (!is_dir($path.'/.conf')) {
return false;
}
if (!file_exists($path.'/.conf/dossier.yaml')) {
return false;
}
if (!file_exists($path.'/.env')) {
return false;
}
if (!file_exists($path.'/intro.md')) {
return false;
}
if (!file_exists($path.'/person.md')) {
return false;
}
if (!file_exists($path.'/letter.md')) {
return false;
}
return true;
}
/**
* Create the directory structure
*
* @return string
*/
private function initTargetDirectory(string $dir): string
{
if (!is_dir($dir)) {
if (mkdir($dir, 0755, true) === false) {
throw new RuntimeException('Creating directory '.$dir.' failed');
}
}
if (!is_dir($dir.'/cv')) {
mkdir($dir.'/cv', 0755, true);
}
if (!is_dir($dir.'/certs/pdf')) {
mkdir($dir.'/certs/pdf', 0755, true);
}
if (!is_dir($dir.'/certs/png')) {
mkdir($dir.'/certs/png', 0755, true);
}
if (!is_dir($dir.'/.conf')) {
mkdir($dir.'/.conf', 0755, true);
}
file_put_contents($dir.'/.conf/dossier.yaml', '');
file_put_contents($dir.'/.env', 'APP_DEBUG=false'.PHP_EOL.'APP_ENV=prod'.PHP_EOL);
return $dir;
}
}

View File

@@ -0,0 +1,122 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Dossier;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\TableSeparator;
use Magdev\Dossier\Model\Person;
use Magdev\Dossier\Model\Intro;
use Magdev\Dossier\Model\CurriculumVitae\Entry;
use Magdev\Dossier\Model\Letter;
use Magdev\Dossier\Style\DossierStyle;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Command to show the current status of your dossier
*
* @author magdev
*/
class DossierStatusCommand extends BaseCommand
{
/**
* Markdown service
* @var \Magdev\Dossier\Service\MarkdownService
*/
private $markdown = null;
private $models = array(
'Person' => 'person.md',
'Intro' => 'intro.md',
'Letter' => 'letter.md'
);
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('dossier:status')
->setDescription('Get the status of the current dossier files');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$markdown = $this->getService('markdown');
/* @var $markdown \Magdev\Dossier\Service\MarkdownService */
$analyzer = $this->getService('analyzer')->getAnalyzer('model.status');
/* @var $analyzer \Magdev\Dossier\Analyzer\DossierStatusAnalyzer */
$thresholds = $this->config->get('style.dossier_status_thresholds');
$person = new Person($markdown->getDocument(PROJECT_ROOT.'/person.md'));
$intro = new Intro($markdown->getDocument(PROJECT_ROOT.'/intro.md'));
$status = array();
$status[] = array(get_class($person), 'person.md',
$this->io->align('---', 9, DossierStyle::ALIGN_CENTER),
$this->io->align($this->io->percent($analyzer->analyze($person), $thresholds), 6, DossierStyle::ALIGN_RIGHT)
);
$status[] = array(get_class($intro), 'intro.md',
$this->io->align('---', 9, DossierStyle::ALIGN_CENTER),
$this->io->align($this->io->percent($analyzer->analyze($intro), $thresholds), 6, DossierStyle::ALIGN_RIGHT)
);
$status[] = new TableSeparator();
$files = new \FilesystemIterator(PROJECT_ROOT.'/cv');
foreach ($files as $file) {
/* @var $file \SplFileInfo */
$document = $markdown->getDocument($file->getPathname());
$entry = new Entry($document);
$status[] = array(get_class($entry), 'cv/'.$file->getFilename(),
$this->io->align($this->io->bool($entry->useInResume()), 9, DossierStyle::ALIGN_CENTER),
$this->io->align($this->io->percent($analyzer->analyze($entry), $thresholds), 6, DossierStyle::ALIGN_RIGHT)
);
}
$this->io->table(array('Model', 'File',
$this->io->align('In Resume', 9),
$this->io->align('Status', 6, DossierStyle::ALIGN_RIGHT)
), $status);
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Intro;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\RuntimeException;
use Droath\ConsoleForm\Exception\FormException;
use Magdev\Dossier\Command\Base\BaseCommand;
final class IntroAddCommand extends BaseCommand
{
/**
* The IntroForm
* @var \Magdev\Dossier\Form\Extension\Form
*/
protected $form = null;
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('intro:add')
->setDescription('Write the Intro page')
->addOption('review', 'r', InputOption::VALUE_NONE, 'Review file in editor');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Command\BaseCommand::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
parent::initialize($input, $output);
try {
$this->form = $this->getHelper('form')
->getFormByName('form.intro', $input, $output);
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::interact()
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$this->io->title('<info> '.$this->translator->trans('form.intro.header.add').'</>');
$this->io->newLine();
$this->form->process();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($this->form->isProcessed()) {
$markdown = $this->getService('markdown');
/* @var $markdown \Magdev\Dossier\Service\MarkdownService */
try {
$text = $this->form->stripData('text', '');
$markdown->save(PROJECT_ROOT.'/intro.md', $this->form->getResults(), $text, false);
$this->io->success($this->translator->trans('message.write.success', array(
'%name%' => 'Intro'
)));
if ($input->getOption('review') != false) {
$this->getService('uri_helper')->openFileInEditor(PROJECT_ROOT.'/intro.md');
}
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Intro;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Exception\RuntimeException;
use Magdev\Dossier\Command\Base\BaseCommand;
class IntroEditCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('intro:edit')
->setDescription('Edit the intro in your default editor');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$file = PROJECT_ROOT.'/intro.md';
if (!file_exists($file)) {
throw new RuntimeException('File '.$file.' not found');
}
$this->getService('uri_helper')->openFileInEditor($file);
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Person;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Exception\RuntimeException;
use Droath\ConsoleForm\Exception\FormException;
use Magdev\Dossier\Command\Base\BaseCommand;
final class PersonAddCommand extends BaseCommand
{
/**
* The IntroForm
* @var \Magdev\Dossier\Form\Extension\Form
*/
protected $form = null;
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('person:add')
->setDescription('Write the Person page')
->addOption('review', 'r', InputOption::VALUE_NONE, 'Review file in editor');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Command\BaseCommand::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
parent::initialize($input, $output);
try {
$this->form = $this->getHelper('form')
->getFormByName('form.person', $input, $output);
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::interact()
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$this->io->title($this->translator->trans('form.person.header.add'));
$this->io->newLine();
$this->form->process();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($this->form->isProcessed()) {
$markdown = $this->getService('markdown');
/* @var $markdown \Magdev\Dossier\Service\MarkdownService */
try {
$text = $this->form->stripData('text', '');
$markdown->save(PROJECT_ROOT.'/person.md', $this->form->getResults(), $text, false);
$this->io->success($this->translator->trans('message.write.success', array(
'%name%' => 'Person'
)));
if ($input->getOption('review') != false) {
$this->getService('uri_helper')->openFileInEditor(PROJECT_ROOT.'/person.md');
}
} catch (FormException $fe) {
throw new RuntimeException(get_class($fe).': '.$fe->getMessage(), $fe->getCode(), $fe);
}
}
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Person;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Exception\RuntimeException;
use Magdev\Dossier\Command\Base\BaseCommand;
class PersonEditCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('person:edit')
->setDescription('Edit personal data in your default editor');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$file = PROJECT_ROOT.'/person.md';
if (!file_exists($file)) {
throw new RuntimeException('File '.$file.' not found');
}
$this->getService('uri_helper')->openFileInEditor($file);
}
}

View File

@@ -0,0 +1,143 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Server;
use Magdev\Dossier\Command\Base\BaseCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Magdev\Dossier\Util\DataCollector;
use Symfony\Component\Console\Exception\RuntimeException;
/**
* Start the local HTTP server
*
* @author magdev
*/
class ServerStartCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Command\Base\BaseCommand::configure()
*/
public function configure()
{
$this->setName('server:start')
->setDescription('Start a local HTTP server')
->addOption('socket', 's', InputOption::VALUE_OPTIONAL, 'Set the HTTP socket (host, port or host:port)', 'localhost:8000')
->addOption('no-index', null, InputOption::VALUE_NONE, 'Suppress rendering of index.html before starting the server');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
public function execute(InputInterface $input, OutputInterface $output)
{
$socket = $input->getOption('socket');
$docroot = PROJECT_ROOT.'/_output';
if (!$input->getOption('no-index')) {
$this->createIndex($docroot);
}
$cmd = sprintf('/usr/bin/env php -S %s -t %s', $socket, $docroot);
try {
$process = new Process($cmd);
$process->setTimeout((60*60*24*365))
->start();
$this->io->info(sprintf('Starting HTTP server on %s, press CTRL+C to stop', $socket));
$process->wait(function($type, $buffer) {
if (getenv('APP_DEBUG')) {
$this->io->write(' <lightyellow>[GET] <fg=cyan>'.$buffer.'</>');
}
});
} catch (\Exception $e) {
$this->io->error($e->getMessage());
}
}
/**
* Create an index.html file before server start
*
* @param string $docroot
* @return void
*/
protected function createIndex(string $docroot): void
{
if (file_exists($docroot.'/index.html')) {
unlink($docroot.'/index.html');
}
try {
$tpl = $this->getService('template')->setTheme('server');
/* @var $tpl \Magdev\Dossier\Service\TemplateService */
$cssproc = $this->getService('cssproc');
/* @var $cssroc \Magdev\Dossier\Service\StylesheetProcessorService */
$uriHelper = $this->getService('uri_helper');
/* @var $uriHelper \Magdev\Dossier\Service\UriHelperService */
$data = new DataCollector(array(
'locale' => $this->translator->getTranslator()->getLocale(),
'stylesheet' => $cssproc->parseThemeStyles(),
'favicon' => $uriHelper->getDataUriFromFile($tpl->getThemeFile('favicon.ico')),
));
$files = array();
$fs = new \FilesystemIterator($docroot);
foreach ($fs as $file) {
if (!sizeof($files)) {
$data->setData('first_link', $file);
}
$files[] = $file;
}
$data->setData('links', $files);
$html = $tpl->renderDocument('index.html.twig', $data);
if (false === file_put_contents($docroot.'/index.html', $html)) {
throw new RuntimeException('Error while writing index.html file');
}
$this->debugLog(sprintf('File index.html created with %s bytes', mb_strlen($html)));
} catch (\Exception $e) {
$this->errorLog($e->getMessage());
}
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Theme;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Create a local copy of a template
*
* @author magdev
*/
final class ThemeDumpCommand extends BaseCommand
{
/**
* Phar helper service
* @var \Magdev\Dossier\Service\PharHelperService
*/
private $pharHelper = null;
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('theme:dump')
->setDescription('Create a local copy of a theme')
->addArgument('theme', InputArgument::REQUIRED, 'The name of the theme')
->addOption('locale', 'l', InputOption::VALUE_OPTIONAL, 'Set the locale', 'de')
->addOption('rename', 'r', InputOption::VALUE_OPTIONAL, 'Rename the theme', '')
->addOption('output', 'o', InputOption::VALUE_OPTIONAL, 'Output folder', getenv('HOME').'/.dossier/tpl');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::initialize()
*/
protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->pharHelper = $this->getService('phar_helper');
parent::initialize($input, $output);
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$theme = $input->getArgument('theme');
$outDir = $input->getOption('output');
$newName = $input->getOption('rename');
$themeDir = 'app/tpl/'.$theme;
$targetDir = !$newName ? $outDir.'/'.$theme : $outDir.'/'.$newName;
$this->pharHelper->copyDir($themeDir, $targetDir);
$this->io->success($this->translator->trans('message.dump.success', array('%theme%' => $theme)));
/*
if ($outDir != getenv('HOME').'/.dossier/tpl') {
$output->writeln('<fg=cyan> '.$this->translator->trans('message.export.template_dir').'</>');
$output->writeln('<fg=blue> '.$this->translator->trans('message.export.code.template_environment', array('%path%' => $outDir)).'</>');
} else {
$output->writeln('<fg=cyan> '.$this->translator->trans('message.export.template_homedir').'</>');
}*/
$this->io->newLine();
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Command\Theme;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Magdev\Dossier\Command\Base\BaseCommand;
/**
* Create a local copy of a template
*
* @author magdev
*/
final class ThemeListCommand extends BaseCommand
{
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::configure()
*/
protected function configure()
{
$this->setName('theme:list')
->setDescription('List available themes')
->addOption('all', 'a', InputOption::VALUE_NONE, 'List all themes, icluding the overridden ones');
parent::configure();
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Command\Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$all = (bool) $input->getOption('all');
$helper = $this->getHelper('export');
/* @var $helper \Magdev\Dossier\Helper\ExportHelper */
$themes = $this->config->findThemes($all);
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Config;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Yaml\Yaml;
/**
* Configuration loader
*
* @author magdev
*/
class ConfigLoader extends FileLoader
{
private $config = array();
private $global = array();
/**
* {@inheritDoc}
* @see \Symfony\Component\Config\Loader\LoaderInterface::load()
*/
public function load($resource, $type = null)
{
$content = file_get_contents($resource);
if ($content) {
$config = Yaml::parse($content);
if (is_array($config)) {
$this->config = array_replace_recursive($this->config, $config);
if (strstr($resource, PROJECT_ROOT, true) === false) {
$this->global = array_replace_recursive($this->global, $config);
}
}
}
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Config\Loader\LoaderInterface::supports()
*/
public function supports($resource, $type = null)
{
return is_string($resource) && 'yaml' === pathinfo($resource, PATHINFO_EXTENSION);
}
/**
* Get the config as PHP array sourcecode
*
* @return string
*/
public function __toString(): string
{
return 'array(
"config" => '.var_export($this->config, true).',
"global" => '.var_export($this->global, true).'
)';
}
}

View File

@@ -0,0 +1,185 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Base;
use Magdev\Dossier\Service\ConfigService;
use Magdev\Dossier\Service\TranslatorService;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\PersonFormBuilder;
use Magdev\Dossier\Form\Field\TextField;
use Droath\ConsoleForm\FieldGroup;
abstract class BaseFormBuilder implements FormBuilderInterface
{
protected $flatGroupFields = array();
/**
* Configuration service
* @var \Magdev\Dossier\Service\ConfigService
*/
protected $config = null;
/**
* Translation service
* @var \Magdev\Dossier\Service\TranslatorService
*/
protected $translator = null;
/**
* Get the configuration service
*
* @return \Magdev\Dossier\Service\ConfigService
*/
public function getConfig(): ConfigService
{
return $this->config;
}
/**
* Set the configuration service
*
* @param \Magdev\Dossier\Service\ConfigService $config
* @return \Magdev\Dossier\Form\Base\FormBuilderInterface
*/
public function setConfig(ConfigService $config): FormBuilderInterface
{
$this->config = $config;
return $this;
}
/**
* Get the translator service
*
* @return \Magdev\Dossier\Service\TranslatorService
*/
public function getTranslator(): TranslatorService
{
return $this->translator;
}
/**
* Set the translator service
*
* @param \Magdev\Dossier\Service\TranslatorService $translator
* @return \Magdev\Dossier\Form\Base\FormBuilderInterface
*/
public function setTranslator(TranslatorService $translator): FormBuilderInterface
{
$this->translator = $translator;
return $this;
}
/**
* Get the flatten callback
*
* @return callable
*/
protected function getFlattenCallback(): callable
{
$flatGroupFields = $this->flatGroupFields;
return function(array $results, Form $form) use ($flatGroupFields){
foreach ($flatGroupFields as $field) {
if (isset($results[$field]) && is_array($results[$field])) {
array_walk($results[$field], function(&$value, $key) {
if (is_array($value)) {
$value = (string) array_shift($value);
}
});
}
}
return $results;
};
}
/**
* Get the unflatten callback
*
* @return callable
*/
protected function getUnflattenCallback(): callable
{
$flatGroupFields = $this->flatGroupFields;
return function(array $results, Form $form) use ($flatGroupFields){
foreach ($flatGroupFields as $field) {
if (isset($results[$field]) && is_array($results[$field])) {
array_walk($results[$field], function(&$value, $key) {
if (!is_array($value)) {
$value = array($value);
}
});
}
}
return $results;
};
}
/**
* Add a flat group array for single line array
*
* @param \Magdev\Dossier\Form\Extension\Form $form
* @param string $key
* @param bool $required
* @param string $langPrefix
* @return \Magdev\Dossier\Form\Base\PersonFormBuilder
*/
protected function addFlatGroupField(Form $form, string $key, bool $required = true, string $langPrefix = ''): FormBuilderInterface
{
$name = substr($key, 0, -1);
$label = 'form.';
if ($langPrefix) {
$label .= $langPrefix.'.';
}
$label .= $key;
$this->flatGroupFields[] = $key;
$form->addField((new FieldGroup($key))
->addFields(array(
(new TextField($name, $this->translator->trans($label), false)),
))->setLoopUntil(function($result) use ($name) {
if (!isset($result[$name]) || empty($result[$name])) {
return false;
}
return true;
}));
return $this;
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Base;
/**
* Interface for elements with decorable label
*
* @author magdev
*/
interface DecoratableLabelInterface
{
/**
* Set a label prefix
*
* @param string $prefix
* @return \Magdev\Dossier\Form\Base\DecoratableLabelInterface
*/
public function setLabelPrefix(string $prefix): DecoratableLabelInterface;
/**
* Set the fixed length of the label
*
* @param int $length
* @return \Magdev\Dossier\Form\Base\DecoratableLabelInterface
*/
public function setLabelLength(int $length): DecoratableLabelInterface;
/**
* Get the label prefix
*
* @return string
*/
public function getLabelPrefix(): string;
/**
* Get the label length
*
* @return int
*/
public function getLabelLength(): int;
/**
* Get the decorated label
*
* @param string $label
* @return string
*/
public function decorateLabel(string $label): string;
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Base;
use Magdev\Dossier\Service\ConfigService;
use Magdev\Dossier\Service\TranslatorService;
use Droath\ConsoleForm\FormInterface;
interface FormBuilderInterface extends FormInterface
{
/**
* Get the configuration service
*
* @return \Magdev\Dossier\Service\ConfigService
*/
public function getConfig(): ConfigService;
/**
* Set the configuration service
*
* @param \Magdev\Dossier\Service\ConfigService $config
* @return \Magdev\Dossier\Form\Base\FormBuilderInterface
*/
public function setConfig(ConfigService $config): FormBuilderInterface;
/**
* Get the translator service
*
* @return \Magdev\Dossier\Service\TranslatorService
*/
public function getTranslator(): TranslatorService;
/**
* Set the translator service
*
* @param \Magdev\Dossier\Service\TranslatorService $translator
* @return \Magdev\Dossier\Form\Base\FormBuilderInterface
*/
public function setTranslator(TranslatorService $translator): FormBuilderInterface;
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\Base\BaseFormBuilder;
use Magdev\Dossier\Form\Base\FormBuilderInterface;
use Magdev\Dossier\Form\Field\TextField;
use Magdev\Dossier\Form\Field\SelectField;
use Magdev\Dossier\Form\Field\BooleanField;
class EmailFormBuilder extends BaseFormBuilder implements FormBuilderInterface
{
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::getName()
*/
public function getName()
{
return 'form.email';
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::buildForm()
*/
public function buildForm()
{
$form = new Form();
$form->setLabelPrefix($this->config->get('form.label.prefix'))
->setLabelLength($this->config->get('form.label.length'));
$form->addField(new TextField('company', $this->translator->trans('form.email.company')));
$form->addField((new SelectField('salutation', $this->translator->trans('form.email.salutation')))
->setOptions(array(
$this->translator->trans('form.email.salutation.female'),
$this->translator->trans('form.email.salutation.male'),
))
->setRequired(true));
$form->addField(new TextField('firstname', $this->translator->trans('form.email.firstname')));
$form->addField(new TextField('lastname', $this->translator->trans('form.email.lastname')));
$form->addField(new TextField('email', $this->translator->trans('form.email.email')));
$form->addField(new TextField('offer_title', $this->translator->trans('form.email.offer_title')));
$form->addField(new TextField('offer_link', $this->translator->trans('form.email.offer_link'), false));
$form->addField((new BooleanField('add_subject', $this->translator->trans('form.email.add_subject')))
->setSubform(function($subform, $value) {
if ($value === true) {
$form->addField(new TextField('subject', $this->translator->trans('form.email.subject')));
}
}));
return $form;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\Field\SelectField;
use Magdev\Dossier\Form\Field\TextField;
use Magdev\Dossier\Form\Field\BooleanField;
/**
* EntryFormBuilder
*
* @author magdev
*/
class EntryFormBuilder extends Base\BaseFormBuilder implements Base\FormBuilderInterface
{
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::getName()
*/
public function getName()
{
return 'form.cv';
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::buildForm()
*/
public function buildForm()
{
$form = new Form();
$form->setLabelPrefix($this->config->get('form.label.prefix'))
->setLabelLength($this->config->get('form.label.length'))
->addFormLoadCallback($this->getUnflattenCallback())
->addFormResultsCallback($this->getFlattenCallback());
$form->addField(new TextField('start_date', $this->translator->trans('form.cv.start_date')));
$form->addField(new TextField('end_date', $this->translator->trans('form.cv.end_date')));
$form->addField(new TextField('position', $this->translator->trans('form.cv.position')));
$form->addField(new TextField('company', $this->translator->trans('form.cv.company')));
$form->addField((new SelectField('tag', $this->translator->trans('form.cv.tag')))
->setOptions($this->config->get('cv.tags'))
->setDefault($this->config->get('cv.default_tag'))
->setRequired(true));
$form->addField(new TextField('industry', $this->translator->trans('form.cv.industry')));
$form->addField(new TextField('qualification', $this->translator->trans('form.cv.qualification'), false));
$this->addFlatGroupField($form, 'skills', false, 'cv')
->addFlatGroupField($form, 'achievements', false, 'cv')
->addFlatGroupField($form, 'toolbox', false, 'cv');
$form->addField(new TextField('text', $this->translator->trans('form.cv.text'), false));
$form->addField(new BooleanField('use_in_resume', $this->translator->trans('form.cv.use_in_resume')));
return $form;
}
}

View File

@@ -0,0 +1,121 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Extension;
use Droath\ConsoleForm\Field\Field as BaseField;
use Magdev\Dossier\Form\Field\SelectField;
use Magdev\Dossier\Form\Base\DecoratableLabelInterface;
use Magdev\Dossier\Form\Traits\DecoratableLabelTrait;
/**
* Field extension to use multiselect option on SelectField
*
* @author magdev
*/
class Field extends BaseField implements DecoratableLabelInterface
{
use DecoratableLabelTrait;
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\Field::setCondition()
*/
public function setCondition($field_name, $value, $operation = '=')
{
if (is_callable($value)) {
$this->condition[$field_name] = $value;
return $this;
}
$this->condition[$field_name] = [
'value' => $value,
'operation' => $operation
];
return $this;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\Field::asQuestion()
*/
public function asQuestion()
{
$instance = $this->questionClassInstance()
->setMaxAttempts($this->maxAttempt);
if ($this->hidden) {
$instance->setHidden(true);
}
if ($this instanceof SelectField) {
$instance->setMultiselect($this->isMultiSelect());
}
if ($this->isRequire()) {
$this->setValidation(function ($answer) {
if ($answer == '' && $this->dataType() !== 'boolean') {
throw new \Exception('Field is required.');
}
});
}
$instance->setValidator(function ($answer) {
foreach ($this->validation as $callback) {
if (!is_callable($callback)) {
continue;
}
$callback($answer);
}
return $answer;
});
if (isset($this->normalizer) && is_callable($this->normalizer)) {
$instance->setNormalizer($this->normalizer);
}
return $instance;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\Field::formattedLabel()
*/
protected function formattedLabel()
{
$label[] = '<fg=cyan;options=bold>'.$this->decorateLabel($this->label, (string) $this->default, '[*]').'</> ';
$label[] = isset($this->default) ? "<fg=yellow;options=bold>[$this->default]</> " : '';
$label[] = $this->isRequire() ? '<fg=red;options=bold>[*]</>: ' : ': ';
return implode('', $label);
}
}

339
src/Form/Extension/Form.php Normal file
View File

@@ -0,0 +1,339 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Extension;
use Droath\ConsoleForm\Form as BaseForm;
use Droath\ConsoleForm\Field\Field;
use Droath\ConsoleForm\Exception\FormException;
use Droath\ConsoleForm\FieldDefinitionInterface;
use Droath\ConsoleForm\Field\FieldInterface;
use Magdev\Dossier\Form\Base\DecoratableLabelInterface;
use Magdev\Dossier\Form\Traits\DecoratableLabelTrait;
/**
* Base Form class
*
* @author magdev
*/
class Form extends BaseForm implements DecoratableLabelInterface
{
use DecoratableLabelTrait;
/**
* Callback to post-process form results
* @var array
*/
protected $formResultsCallbacks = array();
/**
* Callback to pre-process data on load
* @var array
*/
protected $formLoadCallbacks = array();
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Form::addField()
*/
public function addField(FieldDefinitionInterface $field)
{
if ($field instanceof DecoratableLabelInterface) {
$field->setLabelLength($this->getLabelLength())
->setLabelPrefix($this->getLabelPrefix());
}
$this->fields[] = $field;
return $this;
}
/**
* Get a field by name
*
* @param string $name
* @throws \Droath\ConsoleForm\Exception\FormException
* @return \Droath\ConsoleForm\FieldDefinitionInterface
*/
public function getField(string $name): FieldDefinitionInterface
{
foreach ($this->fields as $field) {
if ($field->getName() == $name) {
return $field;
}
}
throw new FormException('Field '.$field.' not found');
}
/**
* Check if a field exists
*
* @param string $name
* @return bool
*/
public function hasField(string $name): bool
{
try {
$this->getField($name);
return true;
} catch (FormException $e) {
return false;
}
}
/**
* Set default values
*
* @param array $defaults
* @return \Magdev\Dossier\Form\Extension\Form
*/
public function setDefaults(array $defaults): Form
{
if ($this->hasFormLoadCallbacks()) {
$defaults = $this->onFormLoad($defaults);
}
foreach ($defaults as $field => $value) {
if ($this->hasField($field)) {
$field = $this->getField($field)->setDefault($value);
}
}
return $this;
}
/**
* Check if the is already processed
*
* @return bool
*/
public function isProcessed(): bool
{
return sizeof($this->results) > 0 ? true : false;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Form::process()
*/
public function process()
{
if (!$this->isProcessed()) {
$this->results = $this->processFields($this->fields, $this->results);
if ($this->hasFormResultsCallbacks()) {
$this->results = $this->onFormResults($this->results);
}
}
return $this;
}
/**
* Ceck if a data value is set
*
* @param string $name
* @throws \Droath\ConsoleForm\Exception\FormException
* @return bool
*/
public function hasData(string $name): bool
{
if (!$this->isProcessed()) {
throw new FormException('Please process the form first');
}
return isset($this->results[$name]) && !empty($this->results[$name]) ? true : false;
}
/**
* Get a value from result and optional delete the field
*
* @param string $name
* @param bool $unset
* @throws \Droath\ConsoleForm\Exception\FormException
* @return string|bool|array
*/
public function getData(string $name = null, bool $unset = false, $default = null)
{
if (!$this->isProcessed()) {
throw new FormException('Please process the form first');
}
if (is_null($name)) {
return $this->results;
}
$value = $default;
if ($this->hasData($name)) {
$value = $this->results[$name];
if ($unset) {
unset($this->results[$name]);
}
}
return $value;
}
/**
* Get a value and strip it from results
*
* @param string $key
* @param string|boolean|array|null $default
* @return string|boolean|array
*/
public function stripData(string $key, $default = null)
{
return $this->hasData($key) ? $this->getData($key, true) : $default;
}
/**
* Check if the form has result callbacks
*
* @return bool
*/
public function hasFormResultsCallbacks(): bool
{
return sizeof($this->formResultsCallbacks) > 0;
}
/**
* Add a callback to perform on results after processing
*
* @param callable $function
* @return \Magdev\Dossier\Form\Extension\Form
*/
public function addFormResultsCallback(callable $callback): Form
{
$this->formResultsCallbacks[] = $callback;
return $this;
}
/**
* Form results callback handler
*
* @param array $results
* @return array
*/
public function onFormResults(array $results): array
{
foreach ($this->formResultsCallbacks as $callback) {
$results = call_user_func_array($callback, array($results, $this));
}
return $results;
}
/**
* Check if the form has load callbacks
*
* @return bool
*/
public function hasFormLoadCallbacks(): bool
{
return sizeof($this->formLoadCallbacks) > 0;
}
/**
* Add a callback to perform on results after processing
*
* @param callable $function
* @return \Magdev\Dossier\Form\Extension\Form
*/
public function addFormLoadCallback(callable $callback): Form
{
$this->formLoadCallbacks[] = $callback;
return $this;
}
/**
* Form results callback handler
*
* @param array $results
* @return array
*/
public function onFormLoad(array $results): arry
{
foreach ($this->formLoadCallbacks as $callback) {
$results = call_user_func_array($callback, array($results, $this));
}
return $results;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Form::fieldConditionMet()
*/
protected function fieldConditionMet(FieldInterface $field, array $results)
{
$conditions = [];
foreach ($field->getCondition() as $field_name => $condition) {
$field_value = $this->getFieldValue($field_name, $results);
if (is_callable($condition)) {
$conditions[] = call_user_func_array($condition, array($field_value, $results, $this));
} else {
if (is_array($field_value) && key_exists($field_name, $field_value)) {
$field_value = $field_value[$field_name];
}
$value = $condition['value'];
$operation = $condition['operation'];
switch ($operation) {
case "!=":
$conditions[] = $field_value != $value;
break;
case '=':
default:
$conditions[] = $field_value == $value;
break;
}
}
}
$conditions = array_unique($conditions);
return sizeof($conditions) === 1 ? reset($conditions) : false;
}
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Droath\ConsoleForm\FormDiscovery as BaseFormDiscovery;
use Droath\ConsoleForm\FormInterface;
use Magdev\Dossier\Form\Base\FormBuilderInterface;
class FormDiscovery extends BaseFormDiscovery
{
/**
* Container
* @var \Symfony\Component\DependencyInjection\ContainerBuilder
*/
protected $container = null;
/**
* Constructor
*
* @param string $depth
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
*/
public function __construct(ContainerBuilder $container, $depth = '< 3')
{
parent::__construct($depth);
$this->container = $container;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormDiscovery::doDiscovery()
*/
protected function doDiscovery(array $directories, $base_namespace)
{
$forms = [];
$filter = $this->filterByNamespace($base_namespace);
$config = $this->container->get('config');
$translator = $this->container->get('translator');
foreach ($this->searchFiles($directories, $filter) as $file) {
$ext = $file->getExtension();
$classname = $base_namespace . '\\' . $file->getBasename(".$ext");
if (!class_exists($classname)) {
throw new \Exception('Missing class found during form discovery. '.$classname);
}
$instance = new $classname();
/* @var $instance \Magdev\Dossier\Form\Base\FormBuilderInterface */
if (!$instance instanceof FormInterface) {
throw new \Exception(sprintf('Form class (%s) is missing \Droath\ConsoleForm\Form\FormInterface.', $classname));
}
if ($instance instanceof FormBuilderInterface) {
$forms[$instance->getName()] = $instance->setConfig($config)
->setTranslator($translator)
->buildForm();
} else {
$forms[$instance->getName()] = $instance->buildForm();
}
}
return $forms;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Field;
use Droath\ConsoleForm\Field\BooleanField as BaseBooleanField;
use Magdev\Dossier\Form\Base\DecoratableLabelInterface;
use Magdev\Dossier\Form\Traits\DecoratableLabelTrait;
/**
* Override BooleanField
*
* @author magdev
*/
class BooleanField extends BaseBooleanField implements DecoratableLabelInterface
{
use DecoratableLabelTrait;
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\BooleanField::formattedValue()
*/
public function formattedValue($value)
{
return $value === true ? true : false;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\BooleanField::formattedLabel()
*/
protected function formattedLabel()
{
// Convert boolean default into a readable format.
$default = $this->default ? 'yes' : 'no';
$l = $this->decorateLabel($this->label);
$label[] = "<fg=cyan;options=bold>'.$l.'</>";
$label[] = isset($default) ? "<fg=yellow>[$default]</>" : '';
return implode(' ', $label);
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Field;
use Droath\ConsoleForm\Field\SelectField as BaseSelectField;
use Magdev\Dossier\Form\Base\DecoratableLabelInterface;
use Magdev\Dossier\Form\Traits\DecoratableLabelTrait;
/**
* Extension for Field class to allow multiselects
*
* @author magdev
*/
class SelectField extends BaseSelectField implements DecoratableLabelInterface
{
use DecoratableLabelTrait;
/**
* Multiselect status
* @var bool
*/
protected $multiSelect = false;
/**
* Set field to multiselect
*
* @param bool $multiSelect
* @return \Magdev\Dossier\Form\Field\SelectField
*/
public function setMultiSelect(bool $multiSelect = true): SelectField
{
$this->multiSelect = $multiSelect;
return $this;
}
/**
* Checkif field is multiselect
*
* @return bool
*/
public function isMultiSelect(): bool
{
return $this->multiSelect;
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\SelectField::dataType()
*/
public function dataType()
{
return $this->isMultiSelect() ? 'array' : 'string';
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\Field\Field::formattedLabel()
*/
protected function formattedLabel()
{
$label[] = '<fg=cyan;options=bold>'.$this->decorateLabel($this->label).'</>';
$label[] = isset($this->default) ? '<fg=yellow;options=bold>['.$this->default.']</>' : '';
$label[] = $this->isRequire() ? '<fg=red;options=bold>[*]</>: ' : ': ';
return implode(' ', $label);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Magdev\Dossier\Form\Field;
use Droath\ConsoleForm\Field\FieldInterface;
use Droath\ConsoleForm\Exception\FormException;
use Magdev\Dossier\Form\Extension\Field;
/**
* Define the text field as input via vim.
*/
class TextField extends Field implements FieldInterface
{
/**
* {@inheritdoc}
*/
public function dataType()
{
return 'string';
}
/**
* {@inheritdoc}
*/
public function questionClassArgs()
{
return [$this->formattedLabel(), $this->default];
}
/**
* {@inheritdoc}
*/
public function questionClass()
{
return '\Symfony\Component\Console\Question\Question';
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\Field\SelectField;
use Magdev\Dossier\Form\Field\TextField;
use Magdev\Dossier\Form\Field\BooleanField;
/**
* IntroFormBuilder
*
* @author magdev
*/
class InitFormBuilder extends Base\BaseFormBuilder implements Base\FormBuilderInterface
{
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::getName()
*/
public function getName()
{
return 'form.init';
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::buildForm()
*/
public function buildForm()
{
$form = new Form();
$form->setLabelPrefix($this->config->get('form.label.prefix'))
->setLabelLength($this->config->get('form.label.length'));
$form->addField((new BooleanField('use_userstyles', $this->translator->trans('form.init.use_userstyles')))
->setSubform(function($subform, $value) {
if ($value === true) {
$subform->addFields(array(
(new SelectField('userstyle_type', $this->translator->trans('form.init.userstyle_type')))
->setOptions(array('SCSS', 'LESS'))
->setDefault('SCSS')
->setRequired(true)
));
}
}));
return $form;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\Field\SelectField;
use Magdev\Dossier\Form\Field\TextField;
use Magdev\Dossier\Form\Field\BooleanField;
/**
* IntroFormBuilder
*
* @author magdev
*/
class IntroFormBuilder extends Base\BaseFormBuilder implements Base\FormBuilderInterface
{
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::getName()
*/
public function getName()
{
return 'form.intro';
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::buildForm()
*/
public function buildForm()
{
$form = new Form();
$form->setLabelPrefix($this->config->get('form.label.prefix'))
->setLabelLength($this->config->get('form.label.length'));
$form->addField(new TextField('text', $this->translator->trans('form.intro.text'), false));
$form->addField((new BooleanField('addquotes', $this->translator->trans('form.intro.add_quotes')))
->setSubform(function($subform, $value) {
if ($value === true) {
$subform->addField((new FieldGroup('quotes'))
->addFields(array(
(new TextField('quoteText', $this->translator->trans('form.intro.quote_text'), false)),
(new TextField('quoteAuthor', $this->translator->trans('form.intro.quote_author')))
->setCondition('quoteText', '', '!=')
))->setLoopUntil(function($result) {
if (!isset($result['quoteText']) || empty($result['quoteText'])) {
return false;
}
return true;
}));
$subform->addFeld((new SelectField('show_quotes', $this->translator->trans('form.intro.show_quotes')))
->setOptions(array('top', 'bottom'))
->setDefault('bottom')
->setCondition('quotes', function($value, $results, $f) {
return is_array($value) && sizeof($value) > 0 ? true : false;
}));
}
}));
return $form;
}
}

View File

@@ -0,0 +1,105 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form;
use Droath\ConsoleForm\FieldGroup;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\Field\SelectField;
use Magdev\Dossier\Form\Field\TextField;
use Magdev\Dossier\Form\Field\BooleanField;
/**
* IntroFormBuilder
*
* @author magdev
*/
class PersonFormBuilder extends Base\BaseFormBuilder implements Base\FormBuilderInterface
{
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::getName()
*/
public function getName()
{
return 'form.person';
}
/**
* {@inheritDoc}
* @see \Droath\ConsoleForm\FormInterface::buildForm()
*/
public function buildForm()
{
$form = new Form();
$form->setLabelPrefix($this->config->get('form.label.prefix'))
->setLabelLength($this->config->get('form.label.length'))
->addFormLoadCallback($this->getUnflattenCallback())
->addFormResultsCallback($this->getFlattenCallback());
$form->addField(new TextField('firstame', $this->translator->trans('form.person.firstname')));
$form->addField(new TextField('lastame', $this->translator->trans('form.person.lastname')));
$form->addField(new TextField('tagline', $this->translator->trans('form.person.tagline'), false));
$form->addField(new TextField('nationality', $this->translator->trans('form.person.nationality'), false));
$form->addField(new TextField('birthdate', $this->translator->trans('form.person.birthdate'), false));
$form->addField((new TextField('birthplace', $this->translator->trans('form.person.birthplace'), false))
->setCondition('birthdate', '', '!='));
$form->addField(new TextField('residence', $this->translator->trans('form.person.residence'), false));
$form->addField(new TextField('status', $this->translator->trans('form.person.status'), false));
$form->addField(new TextField('work_license', $this->translator->trans('form.person.work_license'), false));
$form->addField((new BooleanField('addlang', $this->translator->trans('form.person.add_languages')))
->setSubform(function($subform, $value) {
if ($value === true) {
$subform->addField((new FieldGroup('languages'))
->addFields(array(
(new TextField('language', $this->translator->trans('form.person.language'), false)),
(new SelectField('level', $this->translator->trans('form.person.level')))
->setOptions($this->config->get('language.levels'))
->setDefault($this->config->get('language.default_level'))
->setRequired(true)
->setCondition('language', '', '!=')
))->setLoopUntil(function($result) {
if (!isset($result['language']) || empty($result['language'])) {
return false;
}
return true;
}));
}
}));
$this->addFlatGroupField($form, 'skills', false, 'person')
->addFlatGroupField($form, 'projects', false, 'person')
->addFlatGroupField($form, 'links', false, 'person')
->addFlatGroupField($form, 'interests', false, 'person');
$form->addField(new TextField('text', $this->translator->trans('form.person.text'), false));
return $form;
}
}

View File

@@ -0,0 +1,129 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Form\Traits;
use Magdev\Dossier\Form\Extension\Form;
use Magdev\Dossier\Form\Base\DecoratableLabelInterface;
/**
* Trait for classes with decoratable labels
*
* @author magdev
*/
trait DecoratableLabelTrait
{
/**
* Label prefix
* @var string
*/
protected $labelPrefix = '';
/**
* Label length
* @var int
*/
protected $labelLength = -1;
/**
* Set a label prefix
*
* @param string $prefix
* @return \Magdev\Dossier\Form\Base\DecoratableLabelInterface
*/
public function setLabelPrefix(string $prefix): DecoratableLabelInterface
{
$this->labelPrefix = $prefix;
return $this;
}
/**
* Set a label fixed length
*
* @param int $length
* @return \Magdev\Dossier\Form\Base\DecoratableLabelInterface
*/
public function setLabelLength(int $length): DecoratableLabelInterface
{
$this->labelLength = $length;
return $this;
}
/**
* Get the label prefix
*
* @return string
*/
public function getLabelPrefix(): string
{
return $this->labelPrefix;
}
/**
* Get the label length
*
* @return int
*/
public function getLabelLength(): int
{
return $this->labelLength;
}
/**
* Get the decorated label
*
* @param string $label
* @return string
*/
public function decorateLabel(string $label, string $default = '', string $required = ''): string
{
$labelLength = strlen($label);
$defaultLength = (strlen($default) + 2);
$requiredLength = strlen($required);
if ($requiredLength > 0) {
$requiredLength++;
}
$length = $this->labelLength - ($defaultLength + $requiredLength);
$l = $this->labelPrefix;
if ($this->labelLength > 0) {
$l .= str_pad($label, $length, ' ', STR_PAD_RIGHT);
} else {
$l .= $label;
}
return $l;
}
}

220
src/Helper/ExportHelper.php Normal file
View File

@@ -0,0 +1,220 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Helper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Yaml\Yaml;
/**
* Export helper class
*
* @author magdev
*/
class ExportHelper extends Helper
{
const JSON = 'json';
const YAML = 'yaml';
const PHP = 'php';
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Helper\HelperInterface::getName()
*/
public function getName()
{
return 'export';
}
/**
* Convert an assoziatve array to a tablerow-style array
*
* @param array $source
* @return array
*/
public function arrayToTableRow(array $source): array
{
return array(array_values($source));
}
/**
* Convert an array of assoziatve arrays to a tablerows-style array
*
* @param array $source
* @return array
*/
public function arrayToTableRows(array $source): array
{
$rows = array();
foreach ($source as $values) {
$rows[] = $this->arrayToTableRow($values);
}
return $rows;
}
/**
* Convert tablerow-style array to an assoziatve array
*
* @param array $source
* @return array
*/
public function tableRowToArray(array $source, array $keys): array
{
return array_combine($keys, array_shift($source));
}
/**
* Convert an array of tablerow-style arrays to an array of assoziatve arrays
*
* @param array $source
* @return array
*/
public function tableRowsToArray(array $source, array $keys): array
{
$array = array();
foreach ($source as $row) {
$array[] = $this->tableRowToArray($row, $keys);
}
return $array;
}
/**
* Check if an array is a tablerow-style array
*
* @param array $array
* @return bool
*/
public function isTableRowStyle(array $source): bool
{
return isset($source[0]) === true;
}
/**
* Export data to a given format
*
* @param array $source
* @param string $type (json|yaml)
* @param string $file
* @throws \Symfony\Component\Console\Exception\RuntimeException
* @return bool
*/
public function export(array $source, string $type, string $file): bool
{
$code = $this->convert($source, $type);
if ($bytes = file_put_contents($file, $code) === false) {
throw new RuntimeException('Error while writing target: '.$file);
}
return true;
}
/**
* Convert data to a given format
*
* @param array $source
* @param string $type
* @throws \Symfony\Component\Console\Exception\RuntimeException
* @return string
*/
public function convert(array $source, string $type): string
{
switch ($type) {
case self::JSON: return $this->toJSON($source);
case self::YAML: return $this->toYAML($source);
case self::PHP: return $this->toPHP($source);
default:
throw new RuntimeException('Invalid export type: '.strtoupper($type));
}
}
/**
* Convert an assoziatve array to JSON
*
* @param array $source
* @param bool $pretty
* @return string
*/
public function toJSON(array $source, bool $pretty = true): string
{
if ($pretty) {
return json_encode($source, JSON_FORCE_OBJECT|JSON_PRETTY_PRINT);
}
return json_encode($source, JSON_FORCE_OBJECT);
}
/**
* Convert an assoziatve array to YAML
*
* @param array $source
* @param int $depth
* @param int $indent
* @return string
*/
public function toYAML(array $source, int $depth = 3, int $indent = 2): string
{
return Yaml::dump($source, $depth, $indent);
}
/**
* Convert values to PHP sourcecode
*
* @param mixed $source
* @param bool $includeReturn
* @param bool $includeTags
* @return string
*/
public function toPHP($source, bool $includeReturn = false, bool $includeTags = false): string
{
$code = '';
if ($includeTags) {
$code .= '<?php'.PHP_EOL;
}
if ($includeReturn) {
$code .= 'return ';
}
$code .= var_export($source, true);
if ($includeReturn || $includeTags) {
$code .= ';'.PHP_EOL;
}
return $code;
}
}

106
src/Helper/OutputHelper.php Normal file
View File

@@ -0,0 +1,106 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Helper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magdev\Dossier\Style\DossierStyle;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
class OutputHelper extends Helper
{
/**
* IO style object
* @var \Magdev\Dossier\Style\DossierStyle
*/
private $io = null;
private $appName = '';
private $appVersion = '';
public function __construct(string $appName = '', string $appVersion = '')
{
$this->appName = $appName;
$this->appVersion = $appVersion;
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Helper\HelperInterface::getName()
*/
public function getName()
{
return 'output';
}
/**
* Get the style helper for dossier
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return \Magdev\Dossier\Style\DossierStyle
*/
public function getIoStyle(InputInterface $input, OutputInterface $output): DossierStyle
{
if (!$this->io) {
$this->addOutputStyles($input, $output);
$this->io = new DossierStyle($input, $output);
$this->io->setAppName($this->appName)
->setAppVersion($this->appVersion);
}
return $this->io;
}
/**
* Add some output styles to the output object
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return \Magdev\Dossier\Helper\OutputHelper
*/
protected function addOutputStyles(InputInterface $input, OutputInterface $output): OutputHelper
{
$formatter = $output->getFormatter();
$formatter->setStyle('cmd', new OutputFormatterStyle('white', 'blue', array('bold')));
$formatter->setStyle('option', new OutputFormatterStyle('cyan', null, array('bold')));
$formatter->setStyle('lightmagenta', new OutputFormatterStyle('magenta', null, array('bold')));
$formatter->setStyle('lightgreen', new OutputFormatterStyle('green', null, array('bold')));
$formatter->setStyle('lightred', new OutputFormatterStyle('red', null, array('bold')));
$formatter->setStyle('lightyellow', new OutputFormatterStyle('yellow', null, array('bold')));
return $this;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Helper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Magdev\Dossier\Service\ConfigService;
/**
* Section manager
*
* @author magdev
*/
class SectionManagerHelper extends Helper
{
/**
* Configuration service
* @var \Magdev\Dossier\Service\ConfigService
*/
protected $config = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\ConfigService $config
*/
public function __construct(ConfigService $config)
{
$this->config = $config;
}
/**
* {@inheritDoc}
* @see \Symfony\Component\Console\Helper\HelperInterface::getName()
*/
public function getName()
{
return 'section_manager';
}
/**
* Get an array with section visibility settings
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @return array
*/
public function getDisabledSections(InputInterface $input): array
{
return array(
'cover' => (bool) $input->getOption('no-cover') || $this->config->get('disable.cover', false),
'intro' => (bool) $input->getOption('no-intro') || $this->config->get('disable.intro', false),
'resume' => (bool) $input->getOption('no-resume') || $this->config->get('disable.resume', false),
'cv' => (bool) $input->getOption('no-cv') || $this->config->get('disable.cv', false),
'certs' => (bool) $input->getOption('no-certs') || $this->config->get('disable.certs', false),
'quotes' => (bool) $input->getOption('no-quotes') || $this->config->get('disable.quotes', false),
'toc' => (bool) $input->getOption('no-toc') || $this->config->get('disable.toc', false),
'projects' => (bool) $input->getOption('no-projects') || $this->config->get('disable.projects', false),
);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Base;
/**
* Interface for objects with a postal address
*
* @author magdev
*/
interface AddressInterface
{
/**
* Get address line 1
*
* @return string
*/
public function getAddress1(): string;
/**
* Get address line 2
*
* @return string
*/
public function getAddress2(): string;
/**
* Get the name of the city
*
* @return string
*/
public function getCity(): string;
/**
* Get the postcode
*
* @return string
*/
public function getPostcode(): string;
/**
* Get the country code
*
* @return string
*/
public function getCountry(): string;
/**
* Get the full location string
*
* @return string
*/
public function getLocation(): string;
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Base;
abstract class BaseCollection extends \ArrayObject
{
const SORT_ASC = 'asc';
const SORT_DESC = 'desc';
/**
* Set the sort direction
* @var string
*/
protected $sortDirection = self::SORT_ASC;
/**
* The last sort direction, used for reset
* @var string
*/
protected $storedDirection = null;
/**
* Set the sort direction
*
* @param string $sortDirection
* @param bool $temporary
* @return \Magdev\Dossier\Model\BaseCollection
*/
public function setSortDirection(string $sortDirection, bool $temporary = false): BaseCollection
{
if (!$temporary) {
$this->storedDirection = $this->sortDirection;
}
$this->sortDirection = $sortDirection;
return $this;
}
/**
* Reset a temporary sort direction
*
* @return \Magdev\Dossier\Model\BaseCollection
*/
public function resetSortDirection(): BaseCollection
{
if ($this->storedDirection) {
$this->sortDirection = $this->storedDirection;
$this->storedDirection = null;
}
return $this;
}
}

View File

@@ -0,0 +1,253 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Base;
use Mni\FrontYAML\Document;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Magdev\Dossier\Model\Traits\VarnameConverterTrait;
/**
* Abstract model for Markdown files
*
* @author magdev
*/
abstract class BaseModel
{
use VarnameConverterTrait;
/**
* FrontYAML Document
* @var \Mni\FrontYAML\Document
*/
protected $document = null;
/**
* Additional data
* @var \ArrayObject
*/
protected $additionalData = null;
/**
* Set some properties to ignore while analysing
* @var \ArrayObject
*/
protected $ignoredProperties = null;
/**
* Constructor
*
* @param \Mni\FrontYAML\Document $document
*/
public function __construct(Document $document)
{
$this->document = $document;
$this->additionalData = new \ArrayObject();
$this->ignoredProperties = new \ArrayObject(array(
'ignoreProperties',
'document'
));
$this->load();
}
/**
* Get the document object
*
* @return \Mni\FrontYAML\Document
*/
public function getDocument(): Document
{
return $this->document;
}
/**
* Get the parsed Markdown part of the file
*
* @return string
*/
public function getContent(): string
{
return $this->document->getContent();
}
/**
* Get the YAML content of the file
*
* @return array
*/
public function getYAML(): array
{
$yaml = $this->document->getYAML();
if (is_null($yaml)) {
return array();
}
return $yaml;
}
/**
* Wrapper to access the page content as description
*
* @return string
*/
public function getDescription(): string
{
return $this->getContent();
}
/**
* Get additional data
*
* @return \ArrayObject
*/
public function getAdditionalData(): \ArrayObject
{
return $this->additionalData;
}
/**
* Check if model has additional data
*
* @return bool
*/
public function hasAdditionalData(): bool
{
return $this->additionalData->count() > 0 ? true : false;
}
/**
* Get an array with all data values
*
* @return array
*/
public function toArray(): array
{
return get_object_vars($this);
}
/**
* Add an ignored property
*
* @param string $prop
* @return BaseModel
*/
protected function addIgnoredProperty(string $prop): BaseModel
{
if (!in_array($prop, $this->ignoredProperties->getArrayCopy())) {
$this->ignoredProperties->append($prop);
}
return $this;
}
/**
* Add multiple ignored prperties
*
* @param array $props
* @return BaseModel
*/
protected function addIgnoredProperties(array $props): BaseModel
{
foreach ($props as $prop) {
$this->addIgnoredProperty($prop);
}
return $this;
}
/**
* Add additional data
*
* @param string $key
* @param mixed $value
* @return \Magdev\Dossier\Model\Base\BaseModel
*/
protected function addAdditionalData(string $key, $value): BaseModel
{
$this->additionalData->append(array('key' => $key, 'value' => $value));
return $this;
}
/**
* Set a property
*
* @param string $key
* @param mixed $value
* @return \Magdev\Dossier\Model\Base\BaseModel
*/
protected function setProperty(string $key, $value): BaseModel
{
$prop = $this->convertCase($key);
if (property_exists($this, $prop)) {
$this->{$prop} = $value;
} else if ($this instanceof BaseModel) {
$this->addAdditionalData($prop, $value);
} else {
throw new InvalidArgumentException('Unknow property: '.__CLASS__.'::'.$prop);
}
return $this;
}
/**
* Load YAML data into model properties
*
* @return \Magdev\Dossier\Model\Base\BaseModel
*/
protected function load(): BaseModel
{
$yaml = $this->getYAML();
return $this->loadArray($yaml);
}
/**
* Laod data from array
*
* @param array $data
* @return \Magdev\Dossier\Model\Base\BaseModel
*/
protected function loadArray(array $data): BaseModel
{
foreach ($data as $key => $value) {
$this->setProperty($key, $value);
}
return $this;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Base;
/**
* Interface for exportable models
*
* @author magdev
*/
interface ModelExportableInterface extends ModelInterface
{
/**
* Get the data as assoziative array
*
* @return array
*/
public function getData(): array;
/**
* Get the text content as string
*
* @return string
*/
public function getText(): string;
/**
* Check if the model has data
*
* @return bool
*/
public function hasData(): bool;
/**
* Check if the model has text content
*
* @return bool
*/
public function hasText(): bool;
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Base;
interface ModelInterface
{
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Base;
/**
* Interface for modle with photo capabilities
*
* @author magdev
*/
interface PhotoInterface
{
/**
* Get the photo
*
* @return \SplFileInfo
*/
public function getPhoto(): \SplFileInfo;
/**
* Check if the model has a photo
*
* @return bool
*/
public function hasPhoto(): bool;
/**
* Get the size of the photo
*
* @return int
*/
public function getPhotoSize(): int;
/**
* Set the photo
*
* @param string $path
* @return \Magdev\Dossier\Model\Base\PhotoInterface
*/
public function setPhoto(string $path): PhotoInterface;
}

View File

@@ -0,0 +1,240 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model;
use Magdev\Dossier\Model\CurriculumVitae\Entry;
use Magdev\Dossier\Service\FormatterService;
use Magdev\Dossier\Model\Base\BaseCollection;
/**
* Collection of CV-Entries
*
* @author magdev
*/
class CurriculumVitae extends BaseCollection
{
/**
* Formatter Service
* @var \Magdev\Dossier\Service\FormatterService
*/
protected $formatter = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\FormatterService $formatter
*/
public function __construct(FormatterService $formatter)
{
$this->formatter = $formatter;
}
/**
* Filter entries by tag
*
* @param string $tag
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function filterByTag(string $tag): CurriculumVitae
{
$result = new self($this->formatter);
foreach ($this as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($entry->getTag() == $tag) {
$result->append($entry);
}
}
$result->setSortDirection($this->sortDirection)->sort();
return $result;
}
/**
* Filter entries by industry
*
* @param string $industry
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function filterByIndustry(string $industry): CurriculumVitae
{
$result = new self($this->formatter);
foreach ($this as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($entry->getIndustry() == $industry) {
$result->append($entry);
}
}
$result->setSortDirection($this->sortDirection)->sort();
return $result;
}
/**
* Filter entries by certificates
*
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function filterByCertificates(): CurriculumVitae
{
$result = new self($this->formatter);
foreach ($this as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($entry->hasCertificates()) {
$result->append($entry);
}
}
$result->setSortDirection($this->sortDirection)->sort();
return $result;
}
/**
* Get entries with qualification
*
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function getQualifications(): CurriculumVitae
{
$result = new self($this->formatter);
foreach ($this as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($entry->getQualification()) {
$result->append($entry);
}
}
$result->setSortDirection($this->sortDirection)->sort();
return $result;
}
/**
* Filter entries used for resume
*
* @param bool $useInResume
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function filterByUseInResume(bool $useInResume = true): CurriculumVitae
{
$result = new self($this->formatter);
foreach ($this as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($entry->useInResume()) {
$result->append($entry);
}
}
$result->setSortDirection($this->sortDirection)->sort();
return $result;
}
/**
* Filter entries by toolbox contents
*
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function filterByToolbox(): CurriculumVitae
{
$result = new self($this->formatter);
foreach ($this as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($entry->getToolbox()->count() > 0) {
$result->append($entry);
}
}
$result->setSortDirection($this->sortDirection)->sort();
return $result;
}
/**
* Get the length of experience sorted by industry
*
* @return \ArrayObject
*/
public function getExperienceYears(): \ArrayObject
{
$result = new \ArrayObject();
$entries = $this->filterByTag('experience');
foreach ($entries as $entry) {
/* @var $entry \Magdev\Dossier\Model\CurriculumVitae\Entry */
if ($industry = $entry->getIndustry()) {
if (!array_key_exists($industry, $result)) {
$result[$industry] = 0;
}
$result[$industry] += $entry->getExperienceLength();
}
}
$result->uasort(function(int $a, int $b) {
return $a > $b ? -1 : 1;
});
$formatter = $this->formatter;
array_walk($result, function(int &$seconds, string $key) use ($formatter) {
$seconds = $formatter->formatExperience($seconds);
});
return $result;
}
/**
* Sort by start date
*
* @return \Magdev\Dossier\Model\CurriculumVitae
*/
public function sort(): CurriculumVitae
{
$this->uasort(array($this, 'sortByStartDate'));
return $this;
}
/**
* Sort function to sort by start date
*
* @param \Magdev\Dossier\Model\CurriculumVitae\Entry $a
* @param \Magdev\Dossier\Model\CurriculumVitae\Entry $b
* @return int
*/
protected function sortByStartDate(Entry $a, Entry $b): int
{
$first = $a->getStartDate()->format('U');
$second = $b->getStartDate()->format('U');
if ($first == $second) {
return 0;
}
if ($this->sortDirection == self::SORT_DESC) {
return $first > $second ? -1 : 1;
}
return $first < $second ? -1 : 1;
}
}

View File

@@ -0,0 +1,357 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\CurriculumVitae;
use Magdev\Dossier\Model\AbstractModel;
use Magdev\Dossier\Model\Traits\PhotoTrait;
use Mni\FrontYAML\Document;
use Magdev\Dossier\Model\Base\BaseModel;
use Magdev\Dossier\Analyzer\Base\AnalyzableInterface;
use Magdev\Dossier\Model\Base\PhotoInterface;
/**
* Model for CV entries
*
* @author magdev
*/
final class Entry extends BaseModel implements PhotoInterface, AnalyzableInterface
{
use PhotoTrait;
/**
* Start date
* @var \DateTime
*/
protected $startDate = null;
/**
* End date
* @var \DateTime
*/
protected $endDate = null;
/**
* Tag - either education, experience or other
* @var string
*/
protected $tag = '';
/**
* Employer information
* @var string
*/
protected $company = '';
/**
* Obtained Qualification, i.e. graduations
* @var string
*/
protected $qualification = '';
/**
* Name of the position or role
* @var string
*/
protected $position = '';
/**
* Obtained skills
* @var array
*/
protected $skills = array();
/**
* Achievements - for the sake of glory!
* @var array
*/
protected $achievements = array();
/**
* Industry title
* @var string
*/
protected $industry = '';
/**
* Use this entry in resume
* @var bool
*/
protected $useInResume = false;
/**
* Certificate models
* @var \ArrayObject
*/
protected $certs = null;
/**
* Notes
* @var string
*/
protected $notes = '';
/**
* Toolbox
* @var array
*/
protected $toolbox = array();
/**
* Constrctor
*
* @param \Mni\FrontYAML\Document $document
*/
public function __construct(Document $document)
{
$this->certs = new \ArrayObject();
parent::__construct($document);
}
/**
* Get the start date
*
* @return \DateTime
*/
public function getStartDate(): \DateTime
{
if ($this->startDate) {
$date = new \DateTime($this->startDate);
$date->setTime(0, 0);
return $date;
}
return null;
}
/**
* Get the end date
*
* @return \DateTime
*/
public function getEndDate(): \DateTime
{
if ($this->endDate) {
$date = new \DateTime($this->endDate);
$date->setTime(23, 59, 59);
return $date;
}
$date = new \DateTime();
$date->setTime(23, 59, 59);
return $date;
}
/**
* Get the tag for this entry
*
* @return string
*/
public function getTag(): string
{
return $this->tag;
}
/**
* get the company name
*
* @return string
*/
public function getCompany(): string
{
return $this->company;
}
/**
* Get the qualification obtained
*
* @return string
*/
public function getQualification(): string
{
return $this->qualification;
}
/**
* Get the position/job title
*
* @return string
*/
public function getPosition(): string
{
return $this->position;
}
/**
* Get the achievements
*
* @return array
*/
public function getAchievements(): array
{
return $this->achievements;
}
/**
* Get the obtained skills
*
* @return array
*/
public function getSkills(): array
{
return $this->skills;
}
/**
* Get the industry
*
* @return string
*/
public function getIndustry(): string
{
return $this->industry;
}
/**
* Get notes
*
* @return string
*/
public function getNotes(): string
{
return $this->notes;
}
/**
* Check if this entry should be included in the resume
*
* @return bool
*/
public function useInResume(): bool
{
return $this->useInResume;
}
/**
* Get the attachted certificates
*
* @return \ArrayObject(\Magdev\Dossier\Model\CurriculumVitae\Entry\Certificate[])
*/
public function getCertificates(): \ArrayObject
{
return $this->certs;
}
/**
* Check if entry has certificates
*
* @return bool
*/
public function hasCertificates(): bool
{
return $this->certs->count() > 0;
}
/**
* Get the toolbox
*
* @return \ArrayObject
*/
public function getToolbox(): \ArrayObject
{
return new \ArrayObject($this->toolbox);
}
/**
* Get the length of this entry in seconds
*
* @return int
*/
public function getExperienceLength(): int
{
return $this->getEndDate()->format('U') - $this->getStartDate()->format('U');
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Analyzer\Base\AnalyzableInterface::getAnalyzerData()
*/
public function getAnalyzerData(): array
{
$props = get_object_vars($this);
foreach ($this->ignoredProperties as $prop) {
unset($props[$prop]);
}
$props['text'] = $this->getContent();
return $props;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\BaseModel::loadArray()
*/
protected function loadArray(array $data): BaseModel
{
foreach ($data as $key => $value) {
if ($key == 'certs') {
foreach ($value as $cert) {
$c = new Entry\Certificate(PROJECT_ROOT.'/certs/'.$cert['path'], $cert['type']);
$this->certs->append($c);
}
} else if ($key == 'photo') {
$this->setPhoto($value);
} else {
$prop = $this->convertCase($key);
if (property_exists($this, $prop)) {
$this->{$prop} = $value;
} else {
$this->addAdditionalData($prop, $value);
}
}
}
return $this;
}
}

View File

@@ -0,0 +1,117 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\CurriculumVitae\Entry;
/**
* Certificate Model
*
* @author magdev
*/
class Certificate
{
/**
* Store the file object
*
* @var \SplFileObject
*/
protected $file = null;
/**
* Store the type of this certificate
*
* @var string
*/
protected $type = '';
/**
* Constructor
*
* @param string $path
* @param string $type
*/
public function __construct(string $path, string $type = '')
{
$this->file = new \SplFileObject($path);
$this->setType($type);
}
/**
* Get the file object
*
* @return \SplFileObject
*/
public function getFileObject(): \SplFileObject
{
return $this->file;
}
/**
* Set the type og the certificate
*
* @param string $type
* @return \Magdev\Dossier\Model\CurriculumVitae\Entry\Certificate
*/
public function setType(string $type): Certificate
{
$this->type = $type;
return $this;
}
/**
* Get the type of the certificate
*
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* Get the file contents as Data-URI
*
* @TODO Refactor to use UriHelperService
* @deprecated Use UriHelperService instead
* @return string
*/
public function getDataUri(): string
{
$fi = new \finfo();
$mimetype = $fi->file($this->file->getRealPath(), FILEINFO_MIME);
return 'data:'.$mimetype.'; base64,'.base64_encode(file_get_contents($this->file->getRealPath()));
}
}

154
src/Model/Intro.php Normal file
View File

@@ -0,0 +1,154 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model;
use Mni\FrontYAML\Document;
use Magdev\Dossier\Model\Base\BaseModel;
use Magdev\Dossier\Model\Base\ModelExportableInterface;
use Magdev\Dossier\Model\Base\PhotoInterface;
use Magdev\Dossier\Model\Traits\PhotoTrait;
use Magdev\Dossier\Analyzer\Base\AnalyzableInterface;
/**
* Model for introduction page
*
* @author magdev
*/
class Intro extends BaseModel implements PhotoInterface, AnalyzableInterface
{
const SHOW_TOP = 'top';
const SHOW_BOTTOM = 'bottom';
use PhotoTrait;
/**
* Quotes
* @var \ArrayObject
*/
protected $quotes = null;
/**
* Headline for intro page
* @var string
*/
protected $headline = '';
/**
* Place to show the quotes
*
* @var string
*/
protected $showQuotes = self::SHOW_TOP;
/**
* Get the headline
*
* @return string
*/
public function getHeadline(): string
{
return $this->headline;
}
/**
* Constructor
*
* @param Document $document
*/
public function __construct(Document $document)
{
$this->quotes = new \ArrayObject();
parent::__construct($document);
}
/**
* Get the quotes
*
* @return \ArrayObject
*/
public function getQuotes(): \ArrayObject
{
return $this->quotes;
}
/**
* Get the place where to show the quotes
*
* @return string
*/
public function getShowQuotes(): string
{
return $this->showQuotes;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\BaseModel::loadArray()
*/
protected function loadArray(array $data): BaseModel
{
foreach ($data as $key => $value) {
if ($key == 'quotes') {
foreach ($value as $quote) {
$q = new Intro\Quote($quote);
$this->quotes->append($q);
}
} else if ($key == 'photo') {
$this->setPhoto($value);
} else {
$this->setProperty($key, $value);
}
}
return $this;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Analyzer\Base\AnalyzableInterface::getAnalyzerData()
*/
public function getAnalyzerData(): array
{
$props = get_object_vars($this);
foreach ($this->ignoredProperties as $prop) {
unset($props[$prop]);
}
$props['text'] = $this->getContent();
return $props;
}
}

91
src/Model/Intro/Quote.php Normal file
View File

@@ -0,0 +1,91 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Intro;
use Magdev\Dossier\Model\AbstractModel;
/**
* Quote Model
*
* @author magdev
*/
final class Quote
{
/**
* Quote text
* @var string
*/
protected $quoteText = '';
/**
* Author of the quote
* @var string
*/
protected $quoteAuthor = '';
/**
* Constructor
*
* @param array $quote
*/
public function __construct(array $quote)
{
$this->quoteText = $quote['text'];
if (isset($quote['author'])) {
$this->quoteAuthor = $quote['author'];
}
}
/**
* Get the quote text
*
* @return string
*/
public function getQuoteText(): string
{
return $this->quoteText;
}
/**
* Get the author of the quote
*
* @return string
*/
public function getQuoteAuthor(): string
{
return $this->quoteAuthor;
}
}

422
src/Model/Person.php Normal file
View File

@@ -0,0 +1,422 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model;
use Magdev\Dossier\Model\Traits\PhotoTrait;
use Magdev\Dossier\Model\Base\BaseModel;
use Mni\FrontYAML\Document;
use Magdev\Dossier\Model\Person\Contact;
use Magdev\Dossier\Analyzer\Base\AnalyzableInterface;
use Magdev\Dossier\Model\Base\PhotoInterface;
use Magdev\Dossier\Model\Person\Reference;
/**
* Model for the person object
*
* @author magdev
*/
final class Person extends BaseModel implements PhotoInterface, AnalyzableInterface
{
use PhotoTrait;
/**
* First name
* @var string
*/
protected $firstname = '';
/**
* Last name
* @var string
*/
protected $lastname = '';
/**
* Birthdate
* @var string
*/
protected $birthdate = '';
/**
* Birthplace
* @var string
*/
protected $birthplace = '';
/**
* Tagline
* @var string
*/
protected $tagline = '';
/**
* Current residence
* @var string
*/
protected $residence = '';
/**
* Status
* @var string
*/
protected $status = '';
/**
* Nationality
* @var string
*/
protected $nationality = '';
/**
* Work license
* @var string
*/
protected $workLicense = '';
/**
* Languages
* @var array
*/
protected $languages = array();
/**
* Personal Links
* @var array
*/
protected $links = array();
/**
* Contact
* @var \ArrayObject
*/
protected $contacts = null;
/**
* References
* @var \ArrayObject
*/
protected $references = null;
/**
* Personal Interests
* @var array
*/
protected $interests = array();
/**
* Current Projects
* @var array
*/
protected $projects = array();
/**
* Constructor
*
* @param Mni\FrontYAML\Document $document
*/
public function __construct(Document $document)
{
$this->contacts = new \ArrayObject();
$this->references = new \ArrayObject();
parent::__construct($document);
}
/**
* Get the first name
*
* @return string
*/
public function getFirstname(): string
{
return $this->firstname;
}
/**
* Get the last name
*
* @return string
*/
public function getLastname(): string
{
return $this->lastname;
}
/**
* Get the full name
*
* @param bool $reversed
* @return string
*/
public function getName(bool $reversed = false): string
{
if ($reversed) {
return $this->lastname.', '.$this->firstname;
}
return $this->firstname.' '.$this->lastname;
}
/**
* Get the persons tagline
*
* @return string
*/
public function getTagline(): string
{
return $this->tagline;
}
/**
* Get the persons current residence
*
* @return string
*/
public function getResidence(): string
{
return $this->residence;
}
/**
* Get the birthday date
*
* @return \DateTime
*/
public function getBirthdate(): \DateTime
{
if ($this->birthdate) {
return new \DateTime($this->birthdate);
}
return null;
}
/**
* Get the birthplace
*
* @return string
*/
public function getBirthplace(): string
{
return $this->birthplace;
}
/**
* Get the family status
*
* @return string
*/
public function getStatus(): string
{
return $this->status;
}
/**
* Get the nationality
*
* @return string
*/
public function getNationality(): string
{
return $this->nationality;
}
/**
* Get languages
*
* @return array
*/
public function getLanguages(): array
{
return $this->languages;
}
/**
* Get personal links
*
* @return array
*/
public function getLinks(): array
{
return $this->links;
}
/**
* Get contact info
*
* @return \ArrayObject
*/
public function getContacts(): \ArrayObject
{
return $this->contacts;
}
/**
* Get references
*
* @return \ArrayObject
*/
public function getReferences(): \ArrayObject
{
return $this->references;
}
/**
* Get personal interests
*
* @return array
*/
public function getInterests(): array
{
return $this->interests;
}
/**
* Get current projects
*
* @return array
*/
public function getProjects(): array
{
return $this->projects;
}
/**
* Get the work license
*
* @return string
*/
public function getWorkLicense(): string
{
return $this->workLicense;
}
/**
* Get the email address
*
* @return string
*/
public function getEmail(): string
{
return $this->getContactType('email')->getAddress();
}
/**
* Get the phone number
*
* @return string
*/
public function getPhone(): string
{
return $this->getContactType('phone')->getAddress();
}
/**
* Get a contact with a specific type
*
* @param string $type
* @return \Magdev\Dossier\ModelContact
*/
public function getContactType(string $type): Contact
{
foreach ($this->getContacts() as $contact) {
/* @var $contact \Magdev\Dossier\Model\Person\Contact */
if ($contact->getType() == $type) {
return $contact->getAddress();
}
}
return '';
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\BaseModel::loadArray()
*/
protected function loadArray(array $data): BaseModel
{
foreach ($data as $key => $value) {
if ($key == 'photo') {
$this->setPhoto($value);
} else if ($key == 'contact') {
foreach ($value as $type => $address) {
if ($type == 'accounts' && is_array($address)) {
foreach ($address as $a) {
$this->contacts->append(new Contact($a['address'], $a['type']));
}
} else {
$this->contacts->append(new Contact($address, $type));
}
}
} else if ($key == 'references') {
foreach ($value as $reference) {
$this->references->append(new Reference($reference));
}
} else {
$this->setProperty($key, $value);
}
}
return $this;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Analyzer\Base\AnalyzableInterface::getAnalyzerData()
*/
public function getAnalyzerData(): array
{
$props = get_object_vars($this);
foreach ($this->ignoredProperties as $prop) {
unset($props[$prop]);
}
$props['text'] = $this->getContent();
return $props;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Person;
/**
* Contact model
*
* @author magdev
*/
class Contact
{
/**
* Contact address
* @var string
*/
protected $address = '';
/**
* Contact type
* @var string
*/
protected $type = '';
/**
* Constructor
*
* @param string $address
* @param string $type
*/
public function __construct(string $address, string $type)
{
$this->address = $address;
$this->type = $type;
}
/**
* Get the contact type
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* Get the contact address
* @return string
*/
public function getAddress(): string
{
return $this->address;
}
}

View File

@@ -0,0 +1,192 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Person;
use Magdev\Dossier\Model\Base\BaseModel;
/**
* Model for job references
*
* @author magdev
*/
class Reference extends BaseModel
{
/**
* Reference description
* @var string
*/
protected $decription = '';
/**
* Name of a possible contact person
* @var string
*/
protected $contactName = '';
/**
* Email address of a possible contact person
* @var string
*/
protected $contactEmail = '';
/**
* Phone number of a possible contact person
* @var string
*/
protected $contactPhone = '';
/**
* Refrence is published and can be viewed online
* @var bool
*/
protected $public = false;
/**
* Link to a published reference
* @var string
*/
protected $publicLink = '';
/**
* Example work as file
* @var \SplFileObject
*/
protected $file = null;
/**
* Link to an example work
* @var string
*/
protected $fileLink = null;
/**
* Constructor
*
* @param array $data
*/
public function __construct(array $data)
{
$this->loadArray($data);
}
/**
* Get the description of the reference
*
* @return string
*/
public function getDecription(): string
{
return $this->decription;
}
/**
* Get the name of a possible contact person
*
* @return string
*/
public function getContactName(): string
{
return $this->contactName;
}
/**
* Get the email address of a possible contact person
*
* @return string
*/
public function getContactEmail(): string
{
return $this->contactEmail;
}
/**
* Get the phone number of a possible contact person
*
* @return string
*/
public function getContactPhone(): string
{
return $this->contactPhone;
}
/**
* Check if the reference is published and can be viewed online
*
* @return boolean
*/
public function isPublic(): bool
{
return $this->public;
}
/**
* Lik to a published example work
*
* @return unknown
*/
public function getPublicLink(): string
{
return $this->publicLink;
}
/**
* Example work file
*
* @return \SplFileObject
*/
public function getFile(): \SplFileObject
{
return $this->file;
}
/**
* Get the link to a file with example work
*
* @return string
*/
public function getFileLink(): string
{
return $this->fileLink;
}
}

91
src/Model/Project.php Normal file
View File

@@ -0,0 +1,91 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model;
use Magdev\Dossier\Model\Base\BaseModel;
class Project extends BaseModel
{
protected $name = '';
protected $status = '';
protected $url = '';
protected $shortDescription = '';
protected $stack = '';
protected $role = '';
public function getRole(): string
{
return $this->role;
}
public function getStack(): string
{
return $this->stack;
}
public function getName(): string
{
return $this->name;
}
public function getStatus(): string
{
return $this->status;
}
public function getUrl(): string
{
return $this->url;
}
public function getShortDescription(): string
{
return $this->shortDescription;
}
}

View File

@@ -0,0 +1,149 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Traits;
trait AddressTrait
{
/**
* Address line 1
* @var string
*/
protected $address1 = '';
/**
* Address line 2
* @var string
*/
protected $address2 = '';
/**
* Name of the city
* @var string
*/
protected $city = '';
/**
* Postcode
* @var string
*/
protected $postcode = '';
/**
* Conutry code
* @var string
*/
protected $country = '';
/**
* Constructor
*
* @param array $data
*/
public function __construct(array $data)
{
foreach ($data as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\AddressInterface::getAddress1()
*/
public function getAddress1(): string
{
return $this->address1;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\AddressInterface::getAddress2()
*/
public function getAddress2(): string
{
return $this->address2;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\AddressInterface::getCity()
*/
public function getCity(): string
{
return $this->city;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\AddressInterface::getPostcode()
*/
public function getPostcode(): string
{
return $this->postcode;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\AddressInterface::getCountry()
*/
public function getCountry(): string
{
return $this->country;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\AddressInterface::getLocation()
*/
public function getLocation(): string
{
$location = '';
if ($this->postcode) {
$location .= $this->postcode.' ';
}
if ($this->city) {
$location .= $this->city;
}
if ($this->country) {
$location .= ' ('.$this->country.')';
}
return $location;
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Traits;
trait MarkdownExportTrait
{
protected $text = '';
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\ModelExportableInterface::getData()
*/
public function getData(): array
{
return get_object_vars($this);
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\ModelExportableInterface::getText()
*/
public function getText(): string
{
return $this->text;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\ModelExportableInterface::hasData()
*/
public function hasData(): bool
{
return sizeof($this->getData()) > 0 ? true : false;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Model\Base\ModelExportableInterface::hasText()
*/
public function hasText(): bool
{
}
}

View File

@@ -0,0 +1,129 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Traits;
use Magdev\Dossier\Model\AbstractModel;
use Magdev\Dossier\Model\Base\BaseModel;
use Magdev\Dossier\Model\Base\PhotoInterface;
/**
* Trait to add a photo to a model
*
* @author magdev
*/
trait PhotoTrait
{
/**
* Photo object
* @var \SplFileInfo
*/
protected $photo = null;
/**
* Size of the Photo
* @var int
*/
protected $photoSize = -1;
/**
* Get the photo
*
* @return \SplFileInfo
*/
public function getPhoto(): \SplFileInfo
{
return $this->photo;
}
/**
* Check if the model has a photo
*
* @return bool
*/
public function hasPhoto(): bool
{
return $this->photo instanceof \SplFileInfo;
}
/**
* Get the file contents as Data-URI
*
* @TODO Refactor to use UriHelperService
* @deprecated Use UriHelperService instead
* @return string
*/
public function getPhotoDataUri(): string
{
if ($this->hasPhoto()) {
$fi = new \finfo();
$mimetype = $fi->file($this->photo->getRealPath(), FILEINFO_MIME);
return 'data:'.$mimetype.'; base64,'.base64_encode(file_get_contents($this->photo->getRealPath()));
}
return '';
}
/**
* Get the size of the photo
*
* @return int
*/
public function getPhotoSize(): int
{
if ($this->photoSize == -1) {
if ($this->hasPhoto()) {
if ($size = getimagesize($this->photo->getRealPath())) {
$this->photoSize = $size[0];
}
}
}
return $this->photoSize;
}
/**
* Set the photo
*
* @param string $path
* @return \Magdev\Dossier\Model\Base\PhotoInterface
*/
public function setPhoto(string $path): PhotoInterface
{
$this->photo = new \SplFileInfo(PROJECT_ROOT.'/'.$path);
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Model\Traits;
trait VarnameConverterTrait
{
/**
* Convert snake_case to camelCase
*
* @param string $string
* @return string
*/
protected function convertCase(string $string): string
{
$res = str_replace('_', '', ucwords($string, '_'));
$res[0] = strtolower($res[0]);
return $res;
}
}

View File

@@ -0,0 +1,147 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Magdev\Dossier\Analyzer\Base\AnalyzableInterface;
use Magdev\Dossier\Analyzer\Base\AnalyzerInterface;
use Magdev\Dossier\Analyzer\Base\AnalyzerException;
/**
* Service to analyze models
*
* @author magdev
*/
class AnalyzerService
{
/**
* Configuration service
* @var \Magdev\Dossier\Service\AnalyzerService
*/
protected $config = null;
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Analyzer objects
* @var \ArrayObject
*/
protected $analyzers = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\ConfigService $config
* @param \Magdev\Dossier\Service\MonologService $logger
*/
public function __construct(ConfigService $config, MonologService $logger)
{
$this->config = $config;
$this->logger = $logger;
$this->analyzers = new \ArrayObject();
}
/**
* Get all analyzers
*
* @return \ArrayObject
*/
public function getAnalyzers(): \ArrayObject
{
return $this->analyzers;
}
/**
* Add an analyzer
*
* @param \Magdev\Dossier\Analyzer\Base\AnalyzerInterface $analyzer
* @return \Magdev\Dossier\Service\AnalyzerService
* @throws \Magdev\Dossier\Analyzer\Base\AnalyzerException
*/
public function addAnalyzer(AnalyzerInterface $analyzer): AnalyzerService
{
if ($this->hasAnalyzer($analyzer->getName())) {
throw new AnalyzerException('Analyzer with name '.$name.' already exists');
}
$this->analyzers->append($analyzer);
$this->logger->debug('Analyzer '.get_class($analyzer).' added with name '.$analyzer->getName());
return $this;
}
/**
* Check if an analyzer name is already taken
*
* @param string $name
* @return bool
*/
public function hasAnalyzer(string $name): bool
{
return $this->getAnalyzers() instanceof AnalyzableInterface;
}
/**
* Get an analyzer by name
*
* @param string $name
* @return \Magdev\Dossier\Analyzer\Base\AnalyzerInterface
*/
public function getAnalyzer(string $name): ?AnalyzerInterface
{
foreach ($this->analyzers as $a) {
if ($a->getName() == $name) {
return $a;
}
}
return null;
}
/**
* Set analyzers
*
* @param \ArrayObject $analyzers
* @return AnalyzerService
*/
public function setAnalyzers(\ArrayObject $analyzers): AnalyzerService
{
$this->analyzers = $analyzers;
return $this;
}
}

View File

@@ -0,0 +1,464 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\Finder\Finder;
use Magdev\Dossier\Config\ConfigLoader;
use Magdev\Dossier\Config\Config;
use Magdev\Dossier\Style\DossierStyle;
use Adbar\Dot;
/**
* Cnfiguration service
*
* @author magdev
*/
class ConfigService
{
const FORMAT_FLAT_ARRAY = 1;
const FORMAT_TABLE_ROWS = 2;
const FORMAT_PHP_ARRAY = 3;
const VALUE_SCALAR = 1;
const VALUE_INDEXED_ARRAY = 2;
/**
* The config object
* @var \Adbar\Dot
*/
protected $config = null;
/**
* The global config object
* @var \Adbar\Dot
*/
protected $global = null;
/**
* Constructor
*/
public function __construct()
{
if (file_exists(PROJECT_ROOT.'/.env')) {
$dotenv = new Dotenv();
$dotenv->load(PROJECT_ROOT.'/.env');
}
$this->loadConfig();
mb_internal_encoding(strtoupper($this->config->get('charset')));
}
/**
* Get the differences between current and global config
*
* @return array
*/
public function getDiff(array $current = null, array $global = null): array
{
if (is_null($current)) {
$current = $this->config->all();
}
if (is_null($global)) {
$global = $this->global->all();
}
$diff = array();
foreach ($current as $key => $value) {
if (is_array($value)) {
if (!isset($global[$key]) || !is_array($global[$key])) {
$diff[$key] = $value;
} else {
$newDiff = $this->getDiff($value, $global[$key]);
if (!empty($newDiff)) {
$diff[$key] = $newDiff;
}
}
} else if (!array_key_exists($key, $global) || $global[$key] !== $value) {
$diff[$key] = $value;
}
}
return $diff;
}
/**
* Get the Dot object
*
* @return \Adbar\Dot
*/
public function getConfig(): Dot
{
return $this->config;
}
/**
* Get the global Dot object
*
* @return \Adbar\Dot
*/
public function getGlobalConfig(): Dot
{
return $this->global;
}
/**
* Delegate method calls to Dot
*
* @param string $method
* @param array $args
* @throws \BadFunctionCallException
* @return mixed
*/
public function __call(string $method, array $args)
{
if (!method_exists($this->config, $method)) {
throw new \BadFunctionCallException('Unknown method: '.$method);
}
return call_user_func_array(array($this->config, $method), $args);
}
/**
* Get all configuration values
*
* @param int $format One of FORMAT_* constants
* @return array
*/
public function all(int $format = self::FORMAT_PHP_ARRAY): array
{
switch ($format) {
case self::FORMAT_FLAT_ARRAY:
$data = $this->allFlat();
break;
default:
case self::FORMAT_PHP_ARRAY:
$data = $this->config->all();
break;
}
ksort($data, SORT_NATURAL);
return $data;
}
/**
* Set a configuration value
*
* @param array|int|string $keys
* @param mixed $value
* @param bool $global
* @return \Magdev\Dossier\Service\ConfigService
*/
public function set($keys, $value, bool $global = false): ConfigService
{
$this->config->set($keys, $value);
if ($global) {
$this->global->set($keys, $value);
}
return $this;
}
/**
* Unset a configuration value
*
* @param unknown $keys
* @return \Magdev\Dossier\Service\ConfigService
*/
public function unset($keys): ConfigService
{
if ($this->config->has($keys)) {
$this->config->delete($keys);
}
if ($this->global->has($keys)) {
$this->global->delete($keys);
}
return $this;
}
/**
* Save the global configuration
*
* @return \Magdev\Dossier\Service\ConfigService
*/
public function saveGlobalConfig(): ConfigService
{
$yaml = '';
$config = $this->global->all();
if (!empty($config)) {
$yaml = Yaml::dump($config, 4, 3);
}
return $this->saveYaml(getenv('HOME').'/.dossier', $yaml);
}
/**
* Save the local configuration
*
* @return \Magdev\Dossier\Service\ConfigService
*/
public function saveProjectConfig(): ConfigService
{
$yaml = '';
$config = $this->getDiff();
if (!empty($config)) {
$yaml = Yaml::dump($config, 4, 3);
}
return $this->saveYaml(PROJECT_ROOT.'/.conf', $yaml);
}
/**
* Check if a value is stored in global configuration
*
* @param string $path
* @param mixed $value
* @return bool
*/
public function isGlobalConfig(string $path, $value): bool
{
if ($this->global->has($path) && $this->global->get($path) == $value) {
return true;
}
return false;
}
/**
* Save configuration
*
* @return \Magdev\Dossier\Service\ConfigService
*/
public function save(): ConfigService
{
return $this->saveGlobalConfig()
->saveProjectConfig()
->loadConfig();
}
/**
* Get all config values as flat array
*
* @return array
*/
public function allFlat(): array
{
$iterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->all()), \RecursiveIteratorIterator::SELF_FIRST);
$path = array();
$flatArray = array();
foreach ($iterator as $key => $value) {
$path[$iterator->getDepth()] = $key;
if (!is_array($value)) {
$flatArray[implode('.', array_slice($path, 0, $iterator->getDepth() + 1))] = $value;
}
}
return $flatArray;
}
/**
* Get all config values as table rows
*
* @param \Magdev\Dossier\Style\DossierStyle $io
* @param int $booleanWidth
* @return array
*/
public function allTable(DossierStyle $io, int $booleanWidth = null): array
{
$all = $this->allFlat();
$rows = array();
foreach ($all as $path => $value) {
$global = $this->isGlobalConfig($path, $value);
switch (gettype($value)) {
case 'string':
if ($value !== trim($value)) {
$value = "'$value'";
}
break;
case 'bool':
case 'boolean':
$value = $value ? 'true' : 'false';
break;
}
$rows[] = array($path, $value, $io->align($io->bool($global), $booleanWidth, DossierStyle::ALIGN_CENTER));
}
return $rows;
}
/**
* Find all themes in available directories
*
* @return array
*/
public function findThemes(bool $all = true): array
{
$folders = array(
PROJECT_ROOT.'/.conf/tpl',
getenv('HOME').'/.dossier/tpl',
DOSSIER_ROOT.'/app/tpl'
);
$finder = new Finder();
$finder->ignoreUnreadableDirs()
->directories()
->sortByName()
->depth('== 0');
foreach ($folders as $folder) {
if (file_exists($folder)) {
$finder->in($folder);
}
}
$themes = array();
foreach ($finder as $file) {
/* @var $file \SplFileInfo */
$path = str_replace(
array(DOSSIER_ROOT, PROJECT_ROOT, getenv('HOME')),
array('${DOSSIER}', '${PROJECT}', '${HOME}'),
$file->getPathInfo()->getRealpath()
);
$themes[$file->getFilename()] = $path;
}
ksort($themes);
if ($all) {
return $themes;
}
$themesSorted = array();
foreach ($themes as $name => $path) {
$index = array_search($path, $folders);
if (!array_key_exists($name, $themesSorted)) {
$themesSorted[$name] = $path;
} else {
$existingIndex = array_search($themesSorted[$name], $folders);
if ($index < $existingIndex) {
$themesSorted[$name] = $path;
}
}
}
return $themesSorted;
}
/**
* Save YAML to config file
*
* @param string $targetDir
* @param string $yaml
* @return \Magdev\Dossier\Service\ConfigService
*/
protected function saveYaml(string $targetDir, string $yaml): ConfigService
{
if (!is_dir($targetDir)) {
mkdir($targetDir, 0755, true);
}
file_put_contents($targetDir.'/dossier.yaml', $yaml);
return $this;
}
/**
* Load the configuration
*
* @return ConfigService
*/
protected function loadConfig(): ConfigService
{
clearstatcache();
$configDirectories = array(DOSSIER_ROOT.'/app/conf', getenv('HOME').'/.dossier', PROJECT_ROOT.'/.conf');
$env = getenv('APP_ENV') ?: 'prod';
$cachePath = DOSSIER_CACHE.'/src/'.strtolower($env).'DossierCachedConfig.php';
$fileLocator = new FileLocator($configDirectories);
$loader = new ConfigLoader($fileLocator);
$cache = new ConfigCache($cachePath, getenv('APP_DEBUG'));
if (!$cache->isFresh()) {
$resources = array();
$configFiles = $fileLocator->locate('dossier.yaml', null, false);
$envConfigFiles = $fileLocator->locate('dossier_'.strtolower($env).'.yaml', null, false);
if (!is_array($envConfigFiles)) {
$envConfigFiles = array($envConfigFiles);
}
$configFiles = array_merge($configFiles, $envConfigFiles);
foreach ($configFiles as $configFile) {
$loader->load($configFile);
$resources[] = new FileResource($configFile);
}
$code = '<?php'.PHP_EOL.'return '.(string) $loader.';'.PHP_EOL;
$cache->write($code, $resources);
}
$config = require $cachePath;
$this->config = new Dot($config['config']);
$this->global = new Dot($config['global']);
return $this;
}
/**
* Check if an array is an index flat array
*
* @param array $array
* @return bool
*/
protected function isIndexedFlatArray(array $array): bool
{
return array_key_exists(0, $array) !== false && is_scalar($array[0]) !== false;
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service\Exceptions;
use Symfony\Component\Console\Exception\RuntimeException;
class ServiceExcepton extends RuntimeException
{
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
/**
* Formatter Service
*
* @author magdev
*/
class FormatterService
{
const YEAR = 31536000;
const MONTH = 2635200;
const DAY = 86400;
/**
* Translator
* @var \Symfony\Component\Translation\Translator
*/
protected $translator = null;
/**
* Constructor
*
* @param \Magdev\Resume\Service\TranslatorService $translator
*/
public function __construct(TranslatorService $translator)
{
$this->translator = $translator->getTranslator();
}
/**
* Format seconds to years, months
*
* @TODO Implement translation
* @param int $seconds
* @param string $key
* @return string
*/
public function formatYearMonthDuration(int $seconds): string
{
$null = new \DateTime('@0');
$length = new \DateTime("@$seconds");
$years = floor($seconds / self::YEAR);
$months = floor($seconds - ($seconds * self::YEAR));
$msg = $this->translator->transChoice('date.format.year', $years);
if ($months) {
$msg .= ', '.$this->translator->transChoice('date.format.month', $months);
}
return $null->diff($length)->format($msg);
}
/**
* Wrapper for formatYearMonthDuration()
*
* @deprecated
* @param int $seconds
* @return string
*/
public function formatExperience(int $seconds): string
{
return $this->formatYearMonthDuration($seconds);
}
}

View File

@@ -0,0 +1,213 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Mni\FrontYAML;
use Mni\FrontYAML\Bridge\Parsedown\ParsedownParser;
use Symfony\Component\Yaml\Yaml;
use Magdev\Dossier\Model\Base\ModelInterface;
use Magdev\Dossier\Model\Base\ModelExportableInterface;
use Magdev\Dossier\Model\CurriculumVitae;
use Magdev\Dossier\Model\Person;
use Magdev\Dossier\Model\Intro;
use Magdev\Dossier\Model\Project;
use Magdev\Dossier\Service\Exceptions\ServiceExcepton;
use Magdev\Dossier\Util\Base\DataCollectorInterface;
use Magdev\Dossier\Util\DataCollector;
/**
* Markdown service
*
* @author magdev
*/
class MarkdownService
{
/**
* Parser object
* @var \Mni\FrontYAML\Parser
*/
protected $parser = null;
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Formatter service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $formatter = null;
/**
* Constructor
*/
public function __construct(MonologService $logger, FormatterService $formatter)
{
$this->parser = new FrontYAML\Parser(null, new ParsedownParser(new \ParsedownExtra()));
$this->logger = $logger;
$this->formatter = $formatter;
}
/**
* Get the Markdown parser object
*
* @return \Mni\FrontYAML\Parser
*/
public function getParser(): FrontYAML\Parser
{
return $this->parser;
}
/**
* Get a dataCollector with models of markdown files
*
* @param string $sort
* @return \Magdev\Dossier\Util\Base\DataCollectorInterface
*/
public function getFileSet(string $sort = CurriculumVitae::SORT_DESC): DataCollectorInterface
{
$person = new Person($this->getDocument(PROJECT_ROOT.'/person.md'));
$intro = new Intro($this->getDocument(PROJECT_ROOT.'/intro.md'));
$cv = new CurriculumVitae($this->formatter);
$files = new \FilesystemIterator(PROJECT_ROOT.'/cv');
foreach ($files as $file) {
/* @var $file \SplFileInfo */
$document = $this->getDocument($file->getPathname());
$cv->append(new CurriculumVitae\Entry($document));
}
$cv->setSortDirection($sort)->sort();
$projects = new \ArrayObject();
$files = new \FilesystemIterator(PROJECT_ROOT.'/projects');
foreach ($files as $file) {
/* @var $file \SplFileInfo */
$document = $this->getDocument($file->getPathname());
$projects->append(new Project($document));
}
return new DataCollector(array(
'intro' => $intro,
'person' => $person,
'cv' => $cv,
'projects' => $projects,
));
}
/**
* Parse a markdown file
*
* @param $srcfile string
* @return \Mni\FrontYAML\Document
*/
public function getDocument(string $srcfile, bool $parseMarkdown = true): FrontYAML\Document
{
$content = '';
if (file_exists($srcfile)) {
$content = file_get_contents($srcfile);
$this->logger->debug(mb_strlen($content).' bytes loaded from file '.$srcfile);
}
return $this->getParser()->parse($content, $parseMarkdown);
}
/**
* Save Markdown data
*
* @param string $path
* @param array $data
* @param string $text
* @param bool $overwrite
* @return \Magdev\Dossier\Service\MarkdownService
*/
public function save(string $path, array $data, string $text, bool $overwrite = true): MarkdownService
{
$content = '';
if (sizeof($data)) {
$content .= '---'.PHP_EOL;
$content .= Yaml::dump($data, 1, 2);
$content .= '---'.PHP_EOL;
}
if ($text) {
$content .= $text.PHP_EOL;
}
return $this->saveFile($path, $content, $overwrite);
}
/**
* Save the contents to a file and creates backup copy
*
* @param string $path
* @param string $content
* @param bool $overwrite
* @return \Magdev\Dossier\Service\MarkdownService
*/
protected function saveFile(string $path, string $content, bool $overwrite = true): MarkdownService
{
if (!is_dir(dirname($path))) {
mkdir(dirname($path), 0755, true);
}
if ($content) {
if ($overwrite) {
if (file_exists($path.'~')) {
@unlink($path.'~');
}
@copy($path, $path.'~');
if (file_put_contents($path, $content) === false) {
throw new ServiceExcepton('Error while writing '.$path);
}
$this->logger->debug(mb_strlen($content).' bytes written to file '.$path);
return $this;
}
if (!file_exists($path)) {
if (file_put_contents($path, $content) === false) {
throw new ServiceExcepton('Error while writing '.$path);
}
$this->logger->debug(mb_strlen($content).' bytes written to file '.$path);
}
}
return $this;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use zz\Html\HTMLMinify;
/**
* HTML Minifier Service
*
* @author magdev
*/
class MinifierService
{
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\MonologService $logger
*/
public function __construct(MonologService $logger)
{
$this->logger = $logger;
}
/**
* Minify HTML
*
* @param string $html
* @return string
*/
public function minify(string $html): string
{
if (!getenv('APP_DEBUG')) {
$html = HTMLMinify::minify($html, array(
'optimizationLevel' => HTMLMinify::OPTIMIZATION_ADVANCED,
'doctype' => HTMLMinify::DOCTYPE_HTML5,
));
}
return $html;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Processor\IntrospectionProcessor;
/**
* Log service
*
* @author magdev
*/
class MonologService
{
/**
* Configuration service
* @var \Magdev\Dossier\Service\ConfigService
*/
protected $config = null;
/**
* Monolog logger
* @var \Monolog\Logger
*/
protected $logger = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\ConfigService $config
*/
public function __construct(ConfigService $config)
{
$this->config = $config;
$logLevel = getenv('APP_DEBUG') ? Logger::DEBUG : $config->get('monolog.log_level', Logger::INFO);
$this->logger = new Logger('dossier');
$this->logger->pushHandler(new StreamHandler(PROJECT_ROOT.'/.dossier.log', $logLevel))
->pushProcessor(new IntrospectionProcessor(
$logLevel,
$config->get('monolog.skip_class_partials', array())
));
}
/**
* Get the Logger object
*
* @return \Monolog\Logger
*/
public function getLogger(): Logger
{
return $this->logger;
}
/**
* Delegate method calls to internal Logger
*
* @param string $method
* @param array $args
* @throws \BadFunctionCallException
* @return mixed
*/
public function __call(string $method, array $args)
{
if (!method_exists($this->logger, $method)) {
throw new \BadFunctionCallException('Unknown method: '.$method);
}
return call_user_func_array(array($this->logger, $method), $args);
}
}

View File

@@ -0,0 +1,178 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Magdev\Dossier\Style\DossierStyle;
/**
* Output helper
*
* @author magdev
* @deprecated
*/
class OutputHelperService
{
/**
* Output object
* @var \Symfony\Component\Console\Output\OutputInterface
*/
protected $output = null;
/**
* Translator service
* @var \Magdev\Dossier\Service\TranslatorService
*/
protected $translator = null;
/**
* Output style helper
* @var \Magdev\Dossier\Style\DossierStyle
*/
protected $ioStyle = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\TranslatorService $translator
*/
public function __construct(TranslatorService $translator)
{
$this->translator = $translator;
}
/**
* Set the output object
*
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return \Magdev\Dossier\Service\OutputHelperService
*/
public function setOutput(OutputInterface $output): OutputHelperService
{
$this->output = $output;
return $this->addOutputStyles();
}
/**
* Get the style helper for dossier
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return \Magdev\Dossier\Style\DossierStyle
*/
public function getIoStyle(InputInterface $input, OutputInterface $output): DossierStyle
{
$this->setOutput($output);
if (!$this->ioStyle) {
$this->ioStyle = new DossierStyle($input, $output);
}
return $this->ioStyle;
}
/**
* Write the application header
*
* @return \Magdev\Dossier\Service\OutputHelperService
*/
public function writeApplicationHeader(): OutputHelperService
{
$this->output->write('<fg=magenta;options=bold>'.base64_decode(DOSSIER_LOGO).'</>');
$this->output->writeln('<fg=magenta;options=bold> '.$this->translator->trans('app.header').'</>');
$this->output->writeln('');
return $this;
}
/**
* Write a configuraton value
*
* @param string $key
* @param unknown $value
* @return OutputHelperService
*/
public function writeConfigValue(string $key, $value): OutputHelperService
{
$this->output->writeln('<fg=cyan;options=bold> '.$this->padRight($key).'</>: '.'<fg=yellow;options=bold> '.$value.'</>');
return $this;
}
/**
* Format a boolean value for output
*
* @param bool $status
* @param int $width
* @return string
*/
public function formatBoolean(bool $status, int $width = null): string
{
$string = $status ? '<fg=green;options=bold>*</>' : '<fg=red;options=bold>-</>';
if (is_int($width)) {
$indent = floor(($width - 1) / 2);
$string = str_repeat(' ', $indent).$string;
}
return $string;
}
/**
* Add some output styles to the output object
*
* @return \Magdev\Dossier\Service\OutputHelperService
*/
protected function addOutputStyles(): OutputHelperService
{
$formatter = $this->output->getFormatter();
$formatter->setStyle('cmd', new OutputFormatterStyle('white', 'blue', array('bold')));
$formatter->setStyle('header', new OutputFormatterStyle('magenta', null, array('bold')));
return $this;
}
/**
* Pad a string to the right
*
* @param string $text
* @param int $width
* @return string
*/
protected function padRight(string $text, int $width = 50): string
{
return str_pad($text, $width, ' ', STR_PAD_RIGHT);
}
}

176
src/Service/PdfService.php Normal file
View File

@@ -0,0 +1,176 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use PDFShift\PDFShift;
use PDFShift\Exceptions\PDFShiftException;
use Magdev\Dossier\Service\Exceptions\ServiceExcepton;
use Symfony\Component\Console\Exception\RuntimeException;
use Magdev\Dossier\Util\DataCollector;
/**
* Service to create PFs with PDFShift API
* @author magdev
*
*/
class PdfService
{
/**
* Configuration service
* @var \Magdev\Dossier\Service\ConfigService
*/
protected $config = null;
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Template service
* @var \Magdev\Dossier\Service\TemplateService
*/
protected $tpl = null;
/**
* PDFShift API handler
* @var \PDFShift\PDFShift
*/
protected $pdf = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\ConfigService $config
* @param \Magdev\Dossier\Service\MonologService $logger
* @param \Magdev\Dossier\Service\TemplateService $tpl
*/
public function __construct(ConfigService $config, MonologService $logger, TemplateService $tpl)
{
$this->config = $config;
$this->logger = $logger;
$this->tpl = $tpl;
if (!$this->config->get('pdfshift.apikey')) {
throw new ServiceException('PDFShift API-Key not set!');
}
try {
PDFShift::setApiKey($this->config->get('pdfshift.apikey'));
$this->pdf = new PDFShift(array(
'sandbox' => getenv('APP_DEBUG'),
'use_print' => $this->config->get('pdfshift.stylesheet.use_print'),
'format' => $this->config->get('pdfshift.page.format'),
'margin' => $this->config->get('pdfshift.page.margin'),
));
if ($userAgent = $this->config->get('pdfshift.http.user_agent')) {
$this->pdf->addHTTPHeader('user-agent', $userAgent);
}
} catch (PDFShiftException $e) {
throw new ServiceExcepton('Error initializing PDFShift client', -1, $e);
}
}
/**
* Get the internal PDFSift handler
* @return \PDFShift\PDFShift
*/
public function getPdfShift(): PDFShift
{
return $this->pdf;
}
/**
* Create the PDF
*
* @param string $htmlFile
* @return string
*/
public function createPdf(string $htmlFile, bool $addHeader = false, bool $addFooter = false, bool $addSecurity = false): string
{
$html = file_get_contents($htmlFile);
$outputDir = dirname($htmlFile);
$outputFilename = basename($htmlFile, '.html').'.pdf';
if ($addSecurity) {
$securityConfig = $this->config->get('pdfshift.security');
if (isset($securityConfig['userPassword']) && isset($securityConfig['ownerPassword'])) {
$this->pdf->protect($securityConfig);
}
}
if ($addHeader) {
$this->pdf->setHeader($this->createHeader(new DataCollector()), $this->config->get('pdfshift.header.spacing'));
}
if ($addFooter) {
$this->pdf->setFooter($this->createHeader(new DataCollector()), $this->config->get('pdfshift.footer.spacing'));
}
$this->pdf->convert($html);
$this->pdf->save($outputDir.'/'.$outputFilename);
if (!file_exists($outputDir.'/'.$outputFilename)) {
throw new RuntimeException('Failed to create PDF file at '.$outputDir.'/'.$outputFilename);
}
return $outputDir.'/'.$outputFilename;
}
/**
* Create the header HTML
*
* @param \Magdev\Dossier\Util\DataCollector $vars
* @return string
*/
public function createHeader(DataCollector $data): string
{
return $this->tpl->renderDocument('parts/pdf/header.html.twig', $data);
}
/**
* Create the footer HTML
*
* @param \Magdev\Dossier\Util\DataCollector $vars
* @return string
*/
public function createFooter(DataCollector $data): string
{
return $this->tpl->renderDocument('parts/pdf/footer.html.twig', $data);
}
}

View File

@@ -0,0 +1,186 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Symfony\Component\Console\Exception\RuntimeException;
/**
* Phar helper
*
* @author magdev
*/
class PharHelperService
{
/**
* The Phar URL if inside of an archive
* @var string
*/
private $pharUrl = '';
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Constructor
*/
public function __construct(MonologService $logger)
{
$this->pharUrl = \Phar::running(true);
$this->logger = $logger;
}
/**
* Check if running inside a phar-archive
*
* @return bool
*/
public function isInPhar(): bool
{
return $this->pharUrl != '';
}
/**
* Get the full URL for a file inside a phar-archive
*
* @param string $append
* @return string
*/
public function getPharUrl(string $append = ''): string
{
if ($this->isInPhar()) {
if (!$append) {
return $this->pharUrl;
}
return $this->pharUrl.'/'.$append;
}
if (!$append) {
return DOSSIER_ROOT;
}
return DOSSIER_ROOT.'/'.$append;
}
/**
* Read a file from phar-archive
*
* @param string $file
*/
public function read(string $file)
{
return file_get_contents($this->getPharUrl($file));
}
/**
* Get a local temp-path for files in phar-archives
*
* @param string $file
* @return string
*/
public function createLocalTempFile(string $file): string
{
$tmpfile = tempnam(sys_get_temp_dir(), 'dossier-');
$this->copy($file, $tmpfile);
return $tmpfile;
}
/**
* Copy a file from source to local fs
*
* @param string $source Relative path to DOSSIER_ROOT
* @param string $target Path on local fs
* @return bool
*/
public function copy(string $source, string $target): bool
{
return copy($this->getPharUrl($source), $target);
}
/**
* Copy a directory from phar-archive to local filesystem
*
* @TODO Fix recursive directory iteration
* @param string $source
* @param string $target
* @return bool
*/
public function copyDir(string $source, string $target): bool
{
$rit = new \RecursiveDirectoryIterator(DOSSIER_ROOT.'/'.$source);
foreach (new \RecursiveIteratorIterator($rit) as $filename => $current) {
if ($current->getFilename() != '.' && $current->getFilename() != '..') {
/* @var $current \SplFileInfo */
$relpath = str_replace(DOSSIER_ROOT.'/'.$source.'/', '', $current->getRealPath());
$targetDir = dirname($target.'/'.$relpath);
if (!is_dir($targetDir)) {
mkdir($targetDir, 0755, true);
}
copy($current->getRealPath(), $target.'/'.$relpath);
}
}
return true;
}
/**
* Extract the entire Phar archive
*
* @return \Magdev\Dossier\Service\PharHelperService
*/
public function extractArchive(string $targetDir): PharHelperService
{
if ($this->isInPhar()) {
if (!is_dir($targetDir)) {
mkdir($targetDir, 0755, true);
}
try {
$phar = new \Phar($_SERVER['SCRIPT_FILENAME']);
$phar->extractTo($targetDir);
} catch (\Exception $e) {
throw new RuntimeException('Error while extracting archive', -1, $e);
}
}
return $this;
}
}

View File

@@ -0,0 +1,301 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Leafo\ScssPhp\Compiler;
/**
* LESS CSS processor service
*
* @author magdev
*/
class StylesheetProcessorService
{
const DELIM_MIXINS = 'MIXINS';
const DELIM_VARS = 'VARS';
const TYPE_LESS = 'less';
const TYPE_SCSS = 'scss';
/**
* LESS parser
* @var \Less_Parser
*/
protected $lessc = null;
/**
* SCSS compiler
* @var \Leafo\ScssPhp\Compiler
*/
protected $scssc = null;
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Template service
* @var \Magdev\Dossier\Service\TemplateService
*/
protected $tpl = null;
/**
* Constructor
*
* @param string $formatter
*/
public function __construct(MonologService $logger, TemplateService $tpl, $formatter = '\\Leafo\\ScssPhp\\Formatter\\Compressed')
{
$this->logger = $logger;
$this->tpl = $tpl;
$this->lessc = new \Less_Parser(array(
'compress' => !getenv('APP_DEBUG')
));
$this->scssc = new Compiler();
if (!getenv('APP_DEBUG')) {
$this->scssc->setFormatter($formatter);
}
}
/**
* Get the LESS parser object
*
* @return \Less_Parser
*/
public function getLessc(): \Less_Parser
{
return $this->lessc;
}
/**
* Get the SASS parser object
*
* @return \Leafo\ScssPhp\Compiler
*/
public function getScssc(): Compiler
{
return $this->scssc;
}
/**
* Parse a file and get the CSS
*
* @param string $file
* @return string
*/
public function parse(string $file): string
{
if (file_exists($file)) {
$this->logger->debug('Pre-Processing stylesheet file: '.$file);
$type = explode('.', basename($file))[1];
if ($type == self::TYPE_LESS) {
return $this->lessc->parse(file_get_contents($file))->getCss();
}
if ($type == self::TYPE_SCSS) {
return $this->scssc->compile(file_get_contents($file));
}
}
return '';
}
/**
* Parse theme stylesheets
*
* @return string
*/
public function parseThemeStyles(): string
{
$css = '';
$lessFile = $this->tpl->getThemeFile('less/global.less');
if (file_exists($lessFile)) {
$css .= $this->parse($lessFile);
}
$scssFile = $this->tpl->getThemeFile('scss/global.scss');
if (file_exists($scssFile)) {
$css .= $this->parse($scssFile);
}
return $css;
}
/**
* Parse user stylesheet
*
* @return string
*/
public function parseUserstyles(): string
{
$css = '';
if (file_exists(PROJECT_ROOT.'/'.self::TYPE_LESS.'/userstyles.'.self::TYPE_LESS)) {
$this->logger->debug('Pre-Processing user-stylesheet file: '.PROJECT_ROOT.'/'.self::TYPE_LESS.'/userstyles.'.self::TYPE_LESS);
$css .= $this->parse(PROJECT_ROOT.'/'.self::TYPE_LESS.'/userstyles.'.self::TYPE_LESS);
}
if (file_exists(PROJECT_ROOT.'/'.self::TYPE_SCSS.'/userstyles.'.self::TYPE_SCSS)) {
$this->logger->debug('Pre-Processing user-stylesheet file: '.PROJECT_ROOT.'/'.self::TYPE_SCSS.'/userstyles.'.self::TYPE_SCSS);
$css .= $this->parse(PROJECT_ROOT.'/'.self::TYPE_SCSS.'/userstyles.'.self::TYPE_SCSS);
}
return $css;
}
/**
* Export LESS variables
*
* @param string $file
* @param string $targetDir
* @param string $type
* @return \Magdev\Dossier\Service\StylesheetProcessorService
*/
public function exportVariables(string $file, string $targetDir = PROJECT_ROOT, string $type = self::TYPE_LESS): StylesheetProcessorService
{
$code = $this->cutFile($file, self::DELIM_VARS);
if ($code) {
$target = $targetDir.'/'.$type.'/variables.'.$type;
file_put_contents($target, $code);
}
return $this;
}
/**
* Export LESS Mixins
*
* @param string $file
* @param string $targetDir
* @param string $type
* @return \Magdev\Dossier\Service\StylesheetProcessorService
*/
public function exportMixins(string $file, string $targetDir = PROJECT_ROOT, string $type = self::TYPE_LESS): StylesheetProcessorService
{
$code = $this->cutFile($file, self::DELIM_MIXINS);
if ($code) {
$target = $targetDir.'/'.$type.'/mixins.'.$type;
file_put_contents($target, $code);
}
return $this;
}
/**
* Write basic userstyles.less
*
* @param string $targetDir
* @param string $type
* @return \Magdev\Dossier\Service\StylesheetProcessorService
*/
public function writeBasicUserstylesheet(string $targetDir = PROJECT_ROOT, string $type = self::TYPE_LESS): StylesheetProcessorService
{
if ($type == self::TYPE_LESS) {
$code = <<<EOT
/**
* LESS userstyles for magdev/dossier
*/
EOT;
$path = $targetDir.'/less/userstyles.less';
} else if ($type == self::TYPE_SCSS) {
$code = <<<EOT
/**
* SCSS userstyles for magdev/dossier
*/
EOT;
$path = $targetDir.'/scss/userstyles.scss';
}
$code .= <<<EOT
@import "mixins";
@import "variables";
// Gobal styles
@media print {
// Print styles
}
@media screen {
// Screen styles
}
EOT;
if (!is_dir(dirname($path))) {
mkdir(dirname($path), 0755, true);
}
file_put_contents($path, $code);
return $this;
}
/**
* Cut parts off a stylesheet file
*
* @param string $file
* @param string $delimiter (MIXINS or VARS)
* @return string
*/
protected function cutFile(string $file, string $delimiter): string
{
if ($delimiter == self::DELIM_MIXINS || $delimiter == self::DELIM_VARS) {
$start = '// '.$delimiter.':START';
$end = '// '.$delimiter.':END';
$fp = fopen($file, 'r');
$lines = array();
$started = false;
while ($line = fgets($fp, 1024) !== false) {
if ($line == $start) {
$started = true;
}
if ($started) {
if ($line == $end) {
fclose($fp);
return implode(PHP_EOL, $lines);
} else {
$lines[] = $line;
}
}
}
fclose($fp);
}
return '';
}
}

View File

@@ -0,0 +1,328 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Symfony\Component\Translation\Translator;
use Magdev\Dossier\Util\Base\DataCollectorInterface;
use Mni\FrontYAML\Parser;
/**
* Template service
*
* @author magdev
*/
class TemplateService
{
/**
* Twig object
* @var \Twig_Environment
*/
protected $twig = null;
/**
* Markdown service
* @var \Magdev\Dossier\Service\MarkdownService
*/
protected $markdown = null;
/**
* Translator service
* @var \Magdev\Dossier\Service\TranslatorService
*/
protected $translator = null;
/**
* HTML minifer service
* @var \Magdev\Dossier\Service\MinifierService
*/
protected $minifier = null;
/**
* Configuration service
* @var \Magdev\Dossier\Service\ConfigService
*/
protected $config = null;
/**
* Name of the current theme
* @var string
*/
protected $theme = '';
/**
* Name of the document
* @var string
*/
protected $docname = 'document';
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\MarkdownService $markdown
* @param \Magdev\Dossier\Service\TranslatorService $translator
* @param \Magdev\Dossier\Service\MinifierService $minifier
* @param \Magdev\Dossier\Service\ConfigService $config
* @param \Magdev\Dossier\Service\MonologService $logger
*/
public function __construct(MarkdownService $markdown, TranslatorService $translator, MinifierService $minifier, ConfigService $config, MonologService $logger)
{
$this->markdown = $markdown;
$this->translator = $translator;
$this->minifier = $minifier;
$this->config = $config;
$this->logger = $logger;
}
/**
* Get a file from a theme directory
*
* @param string $file
* @param string $theme
* @return string
*/
public function getThemeFile(string $file, string $theme = ''): string
{
$theme = !$theme ? $this->theme : $theme;
if (getenv('DOSSIER_THEME_DIR')) {
if (is_dir(getenv('DOSSIER_THEME_DIR').'/'.$theme) && file_exists(getenv('DOSSIER_THEME_DIR').'/'.$theme.'/'.$file)) {
return getenv('DOSSIER_THEME_DIR').'/'.$theme.'/'.$file;
}
}
if (is_dir(getenv('HOME').'/.dossier/tpl/'.$theme) && file_exists(getenv('HOME').'/.dossier/tpl/'.$theme.'/'.$file)) {
return getenv('HOME').'/.dossier/tpl/'.$theme.'/'.$file;
}
return DOSSIER_ROOT.'/app/tpl/'.$theme.'/'.$file;
}
/**
* Set the theme
*
* @param string $theme
* @return \Magdev\Dossier\Service\TemplateService
*/
public function setTheme(string $theme): TemplateService
{
$this->theme = $theme;
$loaders = array();
if (getenv('DOSSIER_THEME_DIR') && is_dir(getenv('DOSSIER_THEME_DIR').'/'.$theme)) {
$loaders[] = new \Twig_Loader_Filesystem(getenv('DOSSIER_THEME_DIR').'/'.$theme);
}
if (is_dir(getenv('HOME').'/.dossier/tpl/'.$theme)) {
$loaders[] = new \Twig_Loader_Filesystem(getenv('HOME').'/.dossier/tpl/'.$theme);
}
$loaders[] = new \Twig_Loader_Filesystem(DOSSIER_ROOT.'/app/tpl/'.$theme);
$this->twig = new \Twig_Environment(new \Twig_Loader_Chain($loaders), array(
'cache' => new \Twig_Cache_Filesystem(DOSSIER_CACHE, \Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION),
'debug' => getenv('APP_DEBUG'),
));
$this->addTwigExtensions($this->translator->getTranslator(), $this->config);
return $this;
}
/**
* Get the name of the current theme
*
* @return string
*/
public function getTheme(): string
{
return $this->theme;
}
/**
* Set the document name
*
* @param string $docname
* @return \Magdev\Dossier\Service\TemplateService
*/
public function setDocumentName(string $docname): TemplateService
{
$this->docname = $docname;
return $this;
}
/**
* Get the internal Twig object
*
* @return \Twig_Environment
*/
public function getTwig(): \Twig_Environment
{
return $this->twig;
}
/**
* Render the page
*
* @param string $template
* @param \Magdev\Dossier\Util\Base\DataCollectorInterface $data
* @param string $destDir
* @return string
*/
public function render(string $template, DataCollectorInterface $data, string $destDir): string
{
if (!is_dir($destDir)) {
mkdir($destDir, 0755, true);
}
$vars = $data->getData();
$name = isset($vars['name']) ? $vars['name'] : $this->docname;
$name .= isset($vars['theme']) ? '.'.$vars['theme'] : '';
$path = $destDir.'/'.$name.'.'.$this->translator->getTranslator()->getLocale().'.html';
$html = $this->twig->render($template, $vars);
$html = $this->minifier->minify($html);
if (!file_put_contents($path, $html)) {
throw new \RuntimeException('Error writing output file: '.$path);
}
return $path;
}
/**
* Render a template and return the resulted document
*
* @param string $template
* @param \Magdev\Dossier\Util\Base\DataCollectorInterface $data
* @return string
*/
public function renderDocument(string $template, DataCollectorInterface $data): string
{
$html = $this->twig->render($template, $data->getData());
$html = $this->minifier->minify($html);
return $html;
}
/**
* Add Twig extensions
*
* @param $translator \Symfony\Component\Translation\Translator
* @param $config \Magdev\Dossier\Service\ConfigService
* @return \Magdev\Dossier\Service\TemplateService
*/
private function addTwigExtensions(Translator $translator, ConfigService $config): TemplateService
{
$this->twig->addFilter(new \Twig_Filter('trans', function (string $id, array $parameters = array(), string $domain=null, string $locale=null) use ($translator) {
return $translator->trans($id, $parameters, $domain, $locale);
}));
$this->twig->addFilter(new \Twig_Filter('transChoice', function (string $id, int $number, array $parameters = array(), string $domain = null, string $locale = null) use ($translator) {
return $translator->transChoice($id, $number, $parameters, $domain, $locale);
}));
$this->twig->addFilter(new \Twig_Filter('md', function (string $string) {
return \ParsedownExtra::instance('twig')->parse($string);
}, array('is_safe' => array('html'))));
$this->twig->addFilter(new \Twig_Filter('inlinemd', function (string $string) {
return \ParsedownExtra::instance('twig')->line($string);
}, array('is_safe' => array('html'))));
$this->twig->addFilter(new \Twig_Filter('unixToDateTime', function (int $unixTime) {
return new \DateTime('@'.$unixTime);
}));
$this->twig->addFilter(new \Twig_Filter('filesize', function (int $filesize) {
if ($filesize > (1024*1024)) {
return round(($filesize/(1024*1024)), 2).' MiB';
}
if ($filesize > (1024)) {
return round(($filesize/1024), 2).' KiB';
}
return $filesize.' B';
}));
$this->twig->addFilter(new \Twig_Filter('split', function (string $string, string $split = ',') {
return explode($split, $string);
}));
$this->twig->addFilter(new \Twig_Filter('merge', function (array $strings, string $glue = ', ') {
return implode($glue, $strings);
}, array('is_safe' => array('html'))));
$this->twig->addFilter(new \Twig_Filter('splitmerge', function (string $string, string $split = ',', string $glue = '<br/>') {
$parts = explode($split, $string);
return $glue ? implode($glue, $parts) : $parts;
}, array('is_safe' => array('html'))));
$this->twig->addFilter(new \Twig_Filter('debug', function ($var) {
return getenv('APP_DEBUG') == true ? '<code>'.print_r($var, true).'</code>' : '';
}, array('is_safe' => array('html'))));
$this->twig->addFunction(new \Twig_Function('is_today', function (\DateTime $checkDate) {
return (new \DateTime())->diff($checkDate)->days == 0;
}));
$this->twig->addFunction(new \Twig_Function('is_disabled', function (bool $value) {
return $value == true;
}));
$this->twig->addFunction(new \Twig_Function('config', function (string $key) use ($config) {
if ($config->has($key)) {
$value = $config->get($key);
if (is_scalar($value)) {
return $value;
}
return json_encode($value, JSON_NUMERIC_CHECK);
}
return '';
}));
$this->twig->addFunction(new \Twig_Function('parseFilename', function(string $filename) {
$parts = explode('.', $filename);
return array(
'name' => ucfirst($parts[0]),
'theme' => ucfirst($parts[1]),
'locale' => strtoupper($parts[2]),
'type' => strtolower($parts[3]),
);
}));
return $this;
}
}

View File

@@ -0,0 +1,154 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\YamlFileLoader;
/**
* Translator Service
*
* @author magdev
*/
class TranslatorService
{
/**
* Translator Object
* @var \Symfony\Component\Translation\Translator
*/
protected $translator = null;
/**
* Fallback locales
* @var array
*/
protected $fallbackLocales = array();
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Constructor
*
* @param string $locale
*/
public function __construct(ConfigService $config, MonologService $logger)
{
$this->logger = $logger;
$this->fallbackLocales = $config->get('translator.fallback_locales');
$this->loadLocale($config->get('translator.locale'));
}
/**
* Set the locale
*
* @param string $locale
* @return \Magdev\Dossier\Service\TranslatorService
*/
public function setLocale(string $locale): TranslatorService
{
return $this->loadLocale($locale);
}
/**
* Get the internal Translator object
*
* @return \Symfony\Component\Translation\Translator
*/
public function getTranslator(): Translator
{
return $this->translator;
}
/**
* Translate a string
*
* @param string $id
* @param array $parameters
* @param string $domain
* @param string $locale
* @see \Symfony\Component\Translation\Translator::trans()
* @return string
*/
public function trans(string $id, array $parameters = array(), string $domain = null, string $locale = null): string
{
return $this->getTranslator()->trans($id, $parameters, $domain, $locale);
}
/**
* Translate plural strings
*
* @param string $id
* @param int $number
* @param array $parameters
* @param string $domain
* @param string $locale
* @see \Symfony\Component\Translation\Translator::transChoice()
* @return string
*/
public function transChoice(string $id, int $number, array $parameters = array(), string $domain = null, string $locale = null): string
{
return $this->getTranslator()->transChoice($id, $number, $parameters, $domain, $locale);
}
/**
* Load a locale
*
* @param string $locale
* @return \Magdev\Dossier\Service\TranslatorService
*/
protected function loadLocale(string $locale): TranslatorService
{
$this->translator = new Translator($locale);
$this->translator->setFallbackLocales($this->fallbackLocales);
$this->translator->addLoader('yaml', new YamlFileLoader());
$this->translator->addResource('yaml', DOSSIER_ROOT.'/app/locale/messages.'.$locale.'.yaml', $locale);
if (file_exists(getenv('HOME').'/.dossier/locale/messages.'.$locale.'.yaml')) {
$this->translator->addResource('yaml', getenv('HOME').'/.dossier/locale/messages.'.$locale.'.yaml', $locale);
}
if (file_exists(PROJECT_ROOT.'/.conf/locale/messages.'.$locale.'.yaml')) {
$this->translator->addResource('yaml', PROJECT_ROOT.'/.conf/locale/messages.'.$locale.'.yaml', $locale);
}
return $this;
}
}

View File

@@ -0,0 +1,174 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Service;
use Symfony\Component\Console\Exception\RuntimeException;
/**
* URI helper
*
* @author magdev
*/
class UriHelperService
{
/**
* Root directory to strip to generate relative URLs
* @var string
*/
protected $rootDir = '';
/**
* Phar Helper service
* @var \Magdev\Dossier\Service\PharHelperService
*/
protected $pharHelper = null;
/**
* Monolog service
* @var \Magdev\Dossier\Service\MonologService
*/
protected $logger = null;
/**
* Constructor
*
* @param \Magdev\Dossier\Service\PharHelperService $helper
*/
public function __construct(MonologService $logger, PharHelperService $helper)
{
$this->logger = $logger;
$this->pharHelper = $helper;
$this->rootDir = PROJECT_ROOT.'/';
}
/**
* Set the root directory
*
* @param string $dir
* @return \Magdev\Dossier\Service\UrlHelperService
*/
public function setRootDirectory(string $dir): UrlHelperService
{
$this->rootDir = $dir;
return $this;
}
/**
* Get DataURI from file
*
* @param string $file
* @param string $mimetype
* @return string
*/
public function getDataUriFromFile(string $file, $mimetype = null): string
{
$tmpfile = null;
if ($this->pharHelper->isInPhar()) {
$tmpfile = $this->pharHelper->createLocalTempFile($file);
$f = new \SplFileObject($tmpfile);
} else {
$f = new \SplFileObject($file);
}
if (!$mimetype) {
$fi = new \finfo();
$mimetype = $fi->file($f->getRealPath(), FILEINFO_MIME);
}
$data = file_get_contents($f->getRealPath());
if ($tmpfile && file_exists($tmpfile)) {
@unlink($tmpfile);
}
return $this->toDataUri($data, $mimetype);
}
/**
* Get a DataURI from data
*
* @param mixed $data
* @param string $mimetype
* @return string
*/
public function getDataUriFromData($data, $mimetype = 'text/plain'): string
{
return $this->toDataUri($data, $mimetype);
}
/**
* Open a file in the default editor
*
* @param string $file
* @throws \Symfony\Component\Console\Exception\RuntimeException
* @return \Magdev\Dossier\Service\UriHelperService
*/
public function openFileInEditor(string $file): UriHelperService
{
if (getenv('XSESSION_IS_UP') == 'yes') {
system('xdg-open '.$file);
} else if ($editor = getenv('EDITOR')) {
system($editor.' '.$file);
} else {
throw new RuntimeException('Cannot find a responsible editor');
}
return $this;
}
/**
* Get the relative path for project files
*
* @param string $realpath
* @return string
*/
public function getRelativePath(string $realpath): string
{
return str_replace(PROJECT_ROOT.'/', '', $realpath);
}
/**
* Format the DataURI
*
* @param mixed $data
* @param string $mimetype
* @return string
*/
protected function toDataUri($data, string $mimetype): string
{
return 'data:'.$mimetype.'; base64,'.base64_encode($data);
}
}

287
src/Style/DossierStyle.php Normal file
View File

@@ -0,0 +1,287 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Style;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Console\Helper\Helper;
/**
* Dossier console output styles
*
* @author magdev
*/
class DossierStyle extends SymfonyStyle
{
const ALIGN_LEFT = 1;
const ALIGN_RIGHT = 2;
const ALIGN_CENTER = 3;
private $appName = '';
private $appVersion = '';
public function setAppName(string $appName): DossierStyle
{
$this->appName = $appName;
return $this;
}
public function setAppVersion(string $appVersion): DossierStyle
{
$this->appVersion = $appVersion;
return $this;
}
/**
* Print as command-block
*
* @param strng|array $message
* @return \Magdev\Dossier\Style\DossierStyle
*/
public function cmd($message): DossierStyle
{
$this->block($message, null, 'cmd');
$this->writeln($this->getFormatter()->formatBlock($message, 'cmd', true));
return $this;
}
/**
* Print the application header
*
* @param string|array $message
* @return \Magdev\Dossier\Style\DossierStyle
*/
public function header($message): DossierStyle
{
switch (getenv('DOSSIER_HEADER_STYLE')) {
case 'none':
break;
case 'logo-only';
$this->text('<lightmagenta>'.base64_decode(DOSSIER_LOGO).'</>');
break;
case 'text-only':
if ($this->appName && $this->appVersion) {
$this->text('<lightmagenta>'.sprintf('%s %s', $this->appName, $this->appVersion).'</>');
}
$this->text('<lightmagenta>'.$message.'</>');
break;
default:
case 'full':
$this->text('<lightmagenta>'.base64_decode(DOSSIER_LOGO).'</>');
if ($this->appName && $this->appVersion) {
$this->text('<lightmagenta>'.sprintf('%s %s', $this->appName, $this->appVersion).'</>');
}
$this->text('<lightmagenta>'.$message.'</>');
break;
}
$this->newLine();
return $this;
}
public function info($message)
{
$this->text('<lightgreen> INFO: '.$message.'</>');
}
/**
* Print info messages
*
* @param string|array $message
*/
public function result($message)
{
$this->block($message, 'RESULT', 'fg=black;bg=cyan', ' ', true);
}
/**
* Print debug message
*
* @param string|array $message
*/
public function debug($message)
{
if (getenv('APP_DEBUG')) {
$this->text('<lightyellow> DEBUG: '.$message.'</>');
}
}
/**
* Get a message with a fixed length with specified alignment
*
* @param string $message
* @param int $length
* @param int $alignment
* @return string
*/
public function align(string $message, int $length = null, int $alignment = self::ALIGN_LEFT): string
{
$plainLength = Helper::strlenWithoutDecoration($this->getFormatter(), $message);
$length = $length + (strlen($message) - $plainLength);
switch ($alignment) {
case self::ALIGN_CENTER:
return str_pad($message, $length, ' ', STR_PAD_BOTH);
case self::ALIGN_RIGHT:
return str_pad($message, $length, ' ', STR_PAD_LEFT);
default:
case self::ALIGN_LEFT:
return str_pad($message, $length, ' ', STR_PAD_RIGHT);
}
}
/**
* Format percent
* @param int $value
* @param array $thresholds
* @return string
*/
public function percent(int $value, array $thresholds = array(), string $symbol = '%'): string
{
$prefix = function(int $percent) {
if ($percent < 10) { return ' '; }
if ($percent < 100) { return ' '; }
return '';
};
if (sizeof($thresholds)) {
uasort($thresholds, function($a, $b) {
if ($a['min'] == $b['min']) {
return 0;
}
return $a['min'] < $b['min'] ? -1 : 1;
});
if ($value >= end($thresholds)['max']) {
return $prefix($value).'<lightgreen>'.$value.$symbol.'</>';
} else if ($value <= reset($thresholds)['min']) {
return $prefix($value).'<lightred>'.$value.$symbol.'%</>';
}
foreach ($thresholds as $threshold) {
if ($value <= $threshold['max'] && $value >= $threshold['min']) {
if (isset($threshold['color'])) {
return $prefix($value).'<'.$threshold['color'].'>'.$value.$symbol.'</>';
} else {
return $prefix($value).$value.$symbol;
}
}
}
}
return $prefix($value).$value.$symbol;
}
/**
* Print a colored enviroment tag
*
* @return string
*/
public function environment(): string
{
$env = strtoupper(getenv('APP_ENV'));
switch ($env) {
case 'TEST':
return '<lightyellow>'.$env.'</>';
case 'DEV':
return '<lightred>'.$env.'</>';
default:
case 'PROD':
return '<lightgreen>'.$env.'</>';
}
}
/**
* Print the colored debug status
*
* @return string
*/
public function debugStatus(): string
{
return getenv('APP_DEBUG') ? '<lightred>YES</>' : '<lightgreen>NO</>';
}
/**
* Get the string for a boolean value in table-rows
*
* @param bool $value
* @param string $trueChar
* @param string $falseChar
* @return string
*/
public function bool(bool $value, string $trueChar = '*', string $falseChar = '-'): string
{
return $value == true ? $this->true($trueChar) : $this->false($falseChar);
}
/**
* Get the string to mark table-rows as true
*
* @param string $char
* @return string
*/
public function true(string $char = '*'): string
{
return '<lightgreen>'.$char.'</>';
}
/**
* Get the string to mark table rows as false
*
* @param string $char
* @return string
*/
public function false(string $char = '-'): string
{
return '<lightred>'.$char.'</>';
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Util\Base;
/**
* Interface for template data collectors
*
* @author magdev
*/
interface DataCollectorInterface
{
/**
* Add multiple data values at once
*
* @param array $data
* @return \Magdev\Dossier\Util\Base\DataCollectorInterface
*/
public function addData(array $data): DataCollectorInterface;
/**
* Set a single data value
*
* @param string $varname
* @param unknown $value
* @return \Magdev\Dossier\Util\Base\DataCollectorInterface
*/
public function setData(string $varname, $value): DataCollectorInterface;
/**
* Get all data values as array
*
* @return array
*/
public function getData(): array;
/**
* Get all data values as array
*
* @return bool
*/
public function hasData(): bool;
/**
* Merge another data collector
*
* @param \Magdev\Dossier\Util\Base\DataCollectorInterface $data
* @return \Magdev\Dossier\Util\Base\DataCollectorInterface
*/
public function merge(DataCollectorInterface $data): DataCollectorInterface;
}

114
src/Util/DataCollector.php Normal file
View File

@@ -0,0 +1,114 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 magdev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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.
*
* @author magdev
* @copyright 2018 Marco Grätsch
* @package magdev/dossier
* @license http://opensource.org/licenses/MIT MIT License
*/
namespace Magdev\Dossier\Util;
use Magdev\Dossier\Util\Base\DataCollectorInterface;
/**
* Simple data collector
*
* @author magdev
*/
class DataCollector implements DataCollectorInterface
{
/**
* Store the data
* @var array
*/
protected $data = array();
/**
* Constructor
*
* @param array $data
*/
public function __construct(array $data = null)
{
if (is_array($data)) {
$this->addData($data);
}
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Util\Base\DataCollectorInterface::addData()
*/
public function addData(array $data): DataCollectorInterface
{
$this->data = array_merge($this->data, $data);
return $this;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Util\Base\DataCollectorInterface::setData()
*/
public function setData(string $key, $value): DataCollectorInterface
{
$this->data[$key] = $value;
return $this;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Util\Base\DataCollectorInterface::getData()
*/
public function getData(): array
{
return $this->data;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Util\Base\DataCollectorInterface::hasData()
*/
public function hasData(): bool
{
return sizeof($this->data) > o ? true : false;
}
/**
* {@inheritDoc}
* @see \Magdev\Dossier\Util\Base\DataCollectorInterface::merge()
*/
public function merge(DataCollectorInterface $data): DataCollectorInterface
{
$this->addData($data->getData());
return $this;
}
}