diff --git a/README.md b/README.md index a3a007e..8527a27 100644 --- a/README.md +++ b/README.md @@ -47,20 +47,8 @@ Basta duplicar o arquivo `config/config.php.sample` para `config/config.php` e m O projeto usa o Doctrine, então é preciso criar a base de dados (de acordo com as configurações do config.php) e executar: -`./vendor/bin/doctrine orm:schema-tool:create` - -**Importante**: A extensão APC é um pré-requisito para o projeto. Caso encontre erros ao rodar o comando acima, instale a extensão. - -**Importante**: Nas versões mais atuais do PHP (5.5+) a extensão APC não é mais compatível. Uma solução é instalar o php5-apcu. - -### Acesso ao sistema - -Antes de acessar o sistema é necessário criar o primeiro usuário, rodando **através da linha de comando** o seguinte script: - -`cd /docs/` e `php firstUser.php "Nome da Empresa" "Nome da pessoa responsável" "(xx) xxxx-xxxx" "e-mail da pessoa responsável" "usuario" "senha" "e-mail do usuário"`. - -**Dica**: substituir as informações entre as aspas por suas próprias informações. +`./bin/orcamentos orcamentos:initialize` ### Exemplo de uso -[https://www.youtube.com/watch?v=r5OAGWhk2iQ](https://www.youtube.com/watch?v=r5OAGWhk2iQ) \ No newline at end of file +[https://www.youtube.com/watch?v=r5OAGWhk2iQ](https://www.youtube.com/watch?v=r5OAGWhk2iQ) diff --git a/app.php b/app.php index 8f0d3e4..ba7f224 100644 --- a/app.php +++ b/app.php @@ -1,11 +1,11 @@ register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__.'/views', )); - + $app->register(new Silex\Provider\SwiftmailerServiceProvider()); @@ -43,7 +43,7 @@ } }; -$app->error(function (\Exception $e, $code) use($app) { +$app->error(function (\Exception $e, $code) use ($app) { switch ($code) { case 404: $message = $app['twig']->render('error404.twig', array('code'=>$code, 'message' => $e->getMessage())); @@ -54,7 +54,7 @@ } return new Response($message, $code); }); - + $app['sortCreated'] = $app->protect(function ($a, $b) { if ($a->getCreated() == $b->getCreated()) { return 0; @@ -169,7 +169,7 @@ $share->get('/sendEmails/{limit}', 'Orcamentos\Controller\ShareController::sendEmails')->value('limit', 10) ->before($redirectUnlogged) ->before($redirectCommonUser); - + $share->post('/comment', 'Orcamentos\Controller\ShareController::comment'); $share->get('/removeComment/{shareNoteId}', 'Orcamentos\Controller\ShareController::removeComment'); $share->get('/{hash}', 'Orcamentos\Controller\ShareController::detail'); @@ -190,7 +190,7 @@ )); $app->register(new DoctrineOrmServiceProvider(), array( - 'orm.proxies_dir' => '/tmp/' . getenv('APPLICATION_ENV'), + 'orm.proxies_dir' => sys_get_temp_dir() . '/' . md5(__DIR__ . getenv('APPLICATION_ENV')), 'orm.em.options' => array( 'mappings' => array( array( @@ -202,5 +202,6 @@ ) ), 'orm.proxies_namespace' => 'EntityProxy', - 'orm.auto_generate_proxies' => true -)); \ No newline at end of file + 'orm.auto_generate_proxies' => true, + 'orm.default_cache' => $config['db.options']['cache'] +)); diff --git a/bin/doctrine b/bin/doctrine deleted file mode 100755 index 92f323f..0000000 --- a/bin/doctrine +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env php - new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()), - 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em) -); - -$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface', Doctrine\Common\Version::VERSION); -$cli->setCatchExceptions(true); -$helperSet = $cli->getHelperSet(); -foreach ($helpers as $name => $helper) { - $helperSet->set($helper, $name); -} -$cli->addCommands(array( - // DBAL Commands - new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(), - new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(), - - // ORM Commands - new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(), - new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(), - new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(), - new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(), - new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(), - new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(), - new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(), - new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(), - new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(), - new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(), - new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(), - new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(), - new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(), - new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(), - -)); -$cli->run(); diff --git a/bin/orcamentos b/bin/orcamentos new file mode 100755 index 0000000..b999f3e --- /dev/null +++ b/bin/orcamentos @@ -0,0 +1,17 @@ +#!/usr/bin/env php +setHelperSet(include 'cli-config.php'); +$application->add(new Orcamentos\Console\InitializeCommand); +$application->add(new Orcamentos\Console\ResetPasswordCommand); + +ConsoleRunner::addCommands($application); + +$application->run(); diff --git a/bootstrap.php b/bootstrap.php deleted file mode 100644 index ba96e1f..0000000 --- a/bootstrap.php +++ /dev/null @@ -1,35 +0,0 @@ -add('Orcamentos', __DIR__.'/src'); - -//doctrine -$config = new Configuration(); -//$cache = new Cache(); -$cache = new \Doctrine\Common\Cache\ApcCache(); -$config->setQueryCacheImpl($cache); -$config->setProxyDir('/tmp'); -$config->setProxyNamespace('EntityProxy'); -$config->setAutoGenerateProxyClasses(true); - -//mapping (example uses annotations, could be any of XML/YAML or plain PHP) -AnnotationRegistry::registerFile(__DIR__. DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'doctrine' . DIRECTORY_SEPARATOR . 'orm' . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Doctrine' . DIRECTORY_SEPARATOR . 'ORM' . DIRECTORY_SEPARATOR . 'Mapping' . DIRECTORY_SEPARATOR . 'Driver' . DIRECTORY_SEPARATOR . 'DoctrineAnnotations.php'); - -$driver = new Doctrine\ORM\Mapping\Driver\AnnotationDriver( - new Doctrine\Common\Annotations\AnnotationReader(), - array(__DIR__.'/src/Orcamentos/Model') -); -$config->setMetadataDriverImpl($driver); -$config->setMetadataCacheImpl($cache); \ No newline at end of file diff --git a/cli-config.php b/cli-config.php index d861bc9..9ee19e4 100644 --- a/cli-config.php +++ b/cli-config.php @@ -8,6 +8,15 @@ use Doctrine\ORM\Tools\Setup; use Doctrine\ORM\EntityManager; use Doctrine\Common\Annotations\AnnotationRegistry; +use Symfony\Component\Console\Helper\DebugFormatterHelper; +use Symfony\Component\Console\Helper\ProcessHelper; +use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Helper\DialogHelper; +use Symfony\Component\Console\Helper\ProgressHelper; +use Symfony\Component\Console\Helper\TableHelper; + AnnotationRegistry::registerFile(__DIR__.'/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php'); @@ -15,7 +24,7 @@ $config = new \Doctrine\ORM\Configuration(); // Proxies (3) -$config->setProxyDir(__DIR__ . '/tmp'); +$config->setProxyDir(sys_get_temp_dir() . '/' . md5(__DIR__)); $config->setProxyNamespace('Proxies'); $config->setAutoGenerateProxyClasses(true); @@ -36,5 +45,12 @@ return $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array( 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()), - 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em) + 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em), + new FormatterHelper(), + new DialogHelper(), + new ProgressHelper(), + new TableHelper(), + new DebugFormatterHelper(), + new ProcessHelper(), + new QuestionHelper() )); diff --git a/composer.json b/composer.json index 5bf53e3..2b275dd 100644 --- a/composer.json +++ b/composer.json @@ -2,6 +2,7 @@ "name": "eminetto/silex-sample", "description": "Silex sample", "require": { + "php": ">=5.3.3", "silex/silex": "1.0.*", "symfony/http-kernel": "*", "symfony/browser-kit": "*", @@ -13,11 +14,18 @@ "symfony/twig-bridge": "2.1.*", "swiftmailer/swiftmailer": ">=4.1.2,<4.2-dev", "dflydev/doctrine-orm-service-provider": "1.0.*@dev", - "mockery/mockery": "dev-master@dev", - "zendframework/zend-crypt": "*", + "zendframework/zend-crypt": "*", + "pagerfanta/pagerfanta": "1.0.*@dev" + }, + "require-dev": { + "sebastian/phpcpd": "*", "phpunit/phpunit": "*", - "pagerfanta/pagerfanta": "1.0.*@dev", - "sebastian/phpcpd": "*" + "mockery/mockery": "dev-master@dev" }, - "minimum-stability": "dev" -} \ No newline at end of file + "minimum-stability": "dev", + "autoload": { + "psr-0": { + "Orcamentos\\": "src/" + } + } +} diff --git a/config/config.php.sample b/config/config.php.sample index 843a227..e35c07a 100644 --- a/config/config.php.sample +++ b/config/config.php.sample @@ -14,7 +14,8 @@ return array( 'port' => '3306', 'user' => 'orcamentos', 'password' => 'orcamentos', - 'dbname' => 'orcamentos' + 'dbname' => 'orcamentos', + 'cache' => 'array' // array, apc, xcache... ), 'bitly' => array( //usado para compartilhar os orçamentos. o /share é obrigatório 'url' => 'http://server/share/', diff --git a/docs/firstPlan.php b/docs/firstPlan.php deleted file mode 100644 index dbea397..0000000 --- a/docs/firstPlan.php +++ /dev/null @@ -1,33 +0,0 @@ -getRepository('Orcamentos\Model\Plan')->findAll(); - -if ( count($alreadyDone) == 0){ - $planName = $argv[1]; - $planPrice = $argv[2]; - $planQuoteLimit = $argv[3]; - - $plan = new Plan(); - $plan->setName($planName); - $plan->setPrice($planPrice); - $plan->setQuoteLimit($planQuoteLimit); - - $em->persist($plan); - - $companies = $em->getRepository('Orcamentos\Model\Company')->findAll(); - - foreach ($companies as $company) { - $company->setPlan($plan); - $em->persist($company); - } - - $em->flush(); -} - -return true; \ No newline at end of file diff --git a/docs/firstTypes.php b/docs/firstTypes.php deleted file mode 100644 index be6bcf8..0000000 --- a/docs/firstTypes.php +++ /dev/null @@ -1,29 +0,0 @@ -getRepository('Orcamentos\Model\Type')->findAll(); - -if (count($types)==0){ - $equipmentType = new EquipmentType(); - $equipmentType->setName('Computador'); - $em->persist($equipmentType); - - $serviceType = new ServiceType(); - $serviceType->setName('Conta'); - $em->persist($serviceType); - - $humanType = new HumanType(); - $humanType->setName('Funcionário'); - $em->persist($humanType); - - try { - $em->flush(); - } catch (Exception $e) { - echo $e->getMessage(); - } -} diff --git a/docs/firstUser.php b/docs/firstUser.php deleted file mode 100644 index 0cb6cfe..0000000 --- a/docs/firstUser.php +++ /dev/null @@ -1,45 +0,0 @@ - $companyName, - 'responsable' => $companyResponsable, - 'telephone' => $companyTelephone, - 'email' => $companyEmail -); - -$companyData = json_encode($companyData); -$companyService = new CompanyService(); -$companyService->setEm($em); -$company = $companyService->save($companyData, null, $em); - - -$userData = array( - 'name' => $userName, - 'password' => $userPassword, - 'email' => $userEmail, - 'companyId' => $company->getId(), - 'admin' => true -); - -$userData = json_encode($userData); -$userService = new UserService(); -$userService->setEm($em); -$user = $userService->save($userData, $em); - -return true; \ No newline at end of file diff --git a/src/Orcamentos/Console/InitializeCommand.php b/src/Orcamentos/Console/InitializeCommand.php new file mode 100644 index 0000000..d5b2647 --- /dev/null +++ b/src/Orcamentos/Console/InitializeCommand.php @@ -0,0 +1,150 @@ +setName('orcamentos:initialize') + ->setDescription('Initialize the database and insert the initial data'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + + + try { + $command = $this->getApplication()->find('orm:schema-tool:create'); + $returnCode = $command->run($input, $output); + } catch (\Exception $e) { + $output->writeln("Your database alread have the schema!"); + } + + + $this->input = $input; + $this->output = $output; + + $em = $this->getEm(); + + $userRepo = $this->getEm()->getRepository('Orcamentos\Model\User'); + + $users = $userRepo->findAll(); + + if (count($users)) { + $output->writeln("Your database alread have users!"); + return; + } + + $companyData = $userData = array(); + + $output->writeln("Company setup:"); + $companyData['name'] = $this->askFor('What is your company name:', 'Demo'); + $companyData['telephone'] = $this->askFor('Company phone number:'); + $companyData['email'] = $this->askFor('Company e-mail address:'); + $companyData['responsable'] = null; + $company = $this->saveCompany($companyData); + + $output->writeln("\nUser setup"); + $userData['name'] = $this->askFor('Full name of the user:'); + $userData['email'] = $this->askFor('User\'s e-mail address:'); + $userData['password'] = $this->askForPassword(); + $userData['admin'] = true; + $userData['companyId'] = $company->getId(); + + $user = $this->saveUser($userData); + + $output->writeln("\nPlan setup:"); + $planName = $this->askFor('Enter a name for the default plan:'); + $planPrice = 1 * $this->askFor('Enter the price for this plan (49.90):'); + + $plan = new Plan(); + $plan->setName($planName); + $plan->setPrice($planPrice); + $plan->setQuoteLimit(null); + + $em->persist($plan); + + $company->setPlan($plan); + + $output->writeln("Creating default types: "); + + $equipmentType = new EquipmentType(); + $equipmentType->setName('Computador'); + $em->persist($equipmentType); + $output->writeln("- Equipment"); + + $serviceType = new ServiceType(); + $serviceType->setName('Conta'); + $em->persist($serviceType); + $output->writeln("- Service"); + + $humanType = new HumanType(); + $humanType->setName('Funcionário'); + $em->persist($humanType); + $output->writeln("- Human"); + + $em->flush(); + + $output->writeln("Initial setup complete!"); + } + + private function askForPassword() + { + $helper = $this->getHelper('question'); + $question = new Question('What is the user password: '); + $question->setHidden(true); + $question->setHiddenFallback(false); + return $helper->ask($this->input, $this->output, $question); + } + + private function askFor($question) + { + $helper = $this->getHelper('question'); + $question = new Question("$question "); + return $helper->ask($this->input, $this->output, $question); + } + + private function saveCompany(array $data) + { + $companyData = json_encode($data); + $companyService = new CompanyService(); + $companyService->setEm($this->getEm()); + return $companyService->save($companyData, null); + } + + private function saveUser(array $data) + { + $userData = json_encode($data); + $userService = new UserService(); + $userService->setEm($this->getEm()); + return $userService->save($userData); + } + + private function getEm() + { + return $this->getHelper('em')->getEntityManager(); + } +} diff --git a/src/Orcamentos/Console/ResetPasswordCommand.php b/src/Orcamentos/Console/ResetPasswordCommand.php new file mode 100644 index 0000000..e574b0c --- /dev/null +++ b/src/Orcamentos/Console/ResetPasswordCommand.php @@ -0,0 +1,94 @@ +setName('orcamentos:resetpwd') + ->setDescription('Reset user password'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + + $this->input = $input; + $this->output = $output; + + $userRepo = $this->getEm()->getRepository('Orcamentos\Model\User'); + + $users = $userRepo->findAll(); + + if (0 === count($users)) { + $output->writeln("Your database don't have users!"); + $output->writeln("Try: orcamentos:initialize"); + return; + } + + $options = array(); + foreach ($users as $user) { + $options[$user->getId()] = $user->getName() . "<" . $user->getEmail() . ">"; + } + + $helper = $this->getHelper('question'); + $question = new ChoiceQuestion( + 'Please select the user', + $options + ); + $user = $helper->ask($input, $output, $question); + + $userId = array_search($user, $options); + + $pwd = ''; + + while (strlen($pwd) < 6) { + $pwd = $this->askForPassword(); + if (strlen($pwd) < 6) { + $output->writeln("The password must have at least 6 characters"); + continue; + } + } + + $pwd = (new Bcrypt)->create($pwd); + + $user = $userRepo->find($userId); + $user->setPassword($pwd); + + $this->getEm()->flush(); + + $output->writeln("The password has been successfully changed"); + + } + + private function askForPassword() + { + $helper = $this->getHelper('question'); + $question = new Question('What is the new user\'s password: '); + $question->setHidden(true); + $question->setHiddenFallback(false); + return $helper->ask($this->input, $this->output, $question); + } + + private function getEm() + { + return $this->getHelper('em')->getEntityManager(); + } +} diff --git a/src/Orcamentos/Service/Company.php b/src/Orcamentos/Service/Company.php index d4dd957..cf391e6 100644 --- a/src/Orcamentos/Service/Company.php +++ b/src/Orcamentos/Service/Company.php @@ -5,7 +5,7 @@ use Orcamentos\Model\Company as CompanyModel; use Intervention\Image\Image; use Exception; - + /** * Company Entity * @@ -24,7 +24,7 @@ public function save($data, $logotype) { $data = json_decode($data); - if (!isset($data->name) || !isset($data->responsable) || !isset($data->telephone)) { + if (!isset($data->name) || !isset($data->telephone)) { throw new Exception("Invalid Parameters", 1); } @@ -32,10 +32,14 @@ public function save($data, $logotype) $taxes = 6; - if(isset($data->taxes)){ + if (isset($data->taxes)) { $taxes = $data->taxes; } + if (!isset($data->responsable)) { + $data->responsable = null; + } + $company->setName($data->name); $company->setResponsable($data->responsable); $company->setTaxes($taxes); @@ -47,10 +51,10 @@ public function save($data, $logotype) if (isset($data->site)) { $company->setSite($data->site); } - + if (isset($data->telephone)) { $company->setTelephone($data->telephone); - } + } if (isset($data->email)) { $company->setEmail($data->email); @@ -60,7 +64,7 @@ public function save($data, $logotype) $originalName = $logotype->getClientOriginalName(); $components = explode('.', $originalName); $fileName = md5(time()) . '.' . end($components); - + $file = Image::make($logotype->getPathName())->grab(80); $file->save("public/img/logotypes/" . $fileName ); $company->setLogotype($fileName);