partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit 12bb2c5ebadacce00f706e1a1982d34c8c875591
parent 82a5a5852674eca7f2a36ceffc7577efd0c2f80d
Author: Felicitus <felicitus@felicitus.org>
Date:   Thu, 21 May 2015 21:10:22 +0200

Added initial ExtJS model generator

Diffstat:
Mapp/AppKernel.php | 1+
Mapp/config/routing.yml | 5+++++
Asrc/PartKeepr/DoctrineReflectionBundle/CacheWarmer/ModelCacheWarmer.php | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/DoctrineReflectionBundle/DependencyInjection/Configuration.php | 29+++++++++++++++++++++++++++++
Asrc/PartKeepr/DoctrineReflectionBundle/DependencyInjection/PartKeeprDoctrineReflectionExtension.php | 28++++++++++++++++++++++++++++
Asrc/PartKeepr/DoctrineReflectionBundle/PartKeeprDoctrineReflectionBundle.php | 9+++++++++
Asrc/PartKeepr/DoctrineReflectionBundle/Resources/config/services.xml | 19+++++++++++++++++++
Asrc/PartKeepr/DoctrineReflectionBundle/Resources/views/model.js.twig | 13+++++++++++++
Asrc/PartKeepr/DoctrineReflectionBundle/Services/ReflectionService.php | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/FrontendBundle/Controller/IndexController.php | 35+++++++++++++++++++++++++++++++++--
Msrc/PartKeepr/FrontendBundle/Resources/views/index.html.twig | 57++++-----------------------------------------------------
Msrc/PartKeepr/SiPrefixBundle/Entity/SiPrefix.php | 2+-
12 files changed, 292 insertions(+), 56 deletions(-)

diff --git a/app/AppKernel.php b/app/AppKernel.php @@ -57,6 +57,7 @@ class AppKernel extends Kernel new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new Nelmio\ApiDocBundle\NelmioApiDocBundle(), new \Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(), + new PartKeepr\DoctrineReflectionBundle\PartKeeprDoctrineReflectionBundle(), ); // Developer bundles diff --git a/app/config/routing.yml b/app/config/routing.yml @@ -1,3 +1,8 @@ +part_keepr_doctrine_reflection: + resource: "@PartKeeprDoctrineReflectionBundle/Controller/" + type: annotation + prefix: / + part_keepr_auth: resource: "@PartKeeprAuthBundle/Controller/" type: annotation diff --git a/src/PartKeepr/DoctrineReflectionBundle/CacheWarmer/ModelCacheWarmer.php b/src/PartKeepr/DoctrineReflectionBundle/CacheWarmer/ModelCacheWarmer.php @@ -0,0 +1,50 @@ +<?php +namespace PartKeepr\DoctrineReflectionBundle\CacheWarmer; + + +use Doctrine\Common\Persistence\ManagerRegistry; +use PartKeepr\DoctrineReflectionBundle\Services\ReflectionService; +use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmer; + +class ModelCacheWarmer extends CacheWarmer{ + + private $registry; + private $reflectionService; + + /** + * Constructor. + * + * @param ManagerRegistry $registry A ManagerRegistry instance + */ + public function __construct(ManagerRegistry $registry, ReflectionService $reflectionService) + { + $this->reflectionService = $reflectionService; + $this->registry = $registry; + } + + /** + * This cache warmer is not optional, without proxies fatal error occurs! + * + * @return false + */ + public function isOptional() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function warmUp($cacheDir) + { + $cacheDir .= "/doctrinereflection"; + + $entities = $this->reflectionService->getEntities(); + + foreach ($entities as $entity) { + $model = $this->reflectionService->getEntity($entity); + @mkdir($cacheDir, 0777, true); + $this->writeCacheFile($cacheDir."/".$entity.'.js', $model); + } + } +}+ \ No newline at end of file diff --git a/src/PartKeepr/DoctrineReflectionBundle/DependencyInjection/Configuration.php b/src/PartKeepr/DoctrineReflectionBundle/DependencyInjection/Configuration.php @@ -0,0 +1,29 @@ +<?php + +namespace PartKeepr\DoctrineReflectionBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * This is the class that validates and merges configuration from your app/config files + * + * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} + */ +class Configuration implements ConfigurationInterface +{ + /** + * {@inheritdoc} + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $treeBuilder->root('doctrine_reflection_service'); + + // Here you should define the parameters that are allowed to + // configure your bundle. See the documentation linked above for + // more information on that topic. + + return $treeBuilder; + } +} diff --git a/src/PartKeepr/DoctrineReflectionBundle/DependencyInjection/PartKeeprDoctrineReflectionExtension.php b/src/PartKeepr/DoctrineReflectionBundle/DependencyInjection/PartKeeprDoctrineReflectionExtension.php @@ -0,0 +1,28 @@ +<?php + +namespace PartKeepr\DoctrineReflectionBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader; + +/** + * This is the class that loads and manages your bundle configuration + * + * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} + */ +class PartKeeprDoctrineReflectionExtension extends Extension +{ + /** + * {@inheritdoc} + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = new Configuration(); + $this->processConfiguration($configuration, $configs); + + $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + } +} diff --git a/src/PartKeepr/DoctrineReflectionBundle/PartKeeprDoctrineReflectionBundle.php b/src/PartKeepr/DoctrineReflectionBundle/PartKeeprDoctrineReflectionBundle.php @@ -0,0 +1,9 @@ +<?php + +namespace PartKeepr\DoctrineReflectionBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class PartKeeprDoctrineReflectionBundle extends Bundle +{ +} diff --git a/src/PartKeepr/DoctrineReflectionBundle/Resources/config/services.xml b/src/PartKeepr/DoctrineReflectionBundle/Resources/config/services.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" ?> + +<container xmlns="http://symfony.com/schema/dic/services" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + <services> + <service id="doctrine_reflection_service" class="PartKeepr\DoctrineReflectionBundle\Services\ReflectionService"> + <argument type="service" id="doctrine"/> + <argument type="service" id="templating"/> + </service> + + <service id="model_cache_warmer" class="PartKeepr\DoctrineReflectionBundle\CacheWarmer\ModelCacheWarmer"> + <tag name="kernel.cache_warmer"/> + <argument type="service" id="doctrine"/> + <argument type="service" id="doctrine_reflection_service"/> + </service> + </services> +</container> diff --git a/src/PartKeepr/DoctrineReflectionBundle/Resources/views/model.js.twig b/src/PartKeepr/DoctrineReflectionBundle/Resources/views/model.js.twig @@ -0,0 +1,12 @@ +Ext.define('{{ className }}', { + extend: 'Ext.data.Model', + fields: [ + {% for field in fields %} + { + name: '{{ field.name }}', + type: '{{ field.type }}' + }{% if not loop.last %},{% endif %} + + {% endfor %} + ] +});+ \ No newline at end of file diff --git a/src/PartKeepr/DoctrineReflectionBundle/Services/ReflectionService.php b/src/PartKeepr/DoctrineReflectionBundle/Services/ReflectionService.php @@ -0,0 +1,98 @@ +<?php +namespace PartKeepr\DoctrineReflectionBundle\Services; + +use Doctrine\Bundle\DoctrineBundle\Registry; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\ClassMetadata; +use Symfony\Component\Templating\EngineInterface; + +class ReflectionService { + + /** @var EntityManager */ + protected $em; + + protected $templateEngine; + + public function __construct (Registry $doctrine, EngineInterface $templateEngine) { + $this->templateEngine = $templateEngine; + $this->em = $doctrine->getManager(); + } + + /** + * Returns a list of all registered entities, converted to the ExtJS naming scheme (. instead of \) + * @return array + */ + public function getEntities() + { + $entities = array(); + + $meta = $this->em->getMetadataFactory()->getAllMetadata(); + + foreach ($meta as $m) { + /** @var ClassMetadata $m */ + $entities[] = $this->convertPHPToExtJSClassName($m->getName()); + } + + return $entities; + } + + public function getEntity($entity) + { + $entity = $this->convertExtJSToPHPClassName($entity); + + $cm = $this->em->getClassMetadata($entity); + + $fields = $cm->getFieldNames(); + + $mappings = array(); + + foreach ($fields as $field) { + $currentMapping = $cm->getFieldMapping($field); + + $mappings[] = array( + "name" => $currentMapping["fieldName"], + "type" => $this->getExtJSFieldMapping($currentMapping["type"]), + ); + } + + $renderParams = array( + "fields" => $mappings, + "className" => $this->convertPHPToExtJSClassName($entity), + ); + + return $this->templateEngine->render('PartKeeprDoctrineReflectionBundle::model.js.twig', $renderParams); +} + + protected function getExtJSFieldMapping($type) + { + switch ($type) { + case "integer": + return "int"; + break; + case "string": + return "string"; + break; + case "text": + return "string"; + break; + case "datetime": + return "date"; + break; + case "boolean": + return "boolean"; + break; + } + + return "undefined"; + } + + protected function convertPHPToExtJSClassName($className) + { + return str_replace("\\", ".", $className); + } + + protected function convertExtJSToPHPClassName($className) + { + return str_replace(".", "\\", $className); + } +}+ \ No newline at end of file diff --git a/src/PartKeepr/FrontendBundle/Controller/IndexController.php b/src/PartKeepr/FrontendBundle/Controller/IndexController.php @@ -8,7 +8,10 @@ use \PartKeepr\AuthBundle\Entity\User\User, PartKeepr\Session\SessionManager, PartKeepr\Util\Configuration; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Finder\Glob; +use Symfony\Component\Finder\SplFileInfo; +use Symfony\Component\Routing\Annotation\Route; class IndexController extends Controller { @@ -73,9 +76,37 @@ class IndexController extends Controller } else { $renderParams["https"] = false; } - return $this->render('PartKeeprFrontendBundle::index.html.twig', $renderParams); + + + $renderParams["models"] = $this->copyModels(); + + return $this->render('PartKeeprFrontendBundle::index.html.twig', $renderParams); } + /** + * Copies all generated models to the frontend directory + * + * @todo Refactor to auto-generate models to the correct directory. This is a workaround. + */ + protected function copyModels () { + $cacheDir = $this->get("kernel")->getCacheDir(); + + $target = $this->get("kernel")->getRootDir()."/../web/bundles/doctrinereflection/"; + @mkdir($target, 0777, true); + + $finder = new Finder(); + $finder->files()->in($cacheDir."/doctrinereflection/"); + + $models = array(); + + foreach ($finder as $file) { + /** @var SplFileInfo $file */ + copy($file->getRealPath(), $target.$file->getBasename()); + $models[] = "bundles/doctrinereflection/".$file->getBasename(); + } + + return $models; + } protected function legacyAuthStuff () { /* HTTP auth */ if (Configuration::getOption("partkeepr.auth.http", false) === true) { diff --git a/src/PartKeepr/FrontendBundle/Resources/views/index.html.twig b/src/PartKeepr/FrontendBundle/Resources/views/index.html.twig @@ -5,6 +5,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>PartKeepr</title> + <base href="{{ app.request.getBaseURL() }}"/> <link href="{% if https %}https{% else %}http{% endif %}://fonts.googleapis.com/css?family=Ubuntu:400,700italic" rel="stylesheet" type="text/css"> @@ -171,41 +172,7 @@ '@PartKeeprFrontendBundle/Resources/public/js/Components/CategoryEditor/CategoryEditorForm.js' '@PartKeeprFrontendBundle/Resources/public/js/Components/Picker/CharPicker.js' '@PartKeeprFrontendBundle/Resources/public/js/webcam.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PartParameter.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PartAttachment.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/StockEntry.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/SiPrefix.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/TipOfTheDay.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/User.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PrintingRenderer.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/UserPreference.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/FootprintAttachment.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/Distributor.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PrintingPageBasicLayout.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PrintingResponse.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/SystemInformationRecord.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/Part.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/Manufacturer.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/AbstractCategory.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PartCategory.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/FootprintCategory.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/ProjectReportList.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/Project.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PartUnit.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PrintingType.js' '@PartKeeprFrontendBundle/Resources/public/js/Models/Message.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/StorageLocation.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PrintingPrintingJobConfiguration.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/ProjectPart.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/StatisticSample.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PartDistributor.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/PartManufacturer.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/ManufacturerICLogo.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/ProjectAttachment.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/Unit.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/SystemNotice.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/Footprint.js' - '@PartKeeprFrontendBundle/Resources/public/js/Models/ProjectReport.js' '@PartKeeprFrontendBundle/Resources/public/js/Ext.ux.Wizard.Card.js' '@PartKeeprFrontendBundle/Resources/public/js/Ext.ux.Wizard.Header.js' '@PartKeeprFrontendBundle/Resources/public/js/Ext.ux.Wizard.js' @@ -226,28 +193,12 @@ '@PartKeeprFrontendBundle/Resources/public/js/webcam.js' %} - {# - -'@PartKeeprFrontendBundle/Resources/public/js/ExtJS/Enhancements/Ext.layout.component.field.Trigger-theme.js' - - - - - - - - - - - - - -#} - - <script type="text/javascript" src="{{ asset_url }}"></script> {% endjavascripts %} + {% for i in models %} + <script type="text/javascript" src="{{ i }}"></script> + {% endfor %} </head> <body> <div id="loading"><span class="logo"></span></div> diff --git a/src/PartKeepr/SiPrefixBundle/Entity/SiPrefix.php b/src/PartKeepr/SiPrefixBundle/Entity/SiPrefix.php @@ -15,7 +15,7 @@ use PartKeepr\Util\BaseEntity, class SiPrefix extends BaseEntity { /** - * The prefix of the Si-Prefix (e.g. yotta, deca, deci, centi) + * The prefix name of the Si-Prefix (e.g. yotta, deca, deci, centi) * * @ORM\Column(type="string") *