diff --git a/.gitignore b/.gitignore index 28282b4..1989e00 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ /node_modules/ /app/Resources/assets/semantic/dist /web/resources/ +.php_cs.cache diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..744b531 --- /dev/null +++ b/.php_cs @@ -0,0 +1,18 @@ +in(__DIR__.'/src'); + +return PhpCsFixer\Config::create() + ->setRules([ + '@Symfony' => true, + 'combine_consecutive_unsets' => true, + 'linebreak_after_opening_tag' => true, + 'no_multiline_whitespace_before_semicolons' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'ordered_imports' => true, + 'phpdoc_order' => true, + 'array_syntax' => array('syntax' => 'short'), + ]) + ->setFinder($finder); diff --git a/README.md b/README.md index 64ff678..aaf289a 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,16 @@ You can check if your system meets requirements by running `$ bin/symfony_requir For full requirements see Symfony 3.2 [docs](http://symfony.com/doc/3.2/reference/requirements.html). ###Installing - \ No newline at end of file + +####Back-end +1. Make sure your system meets the application requirements +2. Install dependencies via [Composer](https://getcomposer.org/), `$ composer install` + +####Front-end +1. Install dependencies via [npm](https://www.npmjs.com/), `$ npm install` +2. Compile assets by running [Gulp](http://gulpjs.com/) default task, `$ gulp default` + +####Database +1. Set application parameters in *app/config/parameters.yml* +2. Generate empty database by running command `$ php bin/console doctrine:database:create` + \ No newline at end of file diff --git a/app/AppKernel.php b/app/AppKernel.php index 4c1b43e..724f7f9 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -17,6 +17,7 @@ class AppKernel extends Kernel new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new AppBundle\AppBundle(), new Knp\Bundle\MenuBundle\KnpMenuBundle(), + new Oneup\FlysystemBundle\OneupFlysystemBundle(), ]; if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { diff --git a/app/Resources/assets/javascripts/ModelViewer.js b/app/Resources/assets/javascripts/ModelViewer.js new file mode 100644 index 0000000..a201365 --- /dev/null +++ b/app/Resources/assets/javascripts/ModelViewer.js @@ -0,0 +1,92 @@ +ModelViewer = function() { + var container; + var camera, scene, cameraTarget, renderer, controls, object; + var width, height; + + this.init = function(containerId) { + container = document.getElementById(containerId); + + if (document.defaultView && document.defaultView.getComputedStyle) { + width = parseFloat(document.defaultView.getComputedStyle(container,null).getPropertyValue('width')); + height = parseFloat(document.defaultView.getComputedStyle(container,null).getPropertyValue('height')); + } else { + width = parseFloat(container.currentStyle.width); + height = parseFloat(container.currentStyle.height); + } + + + camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 1000); + camera.position.set(-2, 2, 0.8); + camera.lookAt(new THREE.Vector3(0, 3, 0)); + + scene = new THREE.Scene(); + scene.fog = new THREE.FogExp2(0x000000, 0.001); + + + var grid = new THREE.GridHelper( 30, 70 ); + grid.position.set(30/70,-0.5,30/70); + scene.add( grid ); + + // Lights + + light = new THREE.DirectionalLight( 0xffffff ); + light.position.set( 1, 1, 1 ); + scene.add( light ); + + light = new THREE.DirectionalLight( 0x002288 ); + light.position.set( -1, -1, -1 ); + scene.add( light ); + + + scene.add( new THREE.AmbientLight( 0xf0f0f0 )); + scene.background = new THREE.Color( 0x000000 ); + + // renderer + renderer = new THREE.WebGLRenderer(); + renderer.setClearColor( scene.fog.color ); + renderer.setPixelRatio( window.devicePixelRatio ); + renderer.setSize( width, height ); + renderer.gammaInput = true; + renderer.gammaOutput = true; + renderer.shadowMap.enabled = true; + renderer.shadowMap.renderReverseSided = false; + + container.appendChild(renderer.domElement); + + controls = new THREE.OrbitControls( camera, renderer.domElement ); + controls.addEventListener( 'change', this.render ); // add this only if there is no animation loop (requestAnimationFrame) + // controls.enableDamping = true; + // controls.dampingFactor = 0.25; + controls.enableZoom = true; + + }; + + this.loadStl = function(model) { + var loader = new THREE.STLLoader(); + loader.load(model, function (geometry) { + var material = new THREE.MeshPhongMaterial({color: 0xaaaaaa, shininess:200, specular: 0x333333, shading: THREE.FlatShading}); + + var mesh = new THREE.Mesh(geometry, material); + mesh.position.set(0, 0.5, 0); + mesh.rotation.set(Math.PI, 0, 0); + mesh.castShadow = true; + mesh.receiveShadow = true; + scene.add(mesh); + + renderer.render(scene, camera); + }); + }; + + this.animate = function() { + + requestAnimationFrame( this.animate ); + + controls.update(); // required if controls.enableDamping = true, or if controls.autoRotate = true + + this.render(); + }; + + this.render = function() { + renderer.render(scene, camera); + }; +}; \ No newline at end of file diff --git a/app/Resources/assets/javascripts/STLLoader.js b/app/Resources/assets/javascripts/STLLoader.js deleted file mode 100644 index bbcff10..0000000 --- a/app/Resources/assets/javascripts/STLLoader.js +++ /dev/null @@ -1,491 +0,0 @@ -/** - * @author aleeper / http://adamleeper.com/ - * @author mrdoob / http://mrdoob.com/ - * @author gero3 / https://github.com/gero3 - * - * Description: A THREE loader for STL ASCII files, as created by Solidworks and other CAD programs. - * - * Supports both binary and ASCII encoded files, with automatic detection of type. - * - * Limitations: - * Binary decoding supports "Magics" color format (http://en.wikipedia.org/wiki/STL_(file_format)#Color_in_binary_STL). - * There is perhaps some question as to how valid it is to always assume little-endian-ness. - * ASCII decoding assumes file is UTF-8. Seems to work for the examples... - * - * Usage: - * var loader = new THREE.STLLoader(); - * loader.load( './models/stl/slotted_disk.stl', function ( geometry ) { - * scene.add( new THREE.Mesh( geometry ) ); - * }); - * - * For binary STLs geometry might contain colors for vertices. To use it: - * // use the same code to load STL as above - * if (geometry.hasColors) { - * material = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors }); - * } else { .... } - * var mesh = new THREE.Mesh( geometry, material ); - */ - - -THREE.STLLoader = function ( manager ) { - - this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; - -}; - -THREE.STLLoader.prototype = { - - constructor: THREE.STLLoader, - - load: function ( url, onLoad, onProgress, onError ) { - - var scope = this; - - var loader = new THREE.XHRLoader( scope.manager ); - loader.setResponseType( 'arraybuffer' ); - loader.load( url, function ( text ) { - - onLoad( scope.parse( text ) ); - - }, onProgress, onError ); - - }, - - parse: function ( data ) { - - var isBinary = function () { - - var expect, face_size, n_faces, reader; - reader = new DataView( binData ); - face_size = ( 32 / 8 * 3 ) + ( ( 32 / 8 * 3 ) * 3 ) + ( 16 / 8 ); - n_faces = reader.getUint32( 80, true ); - expect = 80 + ( 32 / 8 ) + ( n_faces * face_size ); - - if ( expect === reader.byteLength ) { - - return true; - - } - - // some binary files will have different size from expected, - // checking characters higher than ASCII to confirm is binary - var fileLength = reader.byteLength; - for ( var index = 0; index < fileLength; index ++ ) { - - if ( reader.getUint8( index, false ) > 127 ) { - - return true; - - } - - } - - return false; - - }; - - var binData = this.ensureBinary( data ); - - return isBinary() - ? this.parseBinary( binData ) - : this.parseASCII( this.ensureString( data ) ); - - }, - - parseBinary: function ( data ) { - - var reader = new DataView( data ); - var faces = reader.getUint32( 80, true ); - - var r, g, b, hasColors = false, colors; - var defaultR, defaultG, defaultB, alpha; - - // process STL header - // check for default color in header ("COLOR=rgba" sequence). - - for ( var index = 0; index < 80 - 10; index ++ ) { - - if ( ( reader.getUint32( index, false ) == 0x434F4C4F /*COLO*/ ) && - ( reader.getUint8( index + 4 ) == 0x52 /*'R'*/ ) && - ( reader.getUint8( index + 5 ) == 0x3D /*'='*/ ) ) { - - hasColors = true; - colors = new Float32Array( faces * 3 * 3 ); - - defaultR = reader.getUint8( index + 6 ) / 255; - defaultG = reader.getUint8( index + 7 ) / 255; - defaultB = reader.getUint8( index + 8 ) / 255; - alpha = reader.getUint8( index + 9 ) / 255; - - } - - } - - var dataOffset = 84; - var faceLength = 12 * 4 + 2; - - var offset = 0; - - var geometry = new THREE.BufferGeometry(); - - var vertices = new Float32Array( faces * 3 * 3 ); - var normals = new Float32Array( faces * 3 * 3 ); - - for ( var face = 0; face < faces; face ++ ) { - - var start = dataOffset + face * faceLength; - var normalX = reader.getFloat32( start, true ); - var normalY = reader.getFloat32( start + 4, true ); - var normalZ = reader.getFloat32( start + 8, true ); - - if ( hasColors ) { - - var packedColor = reader.getUint16( start + 48, true ); - - if ( ( packedColor & 0x8000 ) === 0 ) { - - // facet has its own unique color - - r = ( packedColor & 0x1F ) / 31; - g = ( ( packedColor >> 5 ) & 0x1F ) / 31; - b = ( ( packedColor >> 10 ) & 0x1F ) / 31; - - } else { - - r = defaultR; - g = defaultG; - b = defaultB; - - } - - } - - for ( var i = 1; i <= 3; i ++ ) { - - var vertexstart = start + i * 12; - - vertices[ offset ] = reader.getFloat32( vertexstart, true ); - vertices[ offset + 1 ] = reader.getFloat32( vertexstart + 4, true ); - vertices[ offset + 2 ] = reader.getFloat32( vertexstart + 8, true ); - - normals[ offset ] = normalX; - normals[ offset + 1 ] = normalY; - normals[ offset + 2 ] = normalZ; - - if ( hasColors ) { - - colors[ offset ] = r; - colors[ offset + 1 ] = g; - colors[ offset + 2 ] = b; - - } - - offset += 3; - - } - - } - - geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); - - if ( hasColors ) { - - geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); - geometry.hasColors = true; - geometry.alpha = alpha; - - } - - return geometry; - - }, - - parseASCII: function ( data ) { - - var geometry, length, normal, patternFace, patternNormal, patternVertex, result, text; - geometry = new THREE.Geometry(); - patternFace = /facet([\s\S]*?)endfacet/g; - - while ( ( result = patternFace.exec( data ) ) !== null ) { - - text = result[ 0 ]; - patternNormal = /normal[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g; - - while ( ( result = patternNormal.exec( text ) ) !== null ) { - - normal = new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) ); - - } - - patternVertex = /vertex[\s]+([\-+]?[0-9]+\.?[0-9]*([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+[\s]+([\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?)+/g; - - while ( ( result = patternVertex.exec( text ) ) !== null ) { - - geometry.vertices.push( new THREE.Vector3( parseFloat( result[ 1 ] ), parseFloat( result[ 3 ] ), parseFloat( result[ 5 ] ) ) ); - - } - - length = geometry.vertices.length; - - geometry.faces.push( new THREE.Face3( length - 3, length - 2, length - 1, normal ) ); - - } - - geometry.computeBoundingBox(); - geometry.computeBoundingSphere(); - - return geometry; - - }, - - ensureString: function ( buf ) { - - if ( typeof buf !== "string" ) { - - var array_buffer = new Uint8Array( buf ); - var strArray = []; - for ( var i = 0; i < buf.byteLength; i ++ ) { - - strArray.push(String.fromCharCode( array_buffer[ i ] )); // implicitly assumes little-endian - - } - return strArray.join(''); - - } else { - - return buf; - - } - - }, - - ensureBinary: function ( buf ) { - - if ( typeof buf === "string" ) { - - var array_buffer = new Uint8Array( buf.length ); - for ( var i = 0; i < buf.length; i ++ ) { - - array_buffer[ i ] = buf.charCodeAt( i ) & 0xff; // implicitly assumes little-endian - - } - return array_buffer.buffer || array_buffer; - - } else { - - return buf; - - } - - } - -}; - -if ( typeof DataView === 'undefined' ) { - - DataView = function( buffer, byteOffset, byteLength ) { - - this.buffer = buffer; - this.byteOffset = byteOffset || 0; - this.byteLength = byteLength || buffer.byteLength || buffer.length; - this._isString = typeof buffer === "string"; - - }; - - DataView.prototype = { - - _getCharCodes: function( buffer, start, length ) { - - start = start || 0; - length = length || buffer.length; - var end = start + length; - var codes = []; - for ( var i = start; i < end; i ++ ) { - - codes.push( buffer.charCodeAt( i ) & 0xff ); - - } - return codes; - - }, - - _getBytes: function ( length, byteOffset, littleEndian ) { - - var result; - - // Handle the lack of endianness - if ( littleEndian === undefined ) { - - littleEndian = this._littleEndian; - - } - - // Handle the lack of byteOffset - if ( byteOffset === undefined ) { - - byteOffset = this.byteOffset; - - } else { - - byteOffset = this.byteOffset + byteOffset; - - } - - if ( length === undefined ) { - - length = this.byteLength - byteOffset; - - } - - // Error Checking - if ( typeof byteOffset !== 'number' ) { - - throw new TypeError( 'DataView byteOffset is not a number' ); - - } - - if ( length < 0 || byteOffset + length > this.byteLength ) { - - throw new Error( 'DataView length or (byteOffset+length) value is out of bounds' ); - - } - - if ( this.isString ) { - - result = this._getCharCodes( this.buffer, byteOffset, byteOffset + length ); - - } else { - - result = this.buffer.slice( byteOffset, byteOffset + length ); - - } - - if ( ! littleEndian && length > 1 ) { - - if ( Array.isArray( result ) === false ) { - - result = Array.prototype.slice.call( result ); - - } - - result.reverse(); - - } - - return result; - - }, - - // Compatibility functions on a String Buffer - - getFloat64: function ( byteOffset, littleEndian ) { - - var b = this._getBytes( 8, byteOffset, littleEndian ), - - sign = 1 - ( 2 * ( b[ 7 ] >> 7 ) ), - exponent = ( ( ( ( b[ 7 ] << 1 ) & 0xff ) << 3 ) | ( b[ 6 ] >> 4 ) ) - ( ( 1 << 10 ) - 1 ), - - // Binary operators such as | and << operate on 32 bit values, using + and Math.pow(2) instead - mantissa = ( ( b[ 6 ] & 0x0f ) * Math.pow( 2, 48 ) ) + ( b[ 5 ] * Math.pow( 2, 40 ) ) + ( b[ 4 ] * Math.pow( 2, 32 ) ) + - ( b[ 3 ] * Math.pow( 2, 24 ) ) + ( b[ 2 ] * Math.pow( 2, 16 ) ) + ( b[ 1 ] * Math.pow( 2, 8 ) ) + b[ 0 ]; - - if ( exponent === 1024 ) { - - if ( mantissa !== 0 ) { - - return NaN; - - } else { - - return sign * Infinity; - - } - - } - - if ( exponent === - 1023 ) { - - // Denormalized - return sign * mantissa * Math.pow( 2, - 1022 - 52 ); - - } - - return sign * ( 1 + mantissa * Math.pow( 2, - 52 ) ) * Math.pow( 2, exponent ); - - }, - - getFloat32: function ( byteOffset, littleEndian ) { - - var b = this._getBytes( 4, byteOffset, littleEndian ), - - sign = 1 - ( 2 * ( b[ 3 ] >> 7 ) ), - exponent = ( ( ( b[ 3 ] << 1 ) & 0xff ) | ( b[ 2 ] >> 7 ) ) - 127, - mantissa = ( ( b[ 2 ] & 0x7f ) << 16 ) | ( b[ 1 ] << 8 ) | b[ 0 ]; - - if ( exponent === 128 ) { - - if ( mantissa !== 0 ) { - - return NaN; - - } else { - - return sign * Infinity; - - } - - } - - if ( exponent === - 127 ) { - - // Denormalized - return sign * mantissa * Math.pow( 2, - 126 - 23 ); - - } - - return sign * ( 1 + mantissa * Math.pow( 2, - 23 ) ) * Math.pow( 2, exponent ); - - }, - - getInt32: function ( byteOffset, littleEndian ) { - - var b = this._getBytes( 4, byteOffset, littleEndian ); - return ( b[ 3 ] << 24 ) | ( b[ 2 ] << 16 ) | ( b[ 1 ] << 8 ) | b[ 0 ]; - - }, - - getUint32: function ( byteOffset, littleEndian ) { - - return this.getInt32( byteOffset, littleEndian ) >>> 0; - - }, - - getInt16: function ( byteOffset, littleEndian ) { - - return ( this.getUint16( byteOffset, littleEndian ) << 16 ) >> 16; - - }, - - getUint16: function ( byteOffset, littleEndian ) { - - var b = this._getBytes( 2, byteOffset, littleEndian ); - return ( b[ 1 ] << 8 ) | b[ 0 ]; - - }, - - getInt8: function ( byteOffset ) { - - return ( this.getUint8( byteOffset ) << 24 ) >> 24; - - }, - - getUint8: function ( byteOffset ) { - - return this._getBytes( 1, byteOffset )[ 0 ]; - - } - - }; - -} diff --git a/app/Resources/views/default/index.html.twig b/app/Resources/views/default/index.html.twig index aa88ca9..e8b7a5f 100644 --- a/app/Resources/views/default/index.html.twig +++ b/app/Resources/views/default/index.html.twig @@ -1,76 +1,6 @@ {% extends 'base.html.twig' %} {% block body %} -
-
-
-

Welcome to Symfony {{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION') }}

-
-
-

- - - Your application is now ready. You can start working on it at: - {{ base_dir }} -

-
- - - -
-
{% endblock %} -{% block stylesheets %} - -{% endblock %} diff --git a/app/Resources/views/part/detail.html.twig b/app/Resources/views/part/detail.html.twig new file mode 100644 index 0000000..b6461a2 --- /dev/null +++ b/app/Resources/views/part/detail.html.twig @@ -0,0 +1,33 @@ +{% extends 'base.html.twig' %} + +{% block body %} + + {{ dump(part) }} + + {{ dump(localPart) }} + +
+ + +{% endblock %} + +{% block javascripts %} + {{ parent() }} + + + + + + + + +{% endblock %} \ No newline at end of file diff --git a/app/Resources/views/parts/detail.html.twig b/app/Resources/views/parts/detail.html.twig deleted file mode 100644 index e626c3c..0000000 --- a/app/Resources/views/parts/detail.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'base.html.twig' %} - -{% block body %} - - {{ dump(part) }} - -{% endblock %} \ No newline at end of file diff --git a/app/Resources/views/sets/browse.html.twig b/app/Resources/views/set/browse.html.twig similarity index 100% rename from app/Resources/views/sets/browse.html.twig rename to app/Resources/views/set/browse.html.twig diff --git a/app/Resources/views/sets/detail.html.twig b/app/Resources/views/set/detail.html.twig similarity index 100% rename from app/Resources/views/sets/detail.html.twig rename to app/Resources/views/set/detail.html.twig diff --git a/app/config/config.yml b/app/config/config.yml index 685a70d..4b4bbd4 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -7,6 +7,11 @@ imports: # http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: locale: en + rebrickable_url: + pieces: 'http://rebrickable.com/files/pieces.csv.gz' + sets: 'http://rebrickable.com/files/sets.csv.gz' + set_pieces: 'http://rebrickable.com/files/set_pieces.csv.gz' + ldraw_url: 'http://www.ldraw.org/library/updates/completeCA.zip' framework: #esi: ~ @@ -75,4 +80,13 @@ knp_menu: # if true, enables the helper for PHP templates templating: false # the renderer to use, list is also available by default - default_renderer: twig \ No newline at end of file + default_renderer: twig + +oneup_flysystem: + adapters: + ldraw_adapter: + local: + directory: "%kernel.root_dir%/../var/data/ldraw" + filesystems: + ldraw: + adapter: ldraw_adapter \ No newline at end of file diff --git a/app/config/services.yml b/app/config/services.yml index fa1ed9f..5814f07 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -13,12 +13,16 @@ services: class: AppBundle\Api\Manager\RebrickableManager arguments: ['@client.rebrickable'] - app.collection_service: + sevice.collection: class: AppBundle\Service\CollectionService arguments: ['@doctrine.orm.entity_manager', '@manager.brickset','@manager.rebrickable'] - app.model_loader_service: - class: AppBundle\Service\ModelLoaderService - arguments: ['@doctrine.orm.entity_manager','%kernel.root_dir%/../var/data/LDrawLibrary', '@manager.rebrickable'] + + loader.rebrickable: + class: AppBundle\Command\Loader\RebrickableLoader + arguments: ['@doctrine.orm.entity_manager', '@manager.rebrickable', '%rebrickable_url%' ] + loader.ldraw: + class: AppBundle\Command\Loader\LDrawLoader + arguments: ['@doctrine.orm.entity_manager', '%kernel.root_dir%/../bin/ldview', '@oneup_flysystem.ldraw_filesystem', '%ldraw_url%'] app.form.filter_set: class: AppBundle\Form\FilterSetType diff --git a/bin/ldview b/bin/ldview new file mode 100644 index 0000000..d255b0f Binary files /dev/null and b/bin/ldview differ diff --git a/bin/php-cs-fixer-hook.sh b/bin/php-cs-fixer-hook.sh new file mode 100644 index 0000000..47bcf2f --- /dev/null +++ b/bin/php-cs-fixer-hook.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# To use this hook you need to install php-cs-fixer +# Copy this file to ./git/hooks/pre-commit to get it working. + +ROOT="" + +echo "php-cs-fixer pre commit hook start" + +PHP_CS_FIXER="vendor/bin/php-cs-fixer" +HAS_PHP_CS_FIXER=false + +if [ -x vendor/bin/php-cs-fixer ]; then + HAS_PHP_CS_FIXER=true +fi + +if $HAS_PHP_CS_FIXER; then + git status --porcelain | grep -e '^[AM]\(.*\).php$' | cut -c 3- | while read line; do + $PHP_CS_FIXER fix --config=$ROOT/.php_cs --verbose "$line"; + git add "$line"; + done +else + echo "" + echo "Please install php-cs-fixer, e.g.:" + echo "" + echo " composer require --dev friendsofphp/php-cs-fixer" + echo "" +fi + +echo "php-cs-fixer pre commit hook finish" \ No newline at end of file diff --git a/composer.json b/composer.json index 7368436..4346b66 100644 --- a/composer.json +++ b/composer.json @@ -23,11 +23,13 @@ "sensio/framework-extra-bundle": "^3.0.2", "incenteev/composer-parameter-handler": "^2.0", "guzzlehttp/guzzle": "^6.2", - "knplabs/knp-menu-bundle": "^2.0" + "knplabs/knp-menu-bundle": "^2.0", + "oneup/flysystem-bundle": "^1.7" }, "require-dev": { "sensio/generator-bundle": "^3.0", - "symfony/phpunit-bridge": "^3.0" + "symfony/phpunit-bridge": "^3.0", + "friendsofphp/php-cs-fixer": "^2.0" }, "scripts": { "symfony-scripts": [ diff --git a/composer.lock b/composer.lock index 47c4b3e..fccd0a0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5ce1afc2e13970cdfddedeb899ae01a1", - "content-hash": "f88eedfb311bae0ebb9f759a2d044707", + "content-hash": "54b7bfc7ee85ba1c5bb4cd9f7d9cfa60", "packages": [ { "name": "doctrine/annotations", @@ -73,7 +72,7 @@ "docblock", "parser" ], - "time": "2015-08-31 12:32:49" + "time": "2015-08-31T12:32:49+00:00" }, { "name": "doctrine/cache", @@ -143,7 +142,7 @@ "cache", "caching" ], - "time": "2016-10-29 11:16:17" + "time": "2016-10-29T11:16:17+00:00" }, { "name": "doctrine/collections", @@ -209,7 +208,7 @@ "collections", "iterator" ], - "time": "2015-04-14 22:21:58" + "time": "2015-04-14T22:21:58+00:00" }, { "name": "doctrine/common", @@ -282,7 +281,7 @@ "persistence", "spl" ], - "time": "2016-11-30 16:50:46" + "time": "2016-11-30T16:50:46+00:00" }, { "name": "doctrine/dbal", @@ -353,7 +352,7 @@ "persistence", "queryobject" ], - "time": "2016-09-09 19:13:33" + "time": "2016-09-09T19:13:33+00:00" }, { "name": "doctrine/doctrine-bundle", @@ -434,7 +433,7 @@ "orm", "persistence" ], - "time": "2016-08-10 15:35:22" + "time": "2016-08-10T15:35:22+00:00" }, { "name": "doctrine/doctrine-cache-bundle", @@ -522,7 +521,7 @@ "cache", "caching" ], - "time": "2016-01-26 17:28:51" + "time": "2016-01-26T17:28:51+00:00" }, { "name": "doctrine/inflector", @@ -589,7 +588,7 @@ "singularize", "string" ], - "time": "2015-11-06 14:35:42" + "time": "2015-11-06T14:35:42+00:00" }, { "name": "doctrine/instantiator", @@ -643,7 +642,7 @@ "constructor", "instantiate" ], - "time": "2015-06-14 21:17:01" + "time": "2015-06-14T21:17:01+00:00" }, { "name": "doctrine/lexer", @@ -697,7 +696,7 @@ "lexer", "parser" ], - "time": "2014-09-09 13:34:57" + "time": "2014-09-09T13:34:57+00:00" }, { "name": "doctrine/orm", @@ -773,7 +772,7 @@ "database", "orm" ], - "time": "2016-12-18 15:42:34" + "time": "2016-12-18T15:42:34+00:00" }, { "name": "guzzlehttp/guzzle", @@ -835,7 +834,7 @@ "rest", "web service" ], - "time": "2016-10-08 15:01:37" + "time": "2016-10-08T15:01:37+00:00" }, { "name": "guzzlehttp/promises", @@ -886,7 +885,7 @@ "keywords": [ "promise" ], - "time": "2016-12-20 10:07:11" + "time": "2016-12-20T10:07:11+00:00" }, { "name": "guzzlehttp/psr7", @@ -944,7 +943,7 @@ "stream", "uri" ], - "time": "2016-06-24 23:00:38" + "time": "2016-06-24T23:00:38+00:00" }, { "name": "incenteev/composer-parameter-handler", @@ -995,7 +994,7 @@ "keywords": [ "parameters management" ], - "time": "2015-11-10 17:04:01" + "time": "2015-11-10T17:04:01+00:00" }, { "name": "jdorn/sql-formatter", @@ -1045,7 +1044,7 @@ "highlight", "sql" ], - "time": "2014-01-12 16:20:24" + "time": "2014-01-12T16:20:24+00:00" }, { "name": "knplabs/knp-menu", @@ -1111,7 +1110,7 @@ "menu", "tree" ], - "time": "2016-09-22 07:36:19" + "time": "2016-09-22T07:36:19+00:00" }, { "name": "knplabs/knp-menu-bundle", @@ -1168,7 +1167,90 @@ "keywords": [ "menu" ], - "time": "2016-09-22 12:24:40" + "time": "2016-09-22T12:24:40+00:00" + }, + { + "name": "league/flysystem", + "version": "1.0.32", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "1b5c4a0031697f46e779a9d1b309c2e1b24daeab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1b5c4a0031697f46e779a9d1b309c2e1b24daeab", + "reference": "1b5c4a0031697f46e779a9d1b309c2e1b24daeab", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "ext-fileinfo": "*", + "mockery/mockery": "~0.9", + "phpspec/phpspec": "^2.2", + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-copy": "Allows you to use Copy.com storage", + "league/flysystem-dropbox": "Allows you to use Dropbox storage", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "time": "2016-10-19T20:38:46+00:00" }, { "name": "monolog/monolog", @@ -1246,7 +1328,86 @@ "logging", "psr-3" ], - "time": "2016-11-26 00:15:39" + "time": "2016-11-26T00:15:39+00:00" + }, + { + "name": "oneup/flysystem-bundle", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/1up-lab/OneupFlysystemBundle.git", + "reference": "5b8b5896d6981127b5c55e7620d10dabb86778bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/5b8b5896d6981127b5c55e7620d10dabb86778bc", + "reference": "5b8b5896d6981127b5c55e7620d10dabb86778bc", + "shasum": "" + }, + "require": { + "league/flysystem": "^1.0.14", + "php": ">=5.4.0", + "symfony/framework-bundle": "~2.0|~3.0" + }, + "require-dev": { + "league/flysystem-aws-s3-v2": "~1.0", + "league/flysystem-cached-adapter": "~1.0", + "league/flysystem-copy": "~1.0", + "league/flysystem-dropbox": "~1.0", + "league/flysystem-gridfs": "~1.0", + "league/flysystem-memory": "~1.0", + "league/flysystem-rackspace": "~1.0", + "league/flysystem-sftp": "~1.0", + "league/flysystem-webdav": "~1.0", + "league/flysystem-ziparchive": "~1.0", + "litipk/flysystem-fallback-adapter": "~0.1", + "phpunit/phpunit": "4.4.*", + "symfony/browser-kit": "~2.0|~3.0", + "symfony/finder": "~2.0|~3.0", + "twistor/flysystem-stream-wrapper": "~1.0" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "league/flysystem-aws-s3-v2": "Use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Use S3 storage with AWS SDK v3", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-copy": "Allows you to use Copy.com storage", + "league/flysystem-dropbox": "Use Dropbox storage", + "league/flysystem-gridfs": "Allows you to use GridFS adapter", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "litipk/flysystem-fallback-adapter": "Allows you to use a fallback filesystem", + "twistor/flysystem-stream-wrapper": "Allows you to use stream wrapper" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Oneup\\FlysystemBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Schmid", + "email": "js@1up.io", + "homepage": "http://1up.io", + "role": "Developer" + } + ], + "description": "Integrates Flysystem filesystem abstraction library to your Symfony2 project.", + "homepage": "http://1up.io", + "keywords": [ + "Flysystem", + "Symfony2", + "abstraction", + "filesystem" + ], + "time": "2016-12-04T12:16:31+00:00" }, { "name": "paragonie/random_compat", @@ -1294,7 +1455,7 @@ "pseudorandom", "random" ], - "time": "2016-11-07 23:38:38" + "time": "2016-11-07T23:38:38+00:00" }, { "name": "psr/cache", @@ -1340,7 +1501,7 @@ "psr", "psr-6" ], - "time": "2016-08-06 20:24:11" + "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/http-message", @@ -1390,7 +1551,7 @@ "request", "response" ], - "time": "2016-08-06 14:39:51" + "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", @@ -1437,7 +1598,7 @@ "psr", "psr-3" ], - "time": "2016-10-10 12:19:37" + "time": "2016-10-10T12:19:37+00:00" }, { "name": "sensio/distribution-bundle", @@ -1489,7 +1650,7 @@ "configuration", "distribution" ], - "time": "2016-12-06 07:29:27" + "time": "2016-12-06T07:29:27+00:00" }, { "name": "sensio/framework-extra-bundle", @@ -1557,7 +1718,7 @@ "annotations", "controllers" ], - "time": "2016-12-14 08:30:06" + "time": "2016-12-14T08:30:06+00:00" }, { "name": "sensiolabs/security-checker", @@ -1601,7 +1762,7 @@ } ], "description": "A security checker for your composer.lock", - "time": "2016-09-23 18:09:57" + "time": "2016-09-23T18:09:57+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -1654,7 +1815,7 @@ "mail", "mailer" ], - "time": "2016-11-24 01:01:23" + "time": "2016-11-24T01:01:23+00:00" }, { "name": "symfony/monolog-bundle", @@ -1714,7 +1875,7 @@ "log", "logging" ], - "time": "2016-11-06 18:54:50" + "time": "2016-11-06T18:54:50+00:00" }, { "name": "symfony/polyfill-apcu", @@ -1767,7 +1928,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-intl-icu", @@ -1825,7 +1986,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1884,7 +2045,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-php56", @@ -1940,7 +2101,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-php70", @@ -1999,7 +2160,7 @@ "portable", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/polyfill-util", @@ -2051,7 +2212,7 @@ "polyfill", "shim" ], - "time": "2016-11-14 01:06:16" + "time": "2016-11-14T01:06:16+00:00" }, { "name": "symfony/swiftmailer-bundle", @@ -2110,7 +2271,7 @@ ], "description": "Symfony SwiftmailerBundle", "homepage": "http://symfony.com", - "time": "2016-12-20 04:44:33" + "time": "2016-12-20T04:44:33+00:00" }, { "name": "symfony/symfony", @@ -2252,7 +2413,7 @@ "keywords": [ "framework" ], - "time": "2016-12-13 13:20:15" + "time": "2016-12-13T13:20:15+00:00" }, { "name": "twig/twig", @@ -2313,10 +2474,127 @@ "keywords": [ "templating" ], - "time": "2016-12-13 17:28:18" + "time": "2016-12-13T17:28:18+00:00" } ], "packages-dev": [ + { + "name": "friendsofphp/php-cs-fixer", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", + "reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/f3baf72eb2f58bf275b372540f5b47d25aed910f", + "reference": "f3baf72eb2f58bf275b372540f5b47d25aed910f", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^5.3.6 || >=7.0 <7.2", + "sebastian/diff": "^1.1", + "symfony/console": "^2.3 || ^3.0", + "symfony/event-dispatcher": "^2.1 || ^3.0", + "symfony/filesystem": "^2.4 || ^3.0", + "symfony/finder": "^2.2 || ^3.0", + "symfony/polyfill-php54": "^1.0", + "symfony/process": "^2.3 || ^3.0", + "symfony/stopwatch": "^2.5 || ^3.0" + }, + "conflict": { + "hhvm": "<3.9" + }, + "require-dev": { + "gecko-packages/gecko-php-unit": "^2.0", + "phpunit/phpunit": "^4.5|^5", + "satooshi/php-coveralls": "^1.0" + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dariusz RumiƄski", + "email": "dariusz.ruminski@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "time": "2016-12-01T06:18:06+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2015-12-08T07:14:41+00:00" + }, { "name": "sensio/generator-bundle", "version": "v3.1.2", @@ -2367,7 +2645,7 @@ } ], "description": "This bundle generates code for you", - "time": "2016-12-05 16:01:19" + "time": "2016-12-05T16:01:19+00:00" }, { "name": "symfony/phpunit-bridge", @@ -2425,7 +2703,65 @@ ], "description": "Symfony PHPUnit Bridge", "homepage": "https://symfony.com", - "time": "2016-12-12 13:31:08" + "time": "2016-12-12T13:31:08+00:00" + }, + { + "name": "symfony/polyfill-php54", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php54.git", + "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0", + "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php54\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2016-11-14T01:06:16+00:00" } ], "aliases": [], diff --git a/gulpfile.js b/gulpfile.js index 6b6b82b..c977193 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -17,11 +17,32 @@ gulp.task('css', function() { .pipe(gulp.dest('web/resources/css')); }); +gulp.task('three', function() { + gulp.src([ + 'node_modules/three/build/three.js', + 'node_modules/three/examples/js/libs/stats.min.js', + 'node_modules/three/examples/js/loaders/STLLoader.js', + ]) + .pipe(plugins.concat('three.js')) + .pipe(gulp.dest('web/resources/js')); + + gulp.src([ + 'node_modules/three/examples/js/controls/OrbitControls.js', + ]) + .pipe(plugins.concat('OrbitControls.js')) + .pipe(gulp.dest('web/resources/js')); + + gulp.src([ + 'app/Resources/assets/javascripts/ModelViewer.js', + ]) + .pipe(plugins.concat('ModelViewer.js')) + .pipe(gulp.dest('web/resources/js')); +}); + gulp.task('js', function() { return gulp.src([ 'node_modules/jquery/dist/jquery.js', 'app/Resources/assets/semantic/dist/semantic.js', - 'node_modules//three/build/three.js' ]) .pipe(plugins.concat('main.js')) .pipe(gulp.dest('web/resources/js')); diff --git a/src/AppBundle/Api/Client/Brickset/Brickset.php b/src/AppBundle/Api/Client/Brickset/Brickset.php index 7ac2831..4d98dca 100644 --- a/src/AppBundle/Api/Client/Brickset/Brickset.php +++ b/src/AppBundle/Api/Client/Brickset/Brickset.php @@ -23,7 +23,7 @@ class Brickset extends \SoapClient /** * @var array The defined classes */ - private static $classmap = array( + private static $classmap = [ 'sets' => Set::class, 'additionalImages' => AdditionalImage::class, 'instructions' => Instructions::class, @@ -31,14 +31,14 @@ class Brickset extends \SoapClient 'themes' => Theme::class, 'subthemes' => Subtheme::class, 'years' => Year::class, - ); + ]; /** * @param string $apikey Brickset API key * @param array $options A array of config values * @param string $wsdl The wsdl file to use */ - public function __construct($apikey, $wsdl = null, array $options = array()) + public function __construct($apikey, $wsdl = null, array $options = []) { $this->apiKey = $apikey; @@ -238,11 +238,10 @@ class Brickset extends \SoapClient return false; } elseif (strpos($response, 'ERROR:') === 0) { return false; - } else { - $this->userHash = $response; - - return true; } + $this->userHash = $response; + + return true; } /** diff --git a/src/AppBundle/Api/Client/Brickset/Entity/Review.php b/src/AppBundle/Api/Client/Brickset/Entity/Review.php index 632e04c..c692749 100644 --- a/src/AppBundle/Api/Client/Brickset/Entity/Review.php +++ b/src/AppBundle/Api/Client/Brickset/Entity/Review.php @@ -57,7 +57,7 @@ class Review /** * Review constructor. */ - function __construct() + public function __construct() { } @@ -88,12 +88,11 @@ class Review { if ($this->datePosted == null) { return null; - } else { - try { - return new \DateTime($this->datePosted); - } catch (\Exception $e) { - return null; - } + } + try { + return new \DateTime($this->datePosted); + } catch (\Exception $e) { + return null; } } diff --git a/src/AppBundle/Api/Client/Brickset/Entity/Set.php b/src/AppBundle/Api/Client/Brickset/Entity/Set.php index d1edc95..6b5ad5c 100644 --- a/src/AppBundle/Api/Client/Brickset/Entity/Set.php +++ b/src/AppBundle/Api/Client/Brickset/Entity/Set.php @@ -848,12 +848,11 @@ class Set { if ($this->lastUpdated == null) { return null; - } else { - try { - return new \DateTime($this->lastUpdated); - } catch (\Exception $e) { - return null; - } + } + try { + return new \DateTime($this->lastUpdated); + } catch (\Exception $e) { + return null; } } diff --git a/src/AppBundle/Api/Client/Rebrickable/Entity/Part.php b/src/AppBundle/Api/Client/Rebrickable/Entity/Part.php index b899498..000446b 100644 --- a/src/AppBundle/Api/Client/Rebrickable/Entity/Part.php +++ b/src/AppBundle/Api/Client/Rebrickable/Entity/Part.php @@ -138,6 +138,7 @@ class Part { $this->name = $name; } + /** * @return mixed */ @@ -185,6 +186,7 @@ class Part { $this->category = $category; } + /** * @return mixed */ @@ -200,6 +202,7 @@ class Part { $this->colors = $colors; } + /** * @return mixed */ diff --git a/src/AppBundle/Api/Client/Rebrickable/Rebrickable.php b/src/AppBundle/Api/Client/Rebrickable/Rebrickable.php index f802e2c..03b412e 100644 --- a/src/AppBundle/Api/Client/Rebrickable/Rebrickable.php +++ b/src/AppBundle/Api/Client/Rebrickable/Rebrickable.php @@ -11,7 +11,7 @@ class Rebrickable { const BASE_URI = 'https://rebrickable.com/api/'; const FORMAT = 'json'; - + /** * @var Client */ @@ -21,7 +21,7 @@ class Rebrickable * @var string */ private $apiKey; - + /** * RebrickableAPI constructor. */ @@ -52,13 +52,12 @@ class Rebrickable throw new LogicException('Invalid API Key'); } elseif ($content === 'NOSET' || $content === 'NOPART') { return null; - } else { - return $content; } - } else { + + return $content; + } //TODO throw new LogicException($response->getStatusCode()); - } } catch (ConnectException $e) { //TODO throw new LogicException($e->getMessage()); diff --git a/src/AppBundle/Api/Manager/RebrickableManager.php b/src/AppBundle/Api/Manager/RebrickableManager.php index 11368a7..40ef01e 100644 --- a/src/AppBundle/Api/Manager/RebrickableManager.php +++ b/src/AppBundle/Api/Manager/RebrickableManager.php @@ -2,11 +2,11 @@ namespace AppBundle\Api\Manager; -use AppBundle\Api\Client\Rebrickable\Rebrickable; +use AppBundle\Api\Client\Rebrickable\Converter\PartPropertyNameConverter; use AppBundle\Api\Client\Rebrickable\Entity\Color; use AppBundle\Api\Client\Rebrickable\Entity\Part; use AppBundle\Api\Client\Rebrickable\Entity\Set; -use AppBundle\Api\Client\Rebrickable\Converter\PartPropertyNameConverter; +use AppBundle\Api\Client\Rebrickable\Rebrickable; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; @@ -33,10 +33,10 @@ class RebrickableManager private function getSerializer() { - $encoders = array(new JsonEncoder()); + $encoders = [new JsonEncoder()]; $nameConverter = new PartPropertyNameConverter(); $objectNormalizer = new ObjectNormalizer(null, $nameConverter); - $normalizers = array($objectNormalizer, new ArrayDenormalizer()); + $normalizers = [$objectNormalizer, new ArrayDenormalizer()]; $serializer = new Serializer($normalizers, $encoders); return $serializer; diff --git a/src/AppBundle/Command/LoadLibraryCommand.php b/src/AppBundle/Command/LoadLibraryCommand.php new file mode 100644 index 0000000..d96d211 --- /dev/null +++ b/src/AppBundle/Command/LoadLibraryCommand.php @@ -0,0 +1,43 @@ +setName('app:load:library') + ->setDescription('Loads LDraw library parts') + ->setHelp('This command allows you to..') + ->addArgument('ldraw', InputArgument::OPTIONAL, 'Path to LDraw library folder'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $ldrawLoader = $this->getContainer()->get('loader.ldraw'); + $ldrawLoader->setOutput($output); + + $rebrickableLoader = $this->getContainer()->get('loader.rebrickable'); + $rebrickableLoader->setOutput($output); + + try { + $ldrawLoader->loadModels($input->getArgument('ldraw')); + + $rebrickableLoader->loadColors(); + + $rebrickableLoader->loadParts(); + + $rebrickableLoader->loadBuildingKits(); + + $rebrickableLoader->loadPartBuildingKits(); + } catch (\Exception $e) { + printf($e->getMessage()); + } + } +} diff --git a/src/AppBundle/Command/LoadRebrickableCommand.php b/src/AppBundle/Command/LoadRebrickableCommand.php deleted file mode 100644 index 7e5ef0b..0000000 --- a/src/AppBundle/Command/LoadRebrickableCommand.php +++ /dev/null @@ -1,36 +0,0 @@ -setName('app:loadRebrickable') - ->setDescription('Loads Rebrickable csv data') - ->setHelp('This command allows you to..') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $modelLoader = $this->getContainer()->get('app.model_loader_service'); - - try { - $modelLoader->loadColors(); - - $modelLoader->loadParts($output); - - $modelLoader->loadBuildingKits($output); - - $modelLoader->loadPartBuildingKits($output); - } catch (\Exception $e) { - printf($e->getMessage()); - } - } -} diff --git a/src/AppBundle/Command/Loader/LDrawLoader.php b/src/AppBundle/Command/Loader/LDrawLoader.php new file mode 100644 index 0000000..92dc37f --- /dev/null +++ b/src/AppBundle/Command/Loader/LDrawLoader.php @@ -0,0 +1,187 @@ +em = $em; + $this->ldview = $ldview; + $this->dataPath = $dataPath; + $this->ldraw_url = $ldraw_url; + } + + public function downloadLibrary() + { + $this->output->writeln('Downloading set_pieces.csv from Rebrickable.com'); + $temp = $this->downloadFile($this->ldraw_url); + $temp_dir = tempnam(sys_get_temp_dir(), 'printabrick.'); + if (file_exists($temp_dir)) { + unlink($temp_dir); + } + mkdir($temp_dir); + $zip = new \ZipArchive(); + if ($zip->open($temp) != 'true') { + echo 'Error :- Unable to open the Zip File'; + } + $zip->extractTo($temp_dir); + $zip->close(); + unlink($temp); + + return $temp_dir; + } + + public function loadModels($LDrawLibrary) + { + //TODO Refactor, use flysystem + $adapter = new Local(getcwd().DIRECTORY_SEPARATOR.$LDrawLibrary); + $this->ldraw = new Filesystem($adapter); +// $files = $this->ldraw->get('parts')->getContents(); + + $finder = new Finder(); + $files = $finder->files()->name('*.dat')->depth('== 0')->in(getcwd().DIRECTORY_SEPARATOR.$LDrawLibrary.DIRECTORY_SEPARATOR.'parts'); + + $progressBar = new ProgressBar($this->output, $files->count()); + $progressBar->setFormat('very_verbose'); + $progressBar->setMessage('Loading LDraw library models'); + $progressBar->setFormat('%message:6s% %current%/%max% [%bar%]%percent:3s%% (%elapsed:6s%/%estimated:-6s%)'); + $progressBar->start(); + foreach ($files as $file) { + $model = $this->loadPartHeader($file); + $model->setFile($this->createStlFile($file)->getPath()); + + $this->em->persist($model); + $this->em->flush(); + + $progressBar->advance(); + } + $progressBar->finish(); + } + + /** + * @param SplFileInfo $file + * + * @return Model + */ + private function loadPartHeader($file) + { + $handle = fopen($file->getRealPath(), 'r'); + if ($handle) { + $firstLine = false; + + $model = new Model(); + + // read lines while line starts with 0 or is empty + while (($line = trim(fgets($handle))) !== false && ($line ? $line[0] == '0' : true)) { + if ($line !== '') { + $line = preg_replace('/^0 /', '', $line); + + // 0 + if (!$firstLine) { + //TODO handle "~Moved to" + //TODO "=" - alias name for other part kept for referece + //TODO "_" shortcut + + $array = explode(' ', trim($line), 2); + $category = isset($array[0]) ? $array[0] : ''; + $model->setName($line); + + $firstLine = true; + } + // 0 !CATEGORY + elseif (strpos($line, '!CATEGORY ') === 0) { + $category = trim(preg_replace('/^!CATEGORY /', '', $line)); + } + // 0 !KEYWORDS , , ..., + elseif (strpos($line, '!KEYWORDS ') === 0) { + $keywords = explode(', ', preg_replace('/^!KEYWORDS /', '', $line)); + } + // 0 Name: .dat + elseif (strpos($line, 'Name: ') === 0) { + $model->setNumber(preg_replace('/(^Name: )(.*)(.dat)/', '$2', $line)); + } + // 0 Author: [] + elseif (strpos($line, 'Author: ') === 0) { + $model->setAuthor(preg_replace('/^Author: /', '', $line)); + } + } + } + + $cat = $this->em->getRepository('AppBundle:Category')->findOneBy(['name' => $category]); + if ($cat == null) { + $cat = new Category(); + $cat->setName($category); + } + + $model->setCategory($cat); + $cat->addModel($model); + } else { + throw new LogicException('loadHeader error'); //TODO + } + fclose($handle); + + return $model; + } + + /** + * @param SplFileInfo $file + * + * @return \League\Flysystem\File + */ + private function createStlFile($file) + { + $stlFilename = str_replace('.dat', '.stl', $file->getFilename()); + + if (!$this->dataPath->has($stlFilename)) { + $builder = new ProcessBuilder(); + $process = $builder + ->setPrefix($this->ldview) + ->setArguments([ +// $this->ldraw->getAdapter()->getPathPrefix().$file['path'], + $file->getRealPath(), + '-LDrawDir='.$this->ldraw->getAdapter()->getPathPrefix(), + '-ExportFile='.$this->dataPath->getAdapter()->getPathPrefix().$stlFilename, + ]) + ->getProcess(); + + $process->run(); + + if (!$process->isSuccessful() || !$this->dataPath->has($stlFilename)) { + throw new LogicException($file->getFilename().' : '.$process->getOutput()); //TODO + } + } + + return $this->dataPath->get($stlFilename); + } +} diff --git a/src/AppBundle/Command/Loader/Loader.php b/src/AppBundle/Command/Loader/Loader.php new file mode 100644 index 0000000..f0f2622 --- /dev/null +++ b/src/AppBundle/Command/Loader/Loader.php @@ -0,0 +1,72 @@ +output = $output; + $this->output->setDecorated(true); + } + + private function progressCallback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) + { + switch ($notification_code) { + case STREAM_NOTIFY_FILE_SIZE_IS: + $this->progressBar = new ProgressBar($this->output); + $this->progressBar->setBarWidth(100); + $this->progressBar->start($bytes_max); + break; + case STREAM_NOTIFY_PROGRESS: + $this->progressBar->setProgress($bytes_transferred); + break; + case STREAM_NOTIFY_COMPLETED: + $this->progressBar->setProgress($bytes_transferred); + $this->progressBar->finish(); + break; + } + } + + protected function downloadFile($url) + { + $temp = tempnam(sys_get_temp_dir(), 'printabrick.'); + + $ctx = stream_context_create([], [ + 'notification' => [$this, 'progressCallback'], + ]); + + try { + if (false === file_put_contents($temp, fopen($url, 'r', 0, $ctx))) { + throw new LogicException('error writing file'); //TODO + } + } catch (ContextErrorException $e) { + throw new LogicException('wrong url'); //TODO + } catch (\Exception $e) { + throw new LogicException('exception: '.$e->getMessage()); //TODO + } + + return $temp; + } +} diff --git a/src/AppBundle/Service/ModelLoaderService.php b/src/AppBundle/Command/Loader/RebrickableLoader.php similarity index 60% rename from src/AppBundle/Service/ModelLoaderService.php rename to src/AppBundle/Command/Loader/RebrickableLoader.php index 8fd3d81..2009394 100644 --- a/src/AppBundle/Service/ModelLoaderService.php +++ b/src/AppBundle/Command/Loader/RebrickableLoader.php @@ -1,114 +1,53 @@ STLlib = $STLlib; $this->em = $em; $this->rebrickableManager = $rebrickableManager; + $this->rebrickable_url = $rebrickable_url; } - // LDraw - - public function loadModels($LDrawLibrary) + public function loadPartBuildingKits() { - $finder = new Finder(); - $files = $finder->files()->name('*.dat')->depth('== 0')->in(getcwd().'/'.$LDrawLibrary.'/parts'); + $this->output->writeln('Downloading set_pieces.csv from Rebrickable.com'); + $file = $this->downloadFile('compress.zlib://'.$this->rebrickable_url['set_pieces']); - foreach ($files as $file) { - $this->loadModelHeader($file); - } - } - - private function loadModelHeader(SplFileInfo $fileInfo) - { - $handle = fopen($fileInfo->getRealPath(), 'r'); - if ($handle) { - $firstLine = fgets($handle); - $description = trim(substr($firstLine, 2)); - $model = new Model(); - $model->setFile($fileInfo->getFilename()); - $p['category'] = explode(' ', trim($description))[0]; - - //TODO handle ~Moved to - - while (!feof($handle)) { - $line = trim(fgets($handle)); - if ($line && ($line[0] == '1')) { - break; - } elseif ($line && ($line[0] == '0' && strpos($line, '!CATEGORY '))) { - $p['category'] = trim(explode('!CATEGORY ', $line)[1]); - } elseif ($line && ($line[0] == '0' && strpos($line, '!KEYWORDS '))) { - $keywords = explode(',', explode('!KEYWORDS ', $line)[1]); - foreach ($keywords as $k) { - $p['keywords'][] = trim($k); - } - } elseif ($line && ($line[0] == '0' && strpos($line, 'Name: '))) { - $model->setNumber(trim(explode('.dat', explode('Name: ', $line)[1])[0])); - } elseif ($line && ($line[0] == '0' && strpos($line, 'Author: '))) { - $model->setAuthor(explode('Author: ', $line)[1]); - } - } - - $this->em->persist($model); - $this->em->flush(); - } else { - throw new LogicException('loadHeader error'); //TODO - } - fclose($handle); - } - - // Rebrickable - - public function loadPartBuildingKits($output) - { $partRepository = $this->em->getRepository('AppBundle:Part'); $buldingKitRepository = $this->em->getRepository('AppBundle:BuildingKit'); $colorRepository = $this->em->getRepository('AppBundle:Color'); - $setPieces = tempnam(sys_get_temp_dir(), 'printabrick.'); - file_put_contents($setPieces, fopen('compress.zlib://http://rebrickable.com/files/set_pieces.csv.gz', 'r')); - $this->em->getConnection()->getConfiguration()->setSQLLogger(null); - if (($handle = fopen($setPieces, 'r')) !== false) { + $this->output->writeln('Loading set_pieces.csv into Database'); + if (($handle = fopen($file, 'r')) !== false) { $header = fgetcsv($handle, 200, ','); // create a new progress bar (50 units) - $progress = new ProgressBar($output, intval(exec("wc -l '$setPieces'"))); + $progress = new ProgressBar($this->output, intval(exec("wc -l '$file'"))); //TODO replace wc-l $progress->setFormat('very_verbose'); $progress->setBarWidth(50); $progress->start(); @@ -144,26 +83,26 @@ class ModelLoaderService $this->em->clear(); fclose($handle); $progress->finish(); - $progress->clear(); } - unlink($setPieces); + unlink($file); } - public function loadBuildingKits($output) + public function loadBuildingKits() { - $keywordRepository = $this->em->getRepository('AppBundle:Keyword'); + $this->output->writeln('Downloading sets.csv from Rebrickable.com'); + $file = $this->downloadFile('compress.zlib://'.$this->rebrickable_url['sets']); - $sets = tempnam(sys_get_temp_dir(), 'printabrick.'); - file_put_contents($sets, fopen('compress.zlib://http://rebrickable.com/files/sets.csv.gz', 'r')); + $keywordRepository = $this->em->getRepository('AppBundle:Keyword'); $this->em->getConnection()->getConfiguration()->setSQLLogger(null); - if (($handle = fopen($sets, 'r')) !== false) { + $this->output->writeln('Loading sets.csv into Database'); + if (($handle = fopen($file, 'r')) !== false) { $header = fgetcsv($handle, 500, ','); // create a new progress bar (50 units) - $progress = new ProgressBar($output, intval(exec("wc -l '$sets'"))); + $progress = new ProgressBar($this->output, intval(exec("wc -l '$file'"))); //TODO replace wc-l $progress->setFormat('very_verbose'); $progress->setBarWidth(50); $progress->start(); @@ -206,24 +145,23 @@ class ModelLoaderService fclose($handle); $progress->finish(); - $progress->clear(); } - unlink($sets); + unlink($file); } - public function loadParts($output) + public function loadParts() { - $pieces = tempnam(sys_get_temp_dir(), 'printabrick.'); - file_put_contents($pieces, fopen('compress.zlib://http://rebrickable.com/files/pieces.csv.gz', 'r')); + $this->output->writeln('Downloading pieces.csv from Rebrickable.com'); + $file = $this->downloadFile('compress.zlib://'.$this->rebrickable_url['pieces']); $categoryRepository = $this->em->getRepository('AppBundle:Category'); $this->em->getConnection()->getConfiguration()->setSQLLogger(null); - if (($handle = fopen($pieces, 'r')) !== false) { - + $this->output->writeln('Loading pieces.csv into Database'); + if (($handle = fopen($file, 'r')) !== false) { // create a new progress bar (50 units) - $progress = new ProgressBar($output, intval(exec("wc -l '$pieces'"))); + $progress = new ProgressBar($this->output, intval(exec("wc -l '$file'"))); //TODO replace wc-l $progress->setFormat('very_verbose'); $progress->setBarWidth(50); $progress->start(); @@ -256,14 +194,15 @@ class ModelLoaderService fclose($handle); $progress->finish(); - $progress->clear(); } - unlink($pieces); + unlink($file); } public function loadColors() { + $this->output->writeln('Loading colors into Database'); + $rb_colors = $this->rebrickableManager->getColors(); foreach ($rb_colors as $rb_color) { @@ -283,10 +222,10 @@ class ModelLoaderService { $modelRepository = $this->em->getRepository('AppBundle:Model'); - if (strpos($part->getNumber(), 'p')) { + $model = $modelRepository->findOneBy(['number' => $part->getNumber()]); + + if (!$model && strpos($part->getNumber(), 'p')) { $model = $modelRepository->findOneBy(['number' => explode('p', $part->getNumber())[0]]); - } else { - $model = $modelRepository->findOneBy(['number' => $part->getNumber()]); } return $model; diff --git a/src/AppBundle/Controller/DefaultController.php b/src/AppBundle/Controller/DefaultController.php index 5216afe..36ea5c0 100644 --- a/src/AppBundle/Controller/DefaultController.php +++ b/src/AppBundle/Controller/DefaultController.php @@ -13,9 +13,7 @@ class DefaultController extends Controller */ public function indexAction(Request $request) { - // replace this example code with whatever you need return $this->render('default/index.html.twig', [ - 'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR, ]); } } diff --git a/src/AppBundle/Controller/DownloadController.php b/src/AppBundle/Controller/DownloadController.php new file mode 100644 index 0000000..3447bcb --- /dev/null +++ b/src/AppBundle/Controller/DownloadController.php @@ -0,0 +1,43 @@ +get('oneup_flysystem.ldraw_filesystem'); + + if ($ldraw_filesystem->has($model->getFile())) { + $response = new BinaryFileResponse($ldraw_filesystem->getAdapter()->getPathPrefix().$model->getFile()); + $response->headers->set('Content-Type', 'application/vnd.ms-pki.stl'); + + // Create the disposition of the file + $disposition = $response->headers->makeDisposition( + ResponseHeaderBag::DISPOSITION_ATTACHMENT, + $model->getFile() + ); + + $response->headers->set('Content-Disposition', $disposition); + + return $response; + } + throw new FileNotFoundException($model->getFile()); + } +} diff --git a/src/AppBundle/Controller/PartController.php b/src/AppBundle/Controller/PartController.php new file mode 100644 index 0000000..cfff17f --- /dev/null +++ b/src/AppBundle/Controller/PartController.php @@ -0,0 +1,28 @@ +get('manager.rebrickable')->getPart($id); + + $em = $this->getDoctrine()->getManager(); + $localPart = $em->getRepository('AppBundle:Part')->findOneBy(['number' => $id]); + + return $this->render('part/detail.html.twig', [ + 'part' => $part, + 'localPart' => $localPart, + ]); + } +} diff --git a/src/AppBundle/Controller/PartsController.php b/src/AppBundle/Controller/PartsController.php deleted file mode 100644 index 07c9b1c..0000000 --- a/src/AppBundle/Controller/PartsController.php +++ /dev/null @@ -1,24 +0,0 @@ -get('manager.rebrickable')->getPartById($id); - - return $this->render('parts/detail.html.twig', [ - 'part' => $part, - ]); - } -} \ No newline at end of file diff --git a/src/AppBundle/Controller/SetsController.php b/src/AppBundle/Controller/SetController.php similarity index 72% rename from src/AppBundle/Controller/SetsController.php rename to src/AppBundle/Controller/SetController.php index d4109e2..7679e3b 100644 --- a/src/AppBundle/Controller/SetsController.php +++ b/src/AppBundle/Controller/SetController.php @@ -8,12 +8,12 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; /** - * @Route("/brickset/sets") + * @Route("/brickset/set") */ -class SetsController extends Controller +class SetController extends Controller { /** - * @Route("/", name="sets_browse") + * @Route("/", name="set_browse") */ public function browseAction(Request $request) { @@ -32,7 +32,7 @@ class SetsController extends Controller ]); } - return $this->render('sets/browse.html.twig', [ + return $this->render('set/browse.html.twig', [ 'form' => $form->createView(), 'sets' => $sets, ]); @@ -43,13 +43,10 @@ class SetsController extends Controller */ public function detailAction(Request $request, $id, $name = null) { - $set = $this->get('manager.brickset')->getSetById($id);; + $set = $this->get('manager.brickset')->getSetById($id); - $parts = $this->get('app.collection_service')->getSet($set->getNumber().'-'.$set->getNumberVariant())->getParts(); - - return $this->render('sets/detail.html.twig', [ + return $this->render('set/detail.html.twig', [ 'set' => $set, - 'parts' => $parts, ]); } } diff --git a/src/AppBundle/Entity/BuildingKit.php b/src/AppBundle/Entity/BuildingKit.php index 2eed090..b6ee8ef 100644 --- a/src/AppBundle/Entity/BuildingKit.php +++ b/src/AppBundle/Entity/BuildingKit.php @@ -7,7 +7,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** - * BuildingKit + * BuildingKit. * * @ORM\Table(name="building_kit") * @ORM\Entity(repositoryClass="AppBundle\Repository\BuildingKitRepository") @@ -74,9 +74,8 @@ class BuildingKit $this->keywords = new ArrayCollection(); } - /** - * Get id + * Get id. * * @return int */ @@ -105,9 +104,8 @@ class BuildingKit return $this; } - /** - * Set name + * Set name. * * @param string $name * @@ -121,7 +119,7 @@ class BuildingKit } /** - * Get name + * Get name. * * @return string */ @@ -131,9 +129,9 @@ class BuildingKit } /** - * Set year + * Set year. * - * @param integer $year + * @param int $year * * @return BuildingKit */ @@ -145,7 +143,7 @@ class BuildingKit } /** - * Get year + * Get year. * * @return int */ @@ -175,7 +173,7 @@ class BuildingKit } /** - * Get parts + * Get parts. * * @return Collection */ @@ -209,7 +207,7 @@ class BuildingKit } /** - * Get keywords + * Get keywords. * * @return Collection */ diff --git a/src/AppBundle/Entity/Category.php b/src/AppBundle/Entity/Category.php index 636ed55..10be5c7 100644 --- a/src/AppBundle/Entity/Category.php +++ b/src/AppBundle/Entity/Category.php @@ -5,10 +5,9 @@ namespace AppBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -use Symfony\Component\Form\CallbackTransformer; /** - * Category + * Category. * * @ORM\Table(name="category") * @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository") @@ -54,9 +53,8 @@ class Category $this->parts = new ArrayCollection(); } - /** - * Get id + * Get id. * * @return int */ @@ -66,7 +64,7 @@ class Category } /** - * Set name + * Set name. * * @param string $name * @@ -80,7 +78,7 @@ class Category } /** - * Get name + * Get name. * * @return string */ @@ -90,7 +88,7 @@ class Category } /** - * Get models + * Get models. * * @return ArrayCollection */ @@ -124,7 +122,7 @@ class Category } /** - * Get parts + * Get parts. * * @return ArrayCollection */ diff --git a/src/AppBundle/Entity/Color.php b/src/AppBundle/Entity/Color.php index 18d41c8..abd6547 100644 --- a/src/AppBundle/Entity/Color.php +++ b/src/AppBundle/Entity/Color.php @@ -6,7 +6,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** - * Color + * Color. * * @ORM\Table(name="color") * @ORM\Entity(repositoryClass="AppBundle\Repository\ColorRepository") @@ -43,7 +43,7 @@ class Color private $part_building_kits; /** - * Set id + * Set id. * * @var int * @@ -57,7 +57,7 @@ class Color } /** - * Get id + * Get id. * * @return int */ @@ -67,7 +67,7 @@ class Color } /** - * Set name + * Set name. * * @param string $name * @@ -81,7 +81,7 @@ class Color } /** - * Get name + * Get name. * * @return string */ @@ -91,7 +91,7 @@ class Color } /** - * Set rgb + * Set rgb. * * @param string $rgb * @@ -105,7 +105,7 @@ class Color } /** - * Get rgb + * Get rgb. * * @return string */ @@ -123,7 +123,6 @@ class Color } /** - * * @param Part_BuildingKit $part_building_kit * * @return Color @@ -148,11 +147,10 @@ class Color } /** - * Constructor + * Constructor. */ public function __construct() { $this->part_building_kits = new \Doctrine\Common\Collections\ArrayCollection(); } - } diff --git a/src/AppBundle/Entity/Keyword.php b/src/AppBundle/Entity/Keyword.php index 7b40e3e..f35ebba 100644 --- a/src/AppBundle/Entity/Keyword.php +++ b/src/AppBundle/Entity/Keyword.php @@ -6,7 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; /** - * Keyword + * Keyword. * * @ORM\Table(name="keyword") * @ORM\Entity(repositoryClass="AppBundle\Repository\KeywordRepository") @@ -44,9 +44,8 @@ class Keyword $this->building_kits = new ArrayCollection(); } - /** - * Get id + * Get id. * * @return int */ @@ -56,7 +55,7 @@ class Keyword } /** - * Set name + * Set name. * * @param string $name * @@ -70,7 +69,7 @@ class Keyword } /** - * Get name + * Get name. * * @return string */ @@ -110,5 +109,4 @@ class Keyword return $this; } - } diff --git a/src/AppBundle/Entity/Model.php b/src/AppBundle/Entity/Model.php index 87e5cc0..b88c5d6 100644 --- a/src/AppBundle/Entity/Model.php +++ b/src/AppBundle/Entity/Model.php @@ -6,7 +6,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** - * Model + * Model. * * @ORM\Table(name="model") * @ORM\Entity(repositoryClass="AppBundle\Repository\ModelRepository") @@ -22,6 +22,12 @@ class Model */ private $id; + /** + * @var string + * + * @ORM\Column(name="name", type="string", length=255, nullable=true) + */ + private $name; /** * @var string * @@ -53,13 +59,12 @@ class Model /** * @var Category * - * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="models") + * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category", inversedBy="models", cascade={"persist"}) */ private $category; - /** - * Get id + * Get id. * * @return int */ @@ -69,7 +74,23 @@ class Model } /** - * Set number + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Set number. * * @param string $number * @@ -83,7 +104,7 @@ class Model } /** - * Get number + * Get number. * * @return string */ @@ -93,7 +114,7 @@ class Model } /** - * Set author + * Set author. * * @param string $author * @@ -107,7 +128,7 @@ class Model } /** - * Get author + * Get author. * * @return string */ @@ -117,7 +138,7 @@ class Model } /** - * Set file + * Set file. * * @param string $file * @@ -131,7 +152,7 @@ class Model } /** - * Get file + * Get file. * * @return string */ @@ -141,7 +162,7 @@ class Model } /** - * Get parts + * Get parts. * * @return Collection */ @@ -175,7 +196,7 @@ class Model } /** - * Set category + * Set category. * * @param Category $category * @@ -190,7 +211,7 @@ class Model } /** - * Get category + * Get category. * * @return Category */ diff --git a/src/AppBundle/Entity/Part_BuildingKit.php b/src/AppBundle/Entity/Part_BuildingKit.php index 2133246..3703ef4 100644 --- a/src/AppBundle/Entity/Part_BuildingKit.php +++ b/src/AppBundle/Entity/Part_BuildingKit.php @@ -2,11 +2,10 @@ namespace AppBundle\Entity; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; /** - * Part_BuildingKit + * Part_BuildingKit. * * @ORM\Table(name="part__building_kit") * @ORM\Entity(repositoryClass="AppBundle\Repository\Part_BuildingKitRepository") @@ -57,9 +56,8 @@ class Part_BuildingKit */ private $building_kit; - /** - * Get id + * Get id. * * @return int */ @@ -69,9 +67,9 @@ class Part_BuildingKit } /** - * Set count + * Set count. * - * @param integer $count + * @param int $count * * @return Part_BuildingKit */ @@ -83,7 +81,7 @@ class Part_BuildingKit } /** - * Get count + * Get count. * * @return int */ @@ -93,7 +91,7 @@ class Part_BuildingKit } /** - * Set color + * Set color. * * @param Color $color * @@ -107,7 +105,7 @@ class Part_BuildingKit } /** - * Get color + * Get color. * * @return Color */ @@ -117,9 +115,9 @@ class Part_BuildingKit } /** - * Set type + * Set type. * - * @param boolean $type + * @param bool $type * * @return Part_BuildingKit */ @@ -131,7 +129,7 @@ class Part_BuildingKit } /** - * Get type + * Get type. * * @return bool */ @@ -181,6 +179,4 @@ class Part_BuildingKit return $this; } - - } diff --git a/src/AppBundle/Form/FilterSetType.php b/src/AppBundle/Form/FilterSetType.php index 1e68eaa..50f57e2 100644 --- a/src/AppBundle/Form/FilterSetType.php +++ b/src/AppBundle/Form/FilterSetType.php @@ -26,36 +26,35 @@ class FilterSetType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add("theme", ChoiceType::class, [ + ->add('theme', ChoiceType::class, [ 'choices' => $this->bricksetManager->getThemes(), - 'choice_label' => function(Theme $theme = null) { + 'choice_label' => function (Theme $theme = null) { return $theme ? $theme->getTheme().' ('.$theme->getSetCount().')' : ''; }, 'placeholder' => '', - 'required' => false - + 'required' => false, ]); $formModifier = function (Form $form, Theme $theme = null) { $subthemes = null === $theme ? [] : $this->bricksetManager->getSubthemesByTheme($theme); $years = null === $theme ? [] : $this->bricksetManager->getYearsByTheme($theme); - $form->add("subtheme", ChoiceType::class, [ + $form->add('subtheme', ChoiceType::class, [ 'choices' => $subthemes, - 'choice_label' => function(Subtheme $subtheme = null) { + 'choice_label' => function (Subtheme $subtheme = null) { return $subtheme ? $subtheme->getSubtheme() : ''; }, 'placeholder' => '', - 'required' => false + 'required' => false, ]); - $form->add("years", ChoiceType::class, [ + $form->add('years', ChoiceType::class, [ 'choices' => $years, - 'choice_label' => function(Year $year = null) { + 'choice_label' => function (Year $year = null) { return $year ? $year->getYear() : ''; }, 'placeholder' => '', - 'required' => false + 'required' => false, ]); }; @@ -76,6 +75,6 @@ class FilterSetType extends AbstractType } ); - $builder->add('submit',SubmitType::class); + $builder->add('submit', SubmitType::class); } -} \ No newline at end of file +} diff --git a/src/AppBundle/Menu/Builder.php b/src/AppBundle/Menu/Builder.php index e22ca9b..b78814e 100644 --- a/src/AppBundle/Menu/Builder.php +++ b/src/AppBundle/Menu/Builder.php @@ -15,7 +15,7 @@ class Builder ]); $menu->addChild('Sets', [ - 'route' => 'sets_browse', + 'route' => 'set_browse', ]); return $menu; diff --git a/src/AppBundle/Repository/BuildingKitRepository.php b/src/AppBundle/Repository/BuildingKitRepository.php index e5eaa81..5cf0efe 100644 --- a/src/AppBundle/Repository/BuildingKitRepository.php +++ b/src/AppBundle/Repository/BuildingKitRepository.php @@ -5,7 +5,7 @@ namespace AppBundle\Repository; use AppBundle\Entity\Part; /** - * BuildingSetRepository + * BuildingSetRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. diff --git a/src/AppBundle/Repository/CategoryRepository.php b/src/AppBundle/Repository/CategoryRepository.php index adfdee4..6b9fe2b 100644 --- a/src/AppBundle/Repository/CategoryRepository.php +++ b/src/AppBundle/Repository/CategoryRepository.php @@ -2,10 +2,8 @@ namespace AppBundle\Repository; -use AppBundle\Entity\Category; - /** - * CategoryRepository + * CategoryRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. diff --git a/src/AppBundle/Repository/ColorRepository.php b/src/AppBundle/Repository/ColorRepository.php index 7370126..5874460 100644 --- a/src/AppBundle/Repository/ColorRepository.php +++ b/src/AppBundle/Repository/ColorRepository.php @@ -3,7 +3,7 @@ namespace AppBundle\Repository; /** - * ColorRepository + * ColorRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. diff --git a/src/AppBundle/Repository/KeywordRepository.php b/src/AppBundle/Repository/KeywordRepository.php index c559947..8a2e4e0 100644 --- a/src/AppBundle/Repository/KeywordRepository.php +++ b/src/AppBundle/Repository/KeywordRepository.php @@ -3,7 +3,7 @@ namespace AppBundle\Repository; /** - * KeywordRepository + * KeywordRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. diff --git a/src/AppBundle/Repository/ModelRepository.php b/src/AppBundle/Repository/ModelRepository.php index 49907f3..10611e0 100644 --- a/src/AppBundle/Repository/ModelRepository.php +++ b/src/AppBundle/Repository/ModelRepository.php @@ -3,7 +3,7 @@ namespace AppBundle\Repository; /** - * ModelRepository + * ModelRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. diff --git a/src/AppBundle/Repository/PartRepository.php b/src/AppBundle/Repository/PartRepository.php index 2fdb597..334bc3b 100644 --- a/src/AppBundle/Repository/PartRepository.php +++ b/src/AppBundle/Repository/PartRepository.php @@ -3,7 +3,7 @@ namespace AppBundle\Repository; /** - * PartRepository + * PartRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. diff --git a/src/AppBundle/Repository/Part_BuildingKitRepository.php b/src/AppBundle/Repository/Part_BuildingKitRepository.php index 19c6347..4d6a820 100644 --- a/src/AppBundle/Repository/Part_BuildingKitRepository.php +++ b/src/AppBundle/Repository/Part_BuildingKitRepository.php @@ -3,7 +3,7 @@ namespace AppBundle\Repository; /** - * Part_BuildingKitRepository + * Part_BuildingKitRepository. * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below.