1
0
mirror of https://github.com/ToxicCrack/PrintABrick.git synced 2025-05-20 22:20:08 -07:00

Merged branch feat/ldraw-loader into dev

This commit is contained in:
David Hübner 2017-01-21 23:35:19 +01:00
commit 0b589ba2ca
49 changed files with 1147 additions and 899 deletions

1
.gitignore vendored
View File

@ -18,3 +18,4 @@
/node_modules/
/app/Resources/assets/semantic/dist
/web/resources/
.php_cs.cache

18
.php_cs Normal file
View File

@ -0,0 +1,18 @@
<?php
$finder = PhpCsFixer\Finder::create()
->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);

View File

@ -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
####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`

View File

@ -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)) {

View File

@ -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);
};
};

View File

@ -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 ];
}
};
}

View File

@ -1,76 +1,6 @@
{% extends 'base.html.twig' %}
{% block body %}
<div id="wrapper">
<div id="container">
<div id="welcome">
<h1><span>Welcome to</span> Symfony {{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION') }}</h1>
</div>
<div id="status">
<p>
<svg id="icon-status" width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68z" fill="#759E1A"/></svg>
Your application is now ready. You can start working on it at:
<code>{{ base_dir }}</code>
</p>
</div>
<div id="next">
<h2>What's next?</h2>
<p>
<svg id="icon-book" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="-12.5 9 64 64" enable-background="new -12.5 9 64 64" xml:space="preserve">
<path fill="#AAA" d="M6.8,40.8c2.4,0.8,4.5-0.7,4.9-2.5c0.2-1.2-0.3-2.1-1.3-3.2l-0.8-0.8c-0.4-0.5-0.6-1.3-0.2-1.9
c0.4-0.5,0.9-0.8,1.8-0.5c1.3,0.4,1.9,1.3,2.9,2.2c-0.4,1.4-0.7,2.9-0.9,4.2l-0.2,1c-0.7,4-1.3,6.2-2.7,7.5
c-0.3,0.3-0.7,0.5-1.3,0.6c-0.3,0-0.4-0.3-0.4-0.3c0-0.3,0.2-0.3,0.3-0.4c0.2-0.1,0.5-0.3,0.4-0.8c0-0.7-0.6-1.3-1.3-1.3
c-0.6,0-1.4,0.6-1.4,1.7s1,1.9,2.4,1.8c0.8,0,2.5-0.3,4.2-2.5c2-2.5,2.5-5.4,2.9-7.4l0.5-2.8c0.3,0,0.5,0.1,0.8,0.1
c2.4,0.1,3.7-1.3,3.7-2.3c0-0.6-0.3-1.2-0.9-1.2c-0.4,0-0.8,0.3-1,0.8c-0.1,0.6,0.8,1.1,0.1,1.5c-0.5,0.3-1.4,0.6-2.7,0.4l0.3-1.3
c0.5-2.6,1-5.7,3.2-5.8c0.2,0,0.8,0,0.8,0.4c0,0.2,0,0.2-0.2,0.5c-0.2,0.3-0.3,0.4-0.2,0.7c0,0.7,0.5,1.1,1.2,1.1
c0.9,0,1.2-1,1.2-1.4c0-1.2-1.2-1.8-2.6-1.8c-1.5,0.1-2.8,0.9-3.7,2.1c-1.1,1.3-1.8,2.9-2.3,4.5c-0.9-0.8-1.6-1.8-3.1-2.3
c-1.1-0.7-2.3-0.5-3.4,0.3c-0.5,0.4-0.8,1-1,1.6c-0.4,1.5,0.4,2.9,0.8,3.4l0.9,1c0.2,0.2,0.6,0.8,0.4,1.5c-0.3,0.8-1.2,1.3-2.1,1
c-0.4-0.2-1-0.5-0.9-0.9c0.1-0.2,0.2-0.3,0.3-0.5s0.1-0.3,0.1-0.3c0.2-0.6-0.1-1.4-0.7-1.6c-0.6-0.2-1.2,0-1.3,0.8
C4.3,38.4,4.7,40,6.8,40.8z M46.1,20.9c0-4.2-3.2-7.5-7.1-7.5h-3.8C34.8,10.8,32.7,9,30.2,9L-2.3,9.1c-2.8,0.1-4.9,2.4-4.9,5.4
L-7,58.6c0,4.8,8.1,13.9,11.6,14.1l34.7-0.1c3.9,0,7-3.4,7-7.6L46.1,20.9z M-0.3,36.4c0-8.6,6.5-15.6,14.5-15.6
c8,0,14.5,7,14.5,15.6S22.1,52,14.2,52C6.1,52-0.3,45-0.3,36.4z M42.1,65.1c0,1.8-1.5,3.1-3.1,3.1H4.6c-0.7,0-3-1.8-4.5-4.4h30.4
c2.8,0,5-2.4,5-5.4V17.9h3.7c1.6,0,2.9,1.4,2.9,3.1V65.1L42.1,65.1z"/>
</svg>
Read the documentation to learn
<a href="http://symfony.com/doc/{{ constant('Symfony\\Component\\HttpKernel\\Kernel::VERSION')[:3] }}/book/page_creation.html">
How to create your first page in Symfony
</a>
</p>
</div>
</div>
</div>
{% endblock %}
{% block stylesheets %}
<style>
body { background: #F5F5F5; font: 18px/1.5 sans-serif; }
h1, h2 { line-height: 1.2; margin: 0 0 .5em; }
h1 { font-size: 36px; }
h2 { font-size: 21px; margin-bottom: 1em; }
p { margin: 0 0 1em 0; }
a { color: #0000F0; }
a:hover { text-decoration: none; }
code { background: #F5F5F5; max-width: 100px; padding: 2px 6px; word-wrap: break-word; }
#wrapper { background: #FFF; margin: 1em auto; max-width: 800px; width: 95%; }
#container { padding: 2em; }
#welcome, #status { margin-bottom: 2em; }
#welcome h1 span { display: block; font-size: 75%; }
#icon-status, #icon-book { float: left; height: 64px; margin-right: 1em; margin-top: -4px; width: 64px; }
#icon-book { display: none; }
@media (min-width: 768px) {
#wrapper { width: 80%; margin: 2em auto; }
#icon-book { display: inline-block; }
#status a, #next a { display: block; }
@-webkit-keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
@keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
.sf-toolbar { opacity: 0; -webkit-animation: fade-in 1s .2s forwards; animation: fade-in 1s .2s forwards;}
}
</style>
{% endblock %}

View File

@ -0,0 +1,33 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ dump(part) }}
{{ dump(localPart) }}
<div id="model" style="height: 300px; width: 300px; padding: 5px; display: inline-block"></div>
<img src="{{ part.partImgUrl }}">
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script type="text/javascript" src="{{ asset('resources/js/three.js') }}"></script>
<script type="text/javascript" src="{{ asset('resources/js/OrbitControls.js') }}"></script>
<script type="text/javascript" src="{{ asset('resources/js/ModelViewer.js') }}"></script>
<script type="text/javascript">
window.onload = function() {
modelView = new ModelViewer();
modelView.init('model');
{% if localPart.model is defined %}
modelView.loadStl('{{ path('download_model', {'id' : localPart.model.id })}}');
{% endif %}
modelView.render();
};
</script>
{% endblock %}

View File

@ -1,7 +0,0 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ dump(part) }}
{% endblock %}

View File

@ -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
default_renderer: twig
oneup_flysystem:
adapters:
ldraw_adapter:
local:
directory: "%kernel.root_dir%/../var/data/ldraw"
filesystems:
ldraw:
adapter: ldraw_adapter

View File

@ -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

BIN
bin/ldview Normal file

Binary file not shown.

30
bin/php-cs-fixer-hook.sh Normal file
View File

@ -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"

View File

@ -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": [

418
composer.lock generated
View File

@ -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": [],

View File

@ -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'));

View File

@ -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;
}
/**

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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
*/

View File

@ -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());

View File

@ -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;

View File

@ -0,0 +1,43 @@
<?php
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class LoadLibraryCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->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());
}
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class LoadRebrickableCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->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());
}
}
}

View File

@ -0,0 +1,187 @@
<?php
namespace AppBundle\Command\Loader;
use AppBundle\Entity\Category;
use AppBundle\Entity\Model;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
use Symfony\Component\Asset\Exception\LogicException;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Symfony\Component\Process\ProcessBuilder;
class LDrawLoader extends Loader
{
/**
* @var string LDView binary file path
*/
private $ldview;
/**
* @var Filesystem
*/
private $ldraw;
/**
* @var \League\Flysystem\Filesystem
*/
private $dataPath;
private $ldraw_url;
public function __construct($em, $ldview, $dataPath, $ldraw_url)
{
/*
* @var $em EntityManager
* */
$this->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 <CategoryName> <PartDescription>
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 <CategoryName>
elseif (strpos($line, '!CATEGORY ') === 0) {
$category = trim(preg_replace('/^!CATEGORY /', '', $line));
}
// 0 !KEYWORDS <first keyword>, <second keyword>, ..., <last keyword>
elseif (strpos($line, '!KEYWORDS ') === 0) {
$keywords = explode(', ', preg_replace('/^!KEYWORDS /', '', $line));
}
// 0 Name: <Filename>.dat
elseif (strpos($line, 'Name: ') === 0) {
$model->setNumber(preg_replace('/(^Name: )(.*)(.dat)/', '$2', $line));
}
// 0 Author: <Realname> [<Username>]
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);
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace AppBundle\Command\Loader;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Asset\Exception\LogicException;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Debug\Exception\ContextErrorException;
class Loader
{
/**
* @var EntityManager
*/
protected $em;
/**
* @var OutputInterface
*/
protected $output;
/**
* @var ProgressBar
*/
protected $progressBar;
public function setOutput(OutputInterface $output)
{
$this->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;
}
}

View File

@ -1,114 +1,53 @@
<?php
namespace AppBundle\Service;
namespace AppBundle\Command\Loader;
use AppBundle\Api\Manager\RebrickableManager;
use AppBundle\Entity\BuildingKit;
use AppBundle\Entity\Category;
use AppBundle\Entity\Color;
use AppBundle\Entity\Keyword;
use AppBundle\Entity\Model;
use AppBundle\Entity\BuildingKit;
use AppBundle\Entity\Part;
use AppBundle\Entity\Part_BuildingKit;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Asset\Exception\LogicException;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
class ModelLoaderService
//TODO Refactor
class RebrickableLoader extends Loader
{
private $STLlib;
/**
* @var EntityManager
*/
private $em;
/**
* @var RebrickableManager
*/
private $rebrickableManager;
private $rebrickable_url;
/**
* ModelLoaderService constructor.
*/
public function __construct($em, $STLlib, $rebrickableManager)
public function __construct($em, $rebrickableManager, $rebrickable_url)
{
$this->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;

View File

@ -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,
]);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Model;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/download")
*/
class DownloadController extends Controller
{
/**
* @Route("/model/{id}", name="download_model")
*
* @return Response
*/
public function modelAction(Model $model)
{
$ldraw_filesystem = $this->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());
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
/**
* @Route("/rebrickable/part")
*/
class PartController extends Controller
{
/**
* @Route("/{id}", name="part_detail")
*/
public function detailAction($id)
{
$part = $this->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,
]);
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
/**
* @Route("rebrickable/parts")
*/
class PartsController extends Controller
{
/**
* @Route("/{id}", name="part_detail")
*/
public function detailAction($id)
{
$part = $this->get('manager.rebrickable')->getPartById($id);
return $this->render('parts/detail.html.twig', [
'part' => $part,
]);
}
}

View File

@ -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,
]);
}
}

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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
*/

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -15,7 +15,7 @@ class Builder
]);
$menu->addChild('Sets', [
'route' => 'sets_browse',
'route' => 'set_browse',
]);
return $menu;

View File

@ -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.

View File

@ -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.

View File

@ -3,7 +3,7 @@
namespace AppBundle\Repository;
/**
* ColorRepository
* ColorRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.

View File

@ -3,7 +3,7 @@
namespace AppBundle\Repository;
/**
* KeywordRepository
* KeywordRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.

View File

@ -3,7 +3,7 @@
namespace AppBundle\Repository;
/**
* ModelRepository
* ModelRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.

View File

@ -3,7 +3,7 @@
namespace AppBundle\Repository;
/**
* PartRepository
* PartRepository.
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.

View File

@ -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.