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

Add Imagine PartImage loader

This commit is contained in:
David Hübner 2017-05-05 20:08:52 +02:00
parent 28d7b64244
commit e684d30c45
21 changed files with 417 additions and 248 deletions

1
.gitignore vendored
View File

@ -18,5 +18,6 @@
/node_modules/ /node_modules/
/app/Resources/libs/semantic/dist /app/Resources/libs/semantic/dist
/web/resources/ /web/resources/
/var/media/
/web/media/ /web/media/
.php_cs.cache .php_cs.cache

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,6 +1,3 @@
{% import 'macros/blocks.html.twig' as blocks %}
{% import 'macros/elements.html.twig' as elements %}
{% for label, flashes in app.session.flashbag.all %} {% for label, flashes in app.session.flashbag.all %}
{% for flash in flashes %} {% for flash in flashes %}
{{ elements.flash(label,flash) }} {{ elements.flash(label,flash) }}

View File

@ -1,5 +1,8 @@
{% extends 'ajax.html.twig' %} {% extends 'ajax.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% import 'macros/elements.html.twig' as elements %}
{% block content %} {% block content %}
{% if description|length %} {% if description|length %}
{{ description|raw }} {{ description|raw }}

View File

@ -1,5 +1,8 @@
{% extends 'ajax.html.twig' %} {% extends 'ajax.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% import 'macros/elements.html.twig' as elements %}
{% block content %} {% block content %}
{% if images|length %} {% if images|length %}
<div class="ui six doubling cards"> <div class="ui six doubling cards">

View File

@ -1,5 +1,8 @@
{% extends 'ajax.html.twig' %} {% extends 'ajax.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% import 'macros/elements.html.twig' as elements %}
{% block content %} {% block content %}
{% if instructions|length != 0 %} {% if instructions|length != 0 %}
<p><cite>{{ 'set.instructions.text' | trans | raw | nl2br }}</cite></p> <p><cite>{{ 'set.instructions.text' | trans | raw | nl2br }}</cite></p>

View File

@ -1,13 +1,41 @@
{% extends 'ajax.html.twig' %} {% extends 'ajax.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% import 'macros/elements.html.twig' as elements %}
{% block content %} {% block content %}
{% if reviews|length != 0 %} {% if reviews|length != 0 %}
<div class="ui comments"> <div class="ui comments">
{% for review in reviews %} {% for review in reviews %}
<div class="comment"> <div class="ui segment vertical">
<a class="avatar"> <div class="ui container divided stackable grid comment">
<div class="row">
<div class="column four wide ratings">
<dl>
{% if review.overallRating %}
<dt>Overall rating</dt>
<dd><span class="ui star rating" data-rating="{{ review.overallRating }}" data-max-rating="5"></span></dd>
{% endif %}
{% if review.valueForMoney %}
<dt>Value for money</dt>
<dd><span class="ui star rating" data-rating="{{ review.valueForMoney }}" data-max-rating="5"></span></dd>
{% endif %}
{% if review.playability %}
<dt>Playability</dt>
<dd><span class="ui star rating" data-rating="{{ review.playability }}" data-max-rating="5"></span></dd>
{% endif %}
{% if review.parts %}
<dt>Parts</dt>
<dd><span class="ui star rating" data-rating="{{ review.parts }}" data-max-rating="5"></span></dd>
{% endif %}
{% if review.buildingExperience %}
<dt>Building experience</dt>
<dd><span class="ui star rating" data-rating="{{ review.buildingExperience }}" data-max-rating="5"></span></dd>
{% endif %}
</dl>
</div>
</a> <div class="column twelve wide comment">
<div class="content"> <div class="content">
<div class="header"> <div class="header">
<h2>{{ review.title }}</h2> <h2>{{ review.title }}</h2>
@ -24,12 +52,8 @@
<p>{{ review.review }}</p> <p>{{ review.review }}</p>
{% endif %} {% endif %}
</div> </div>
<div> </div>
Overall rating <div class="ui star rating" data-rating="{{ review.overallRating }}" data-max-rating="5"></div> </div>
Value for money <div class="ui star rating" data-rating="{{ review.valueForMoney }}" data-max-rating="5"></div>
Playability <div class="ui star rating" data-rating="{{ review.playability }}" data-max-rating="5"></div>
Parts <div class="ui star rating" data-rating="{{ review.parts }}" data-max-rating="5"></div>
Building experience <div class="ui star rating" data-rating="{{ review.buildingExperience }}" data-max-rating="5"></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,39 +1,70 @@
{% macro modelImageMin(model, color) %} {% macro partImage(number, filter, color = -1) %}
{% if filter == 'part_large' %}
{% set placeholder = asset("resources/images/unknown_large.png") %}
{% else %}
{% set placeholder = asset("resources/images/unknown.png") %}
{% endif %}
<div class="image load"> <div class="image load">
<img src="{{ asset('/images/'~color~'/'~model.number~'.png') | imagine_filter('media_min') }}"> <img src="{{ placeholder }}" data-src="{{ asset(color~'/'~number~'.png') | imagine_filter(filter)}}">
</div> </div>
{% endmacro %} {% endmacro %}
{% macro modelImageLarge(model, color) %} {% macro setImage(number, filter) %}
<div class="image"> <div class="image load">
<img src="{{ asset('/images/'~color~'/'~model.number~'.png')|imagine_filter('media_large') }}"> {% if filter == 'set_large' %}
{% set placeholder = asset("resources/images/unknown_large.png") %}
{% else %}
{% set placeholder = asset("resources/images/unknown.png") %}
{% endif %}
<img src="{{ placeholder }}" data-src="{{ asset('/sets/'~number|lower~'.jpg')|imagine_filter(filter) }}">
</div> </div>
{% endmacro %} {% endmacro %}
{% macro model(model, quantity = null) %} {% macro model(model, quantity = null, color = -1) %}
<div class="column"> <div class="column model">
<div class="ui bordered fluid image">
<a href="{{ url('model_detail', {'number': model.number})}}"> <a href="{{ url('model_detail', {'number': model.number})}}">
<div class="ui bordered fluid image">
{% import _self as blocks %} {% import _self as blocks %}
{{ blocks.modelImageMin(model, -1) }} {{ blocks.partImage(model.number, 'part_min', color) }}
<div class="ui bottom attached label">{% if quantity %}{{ quantity }}x{% endif %} {{ model.number }}</div> </div>
<div class="model-meta">
<span class="quantity"></span> {% if quantity %}{{ quantity }}x{% endif %}<span class="number">{{ model.number }}</span>
{#<span class="name">{{ model.name }}</span>#}
</div>
</a> </a>
</div> </div>
</div>
{% endmacro %} {% endmacro %}
{% macro part(part, quantity, color = -1) %} {% macro part(part, quantity = null, color = -1) %}
<div class="column"> <div class="column">
<div class="ui bordered fluid image"> <div class="ui color-{{ color }} bordered fluid image">
<a href="{{ url('reb_part_detail', {'number': part.number})}}"> <a href="{{ url('reb_part_detail', {'number': part.number})}}">
{% import _self as blocks %} {% import _self as blocks %}
{#{{ blocks.partImage(part.number, -1) }}#} {{ blocks.partImage(part.number,'part_min', color) }}
<div class="ui bottom attached label">{{ quantity }}x {{ part.number }}</div> <div class="part-meta">
<span class="quantity"></span> {% if quantity %}{{ quantity }}x{% endif %}<span class="number">{{ part.number }}</span>
</div>
</a> </a>
</div> </div>
</div> </div>
{% endmacro %} {% endmacro %}
{% macro set(set) %}
<div class="column">
<a href="{{ url('set_detail', {'number': set.number}) }}">
<div class="ui bordered fluid image">
{{ blocks.setImage(set.number,'set_min') }}
</div>
<div class="set-meta">
<p>{{ set.number }}</p>
<p>{{ set.name }}</p>
</div>
</a>
</div>
{% endmacro %}
{% macro empty(message) %} {% macro empty(message) %}
<p class="ui center aligned icon header"><i class="circular frown icon"></i>{{ message }}</p> <p class="ui center aligned icon header"><i class="circular frown icon"></i>{{ message }}</p>
{% endmacro %} {% endmacro %}
@ -41,3 +72,4 @@
{% macro ccal2_license(title,author) %} {% macro ccal2_license(title,author) %}
"{{ title }}" by {{ author }}, used under <a href="https://creativecommons.org/licenses/by/2.0/">CC BY 2.0</a> / Converted to stl from original "{{ title }}" by {{ author }}, used under <a href="https://creativecommons.org/licenses/by/2.0/">CC BY 2.0</a> / Converted to stl from original
{% endmacro %} {% endmacro %}

View File

@ -1,5 +1,7 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% block title %}#{{ model.number }} - {{ model.name }}{% endblock %} {% block title %}#{{ model.number }} - {{ model.name }}{% endblock %}
{% block header %}#{{ model.number }} - {{ model.name }}{% endblock %} {% block header %}#{{ model.number }} - {{ model.name }}{% endblock %}
@ -9,16 +11,15 @@
<div class="ui grid"> <div class="ui grid">
<div class="column ten wide"> <div class="column ten wide">
<div id="model-viewer" class="model-container"> <div id="model-viewer" class="model-container">
{{ blocks.modelImageLarge(model, -1) }} {{ blocks.partImage(model.number,'part_large') }}
</div> </div>
</div> </div>
<div class="column six wide"> <div class="column six wide">
<div class="item-info ui"> <div class="item-info ui">
<a class="ui download primary button" href="{{ path('model_zip', {number: model.number}) }}">{{ 'model.download'|trans }}</a>
<table class="ui very basic table"> <table class="ui very basic table">
<tr> <tr>
<td>{{ 'model.category' | trans }}</td><td>{{ model.category ? model.category.name }}</td> <td>{{ 'model.category' | trans }}</td>
<td><a href="{{ path('model_index',{}) }}">{{ model.category ? model.category.name }}</a></td>
</tr> </tr>
<tr> <tr>
<td>{{ 'model.author' | trans }}</td><td>{{ model.author.name }}</td> <td>{{ 'model.author' | trans }}</td><td>{{ model.author.name }}</td>
@ -51,6 +52,9 @@
</tr> </tr>
{% endif %} {% endif %}
</table> </table>
<a class="ui download primary button" href="{{ path('model_zip', {number: model.number}) }}">{{ 'model.download'|trans }}</a>
</div> </div>
</div> </div>
</div> </div>
@ -66,12 +70,8 @@
<div class="ui tab active" data-tab="subparts"> <div class="ui tab active" data-tab="subparts">
<div class="ui eight column grid"> <div class="ui eight column grid">
{% for subpart in model.subparts %} {% for subpart in subparts %}
<div class="column"> {{ blocks.model(subpart['model'], subpart['quantity']) }}
{{ blocks.part(subpart.subpart) }}
<p>{{ subpart.count }}</p>
<p style="border-bottom: 2px solid #{{ subpart.color.rgb }}">color: {{ subpart.color.name }}</p>
</div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
@ -80,7 +80,7 @@
<div class="ui eight column grid"> <div class="ui eight column grid">
{% for subpart in related %} {% for subpart in related %}
<div class="column"> <div class="column">
{{ blocks.part(subpart) }} {{ blocks.model(subpart) }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@ -90,16 +90,25 @@
<div class="ui eight column grid"> <div class="ui eight column grid">
{% for subpart in model.parents %} {% for subpart in model.parents %}
<div class="column"> <div class="column">
{{ blocks.part(subpart.parent) }} {{ blocks.model(subpart.parent) }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div class="ui tab" data-tab="sets"> <div class="ui tab" data-tab="sets">
{% for set in sets %} <div class="ui six column doubling grid">
<span style="margin: 5px"><a href="{{ url('set_detail', {number:set.number}) }}">{{ set.number }}</a></span> <div class="row">
{% endfor %} {#{% for set in sets %}#}
{#<div class="column">#}
{#<a href="{{ url('set_detail', {number:set.number}) }}">#}
{#{{ blocks.setImage(set.number,'set_min') }}#}
{#<h5>{{ set.number }}</h5>#}
{#</a>#}
{#</div>#}
{#{% endfor %}#}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,7 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% block title %}{{ 'page.model.index' | trans }}{% endblock %} {% block title %}{{ 'page.model.index' | trans }}{% endblock %}
{% block header %}{{ 'page.model.index' | trans }}{% endblock %} {% block header %}{{ 'page.model.index' | trans }}{% endblock %}
@ -14,7 +16,7 @@
{{ form_row(form.search) }} {{ form_row(form.search) }}
<div class="field fluid search selection"> <div class="field fluid search selection">
{{ form_label(form.category.id) }} {{ form_label(form.category.id) }}
{{ form_widget(form.category.id) }} {{ form_widget(form.category.id)}}
</div> </div>
<div class="field"> <div class="field">
<input class="ui submit button" type="submit" value="filter"/> <input class="ui submit button" type="submit" value="filter"/>
@ -23,16 +25,15 @@
</form> </form>
</div> </div>
<div class="column twelve wide"> <div class="column twelve wide">
<div class="ui spacing 20"> <div class="ui six column doubling grid">
<div class="ui eight column doubling grid">
{% for model in models %} {% for model in models %}
{{ blocks.model(model) }} {{ blocks.model(model) }}
{% endfor %} {% endfor %}
</div> </div>
</div>
<div class="ui column vertical segment noborder">
{{ knp_pagination_render(models) }} {{ knp_pagination_render(models) }}
<p>{{ models.getTotalItemCount }}</p> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% import 'macros/elements.html.twig' as elements %} {% import 'macros/blocks.html.twig' as blocks %}
{% block header %}#{{ part.number }} - {{ part.name }}{% endblock %} {% block header %}#{{ part.number }} - {{ part.name }}{% endblock %}
@ -8,7 +8,7 @@
<div class="ui grid"> <div class="ui grid">
<div class="column ten wide"> <div class="column ten wide">
<div id="model-viewer" class="model-container"> <div id="model-viewer" class="model-container">
<img src="{{ apiPart.imgUrl }}"> {{ blocks.partImage(part.number,'part_large') }}
</div> </div>
</div> </div>
<div class="column six wide"> <div class="column six wide">
@ -21,7 +21,7 @@
<td>{{ 'part.name' | trans }}</td><td>{{ part.name}}</td> <td>{{ 'part.name' | trans }}</td><td>{{ part.name}}</td>
</tr> </tr>
<tr> <tr>
<td>{{ 'part.category' | trans }}</td><td>{{ part.category.name }}</td> <td>{{ 'part.category' | trans }}</td><td>{{ part.category ? part.category.name }}</td>
</tr> </tr>
<tr> <tr>
<td>{{ 'part.model' | trans }}</td> <td>{{ 'part.model' | trans }}</td>
@ -48,6 +48,13 @@
{% endfor %} {% endfor %}
</td> </td>
</tr> </tr>
<tr>
<td></td>
<td><a href="{{ apiPart.url }}">Rebrickable</a></td>
</tr>
<tr>
{{ dump(apiPart.externalIds, apiPart) }}
</tr>
{% endif %} {% endif %}
</table> </table>
</div> </div>
@ -63,9 +70,7 @@
<div class="column"> <div class="column">
<div class="ui fluid bordered image"> <div class="ui fluid bordered image">
<a href="{{ url('set_detail', {number:set.number}) }}"> <a href="{{ url('set_detail', {number:set.number}) }}">
<div class="image load"> {{ blocks.setImage(set.number,'set_min') }}
<img class="ui bordered" src="{{ asset('resources/images/unknown_image.png') }}" data-src="{{ set.number|setImage|imagine_filter('rebrickable_min') }}">
</div>
<div class="ui bottom attached label">{{ set.number }}<br></div> <div class="ui bottom attached label">{{ set.number }}<br></div>
</a> </a>
</div> </div>

View File

@ -1,44 +1,38 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block title %}{{ set ? set.number }} {{ set ? set.name }}{% endblock %} {% import 'macros/blocks.html.twig' as blocks %}
{% block header %}{{ set ? set.number }} {{ set ? set.name | escape('html') }}{% endblock %} {% block title %}{{ set.number }} {{ set.name }}{% endblock %}
{% block header %}{{ set.number }} {{ set.name | escape('html') }}{% endblock %}
{% block content %} {% block content %}
<div class="ui stackable grid"> <div class="ui stackable grid">
<div class="column nine wide"> <div class="column nine wide">
<div class="image bordered ui big"> <div class="ui bordered fluid image">
{% if brset %} {{ blocks.setImage(set.number,'set_large') }}
<img class="big" src="{{ ('/sets/images/'~brset.legoSetID~'.jpg')|imagine_filter('brickset_large') }}">
{% else %}
<img class="big" src="{{ set.number|setImage|imagine_filter('rebrickable_large') }}">
{% endif %}
</div> </div>
</div> </div>
<div class="column seven wide"> <div class="column seven wide">
<div class="item-info ui"> <div class="item-info ui">
<table class="ui very basic table"> <table class="ui very basic table">
<tr> <tr>
<td>{{ 'set.number' | trans }}</td><td>{{ brset ? brset.legoSetID : set ? set.number : null}}</td> <td>{{ 'set.number' | trans }}</td><td>{{ set.number }}</td>
</tr> </tr>
<tr> <tr>
<td>{{ 'set.name' | trans }}</td><td>{{ brset ? brset.name : set ? set.name : null}}</td> <td>{{ 'set.name' | trans }}</td><td>{{ set.name }}</td>
</tr> </tr>
<tr> <tr>
<td>{{ 'set.year' | trans }}</td><td>{{ brset ? brset.year : set ? set.year : null}}</td> <td>{{ 'set.year' | trans }}</td><td>{{ set.year }}</td>
</tr> </tr>
<tr> <tr>
<td>{{ 'set.theme' | trans }}</td> <td>{{ 'set.theme' | trans }}</td>
{% if set %} <td><a href="#">{{ set.theme.parent ? set.theme.parent.name }}</a> &gt; <a href="#">{{ set.theme ? set.theme.name }}</a> </td>
<td><a href="#">{{ set.theme.parent ? set.theme.parent.name }}</a> <a href="#">{{ set.theme.name }}</a> </td>
{% elseif brset %}
<td>{{ brset.theme }}</td>
{% endif %}
</tr> </tr>
<tr> <tr>
<td>{{ 'set.parts' | trans }}</td><td> <td>{{ 'set.parts' | trans }}</td><td>
{{ set ? set.partCount }} {{ brset ? '('~brset.pieces~')' }} {{ set.partCount }} {{ brset ? '('~brset.pieces~')' }}
</td> </td>
</tr> </tr>
{% if brset %} {% if brset %}
@ -64,22 +58,39 @@
</tr> </tr>
</table> </table>
<a class="ui download primary button">{{ 'set.download'|trans }}</a>
<div class="ui download flowing popup bottom center transition hidden"> <div class="ui primary open-modal button">{{ 'set.download' | trans }}</div>
{% embed 'embeds/modal.html.twig' %}
{% block title %}
{{ 'set.download.title' | trans({'%set%': set.number~' '~set.name}) }}
{% endblock %}
{% block content %}
{#<div class="ui icon message">#}
{#<i class="warning icon"></i>#}
{#<div class="content">#}
{#<div class="header">#}
{#{{ 'set.download.warning.title' | trans }}#}
{#</div>#}
{#<p> {{ 'set.download.warning.text' | trans }}</p>#}
{#</div>#}
{#</div>#}
{% endblock %}
{% block actions %}
<div class="ui two column divided center aligned grid"> <div class="ui two column divided center aligned grid">
<div class="column"> <div class="column">
<h4 class="ui header">{{ 'set.download.sorted' }}</h4> <h4 class="ui header">{{ 'set.download.sorted.title' | trans }}</h4>
<p>{{ 'set.download.sorted.text' | trans }}</p> <p>{{ 'set.download.sorted.text' | trans }}</p>
<a class="ui button" href="{{ path('set_zip', {number: set.number, sorted: true }) }}" download>Download ZIP</a> <a class="ui download button" href="{{ path('set_zip', {number: set.number, sorted: true }) }}" download>Download ZIP</a>
</div> </div>
<div class="column"> <div class="column">
<h4 class="ui header">{{ 'set.download.unsorted' }}</h4> <h4 class="ui header">{{ 'set.download.unsorted.title' | trans }}</h4>
<p>{{ 'set.download.unsorted.text' | trans }}</p> <p>{{ 'set.download.unsorted.text' | trans }}</p>
<a class="ui button" href="{{ path('set_zip', {number: set.number, sorted: false }) }}" download>Download ZIP</a> <a class="ui download button" href="{{ path('set_zip', {number: set.number, sorted: false }) }}" download>Download ZIP</a>
</div> </div>
</div> </div>
</div> {% endblock %}
{% endembed %}
</div> </div>
</div> </div>
@ -97,11 +108,19 @@
</div> </div>
<div class="ui vertical segment"> <div class="ui vertical segment">
<div class="ui tab active" data-tab="parts"> <div class="ui tab active" data-tab="parts">
{#<div class="ui icon buttons right floated">#}
{#<button class="ui button"><i class="grid layout icon"></i></button>#}
{#<button class="ui button"><i class="list layout icon"></i></button>#}
{#</div>#}
<p>{{ 'set.models.text' | trans({'%rebrickable%' : partCount, '%brickset%' : brset ? brset.pieces }) | nl2br }}</p>
<div class="ajax-load" data-src="{{ path('set_models', { 'number': set.number }) }}"> <div class="ajax-load" data-src="{{ path('set_models', { 'number': set.number }) }}">
<div class="ui active centered inline loader"></div> <div class="ui active centered inline loader"></div>
</div> </div>
{#{{ render(path('set_colors', {number: set.number})) }}#} {#{{ render(path('set_models', {number: set.number})) }}#}
{{ render(path('set_sets', {number: set.number})) }}
</div> </div>
{% if brset %} {% if brset %}
<div class="ui tab ajax-load" data-tab="description" data-src="{{ path('brickset_description', { 'id': brset.setID }) }}"> <div class="ui tab ajax-load" data-tab="description" data-src="{{ path('brickset_description', { 'id': brset.setID }) }}">

View File

@ -1,5 +1,7 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% block title %}{{ 'page.set.index' | trans }}{% endblock %} {% block title %}{{ 'page.set.index' | trans }}{% endblock %}
{% block header %}{{ 'page.set.index' | trans }}{% endblock %} {% block header %}{{ 'page.set.index' | trans }}{% endblock %}
@ -18,6 +20,7 @@
{{ form_widget(form.theme.id) }} {{ form_widget(form.theme.id) }}
</div> </div>
<div class="field"> <div class="field">
<div id="slider"></div>
{{ form_row(form.partCount) }} {{ form_row(form.partCount) }}
</div> </div>
<div class="field"> <div class="field">
@ -33,15 +36,10 @@
</div> </div>
<div class="column twelve wide"> <div class="column twelve wide">
<div class="segment vertical"> <div class="segment vertical">
<div class="ui six column doubling grid"> <div class="ui five column doubling grid">
<div class="row"> <div class="row">
{% for set in sets %} {% for set in sets %}
<div class="column"> {{ set(set) }}
<a href="{{ url('set_detail', {'number': set.number}) }}">
<img class="ui bordered image medium" src="{{ set.number|setImage|imagine_filter('rebrickable_min') }}">
<p>{{ set.number }} - {{ set.name }}</p>
</a>
</div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
@ -56,6 +54,4 @@
{% block javascripts %} {% block javascripts %}
{{ parent() }} {{ parent() }}
{% endblock %} {% endblock %}

View File

@ -10,7 +10,7 @@
<div class="ui ten column grid"> <div class="ui ten column grid">
{% for model in color['models'] %} {% for model in color['models'] %}
{{ blocks.model(model['model'],model['quantity']) }} {{ blocks.model(model['model'],model['quantity'], color['color'].id) }}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>

View File

@ -8,7 +8,8 @@
<div class="ui ten column grid"> <div class="ui ten column grid">
{% for inventoryPart in regularParts %} {% for inventoryPart in regularParts %}
{{ blocks.part(inventoryPart.part,inventoryPart.quantity, inventoryPart.color) }} {{ blocks.part(inventoryPart.part.number,inventoryPart.quantity, inventoryPart.color.id) }}
{{ inventoryPart.color.id }}
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}
@ -19,7 +20,7 @@
</h4> </h4>
<div class="ui ten column grid"> <div class="ui ten column grid">
{% for inventoryPart in missing %} {% for inventoryPart in missing %}
{{ blocks.part(inventoryPart.part,inventoryPart.quantity, inventoryPart.color) }} {{ blocks.part(inventoryPart.part.number,inventoryPart.quantity, inventoryPart.color.id) }}
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}
@ -30,7 +31,7 @@
</h4> </h4>
<div class="ui ten column grid"> <div class="ui ten column grid">
{% for inventoryPart in spareParts %} {% for inventoryPart in spareParts %}
{{ blocks.part(inventoryPart.part,inventoryPart.quantity, inventoryPart.color) }} {{ blocks.part(inventoryPart.part.number,inventoryPart.quantity, inventoryPart.color.id) }}
{% endfor %} {% endfor %}
</div> </div>
{% endif %} {% endif %}

View File

@ -1,13 +1,14 @@
{% extends 'ajax.html.twig' %} {% extends 'ajax.html.twig' %}
{% import 'macros/blocks.html.twig' as blocks %}
{% block content %} {% block content %}
<p>{{ 'set.models.text' | trans | nl2br }}</p>
{% if models|length > 0 %} {% if models|length > 0 %}
<h4 class="ui horizontal divider header"> <h4 class="ui horizontal divider header">
Regular parts Models
</h4> </h4>
<div class="ui segment vertical"> <div class="ui segment vertical noborder">
<div class="ui grid"> <div class="ui grid">
<div class="doubling ten column row"> <div class="doubling ten column row">
{% for model in models %} {% for model in models %}
@ -17,44 +18,43 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% if missing|length > 0 %} {% if missing|length > 0 %}
<h4 class="ui horizontal divider header"> <h4 class="ui horizontal divider header">
Missing regular models Missing models
</h4> </h4>
<div class="ui segment vertical"> <div class="ui segment vertical noborder">
<div class="ui ten column grid"> <div class="ui ten column grid">
{% for inventoryPart in missing %} {% for part in missing %}
{{ blocks.part(inventoryPart.part,inventoryPart.quantity) }} {{ blocks.part(part['part'],part['quantity']) }}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% if spareModels|length > 0 %} {#{% if spareModels|length > 0 %}#}
<h4 class="ui horizontal divider header"> {#<h4 class="ui horizontal divider header">#}
Spare parts {#Spare parts#}
</h4> {#</h4>#}
<div class="ui segment vertical"> {#<div class="ui segment vertical">#}
<div class="ui ten column grid"> {#<div class="ui ten column grid">#}
{% for model in spareModels %} {#{% for model in spareModels %}#}
{{ blocks.model(model['model'],model['quantity']) }} {#{{ blocks.model(model['model'],model['quantity']) }}#}
{% endfor %} {#{% endfor %}#}
</div> {#</div>#}
</div> {#</div>#}
{% endif %} {#{% endif %}#}
{% if missingSpare|length > 0 %} {#{% if missingSpare|length > 0 %}#}
<h4 class="ui horizontal divider header"> {#<h4 class="ui horizontal divider header">#}
Missing spare models {#Missing spare models#}
</h4> {#</h4>#}
<div class="ui segment vertical"> {#<div class="ui segment vertical">#}
<div class="ui ten column grid segment"> {#<div class="ui ten column grid segment">#}
{% for inventoryPart in missingSpare %} {#{% for inventoryPart in missingSpare %}#}
{{ blocks.part(inventoryPart.part,inventoryPart.quantity) }} {#{{ blocks.part(inventoryPart.part.number,inventoryPart.quantity, inventoryPart.color.id) }}#}
{% endfor %} {#{% endfor %}#}
</div> {#</div>#}
</div> {#</div>#}
{% endif %} {#{% endif %}#}
{% endblock %} {% endblock %}

View File

@ -1,20 +1,20 @@
{% extends 'ajax.html.twig' %} {% extends 'ajax.html.twig' %}
{% block content %} {% block content %}
{% if inventorySets %}
<h4 class="ui horizontal divider header">Sets</h4> <h4 class="ui horizontal divider header">Sets</h4>
<div class="ui seven column grid"> <div class="ui seven column grid">
<div class="row"> <div class="row">
{% for set in inventorySets %} {% for inventorySet in inventorySets %}
<div class="column"> <div class="column">
<a href="{{ url('set_detail', {'number': set.set.number}) }}"> <a href="{{ url('set_detail', {'number': inventorySet.set.number}) }}">
<div class="ui bordered image medium"> {{ blocks.setImage(inventorySet.set.number,'set_min') }}
<img src="{{ asset('resources/images/unknown_image.png') }}" data-src="{{ set.set.number|setImage|imagine_filter('rebrickable_set_min') }}" class="transition visible"> <p>{{ inventorySet.set.number }} - {{ inventorySet.set.name }}</p>
</div> <p>{{ inventorySet.quantity}}</p>
<p>{{ set.set.number }} - {{ set.set.name }}</p>
<p>{{ set.quantity}}</p>
</a> </a>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% endif %}
{% endblock %} {% endblock %}

View File

@ -111,9 +111,6 @@ knp_paginator:
liip_imagine: liip_imagine:
loaders: loaders:
media:
flysystem:
filesystem_service: oneup_flysystem.media_filesystem
rebrickable: rebrickable:
stream: stream:
wrapper: 'http://rebrickable.com/media/' wrapper: 'http://rebrickable.com/media/'
@ -121,49 +118,11 @@ liip_imagine:
stream: stream:
wrapper: 'https://images.brickset.com/' wrapper: 'https://images.brickset.com/'
resolvers: resolvers:
default: default:
web_path: ~ web_path: ~
filter_sets: filter_sets:
media:
data_loader: media
media_min:
data_loader: media
cache: ~
quality: 80
filters:
thumbnail: { size: [200, 200], mode: inset }
background: { size: [250, 250], position: center, color: '#FFFFFF' }
media_large:
data_loader: media
cache: ~
quality: 92
filters:
thumbnail: { size: [840, 580], mode: inset }
background: { size: [900, 600], position: center, color: '#FFFFFF' }
rebrickable:
data_loader: rebrickable
rebrickable_min:
quality: 80
data_loader: rebrickable
default_image: '/resources/images/unknown_image.png'
cache: ~
filters:
thumbnail: { size: [200, 200], mode: inset }
background: { size: [250, 250], position: center, color: '#FFFFFF' }
rebrickable_large:
data_loader: rebrickable
cache: ~
quality: 92
filters:
thumbnail: { size: [840, 580], mode: inset }
background: { size: [900, 600], position: center, color: '#FFFFFF' }
brickset:
data_loader: brickset
brickset_large: brickset_large:
data_loader: brickset data_loader: brickset
cache: ~ cache: ~
@ -171,6 +130,37 @@ liip_imagine:
filters: filters:
thumbnail: { size: [840, 580], mode: inset } thumbnail: { size: [840, 580], mode: inset }
background: { size: [900, 600], position: center, color: '#FFFFFF' } background: { size: [900, 600], position: center, color: '#FFFFFF' }
set_min:
quality: 80
data_loader: rebrickable
cache: ~
filters:
thumbnail: { size: [200, 200], mode: inset }
background: { size: [250, 250], position: center, color: '#FFFFFF' }
set_large:
data_loader: rebrickable
cache: ~
quality: 92
filters:
thumbnail: { size: [840, 580], mode: inset }
background: { size: [900, 600], position: center, color: '#FFFFFF' }
part_large:
data_loader: part_image_loader
cache: ~
quality: 92
filters:
thumbnail: { size: [840, 580], mode: inset }
background: { size: [900, 600], position: center, color: '#FFFFFF' }
part_min:
quality: 80
data_loader: part_image_loader
default_image: "noimage.png"
cache: ~
filters:
thumbnail: { size: [200, 200], mode: inset }
background: { size: [250, 250], position: center, color: '#FFFFFF' }
oneup_flysystem: oneup_flysystem:
adapters: adapters:
media: media:

View File

@ -17,4 +17,9 @@ services:
service.set: service.set:
class: AppBundle\Service\SetService class: AppBundle\Service\SetService
arguments: ['@repository.rebrickable.inventorypart'] arguments: ['@repository.rebrickable.inventorypart'] arguments: ['@repository.rebrickable.inventorypart'] app.part_image_loader:
app.part_image_loader:
class: AppBundle\Imagine\PartImageLoader
arguments: ['@api.manager.rebrickable', '@oneup_flysystem.media_filesystem']
tags:
- { name: liip_imagine.binary.loader, loader: part_image_loader }

View File

@ -0,0 +1,79 @@
<?php
namespace AppBundle\Imagine;
use AppBundle\Api\Manager\RebrickableManager;
use League\Flysystem\Filesystem;
use Liip\ImagineBundle\Binary\Loader\LoaderInterface;
use Liip\ImagineBundle\Exception\Binary\Loader\NotLoadableException;
class PartImageLoader implements LoaderInterface
{
/** @var Filesystem */
private $mediaFilesystem;
/** @var RebrickableManager */
private $rebrickableManager;
private $rebrickableContext = 'http://rebrickable.com/media/parts/ldraw/';
/**
* LocalStreamLoader constructor.
*
* @param $rebrickableManager
* @param $mediaFilesystem
*/
public function __construct($rebrickableManager, $mediaFilesystem)
{
$this->mediaFilesystem = $mediaFilesystem;
$this->rebrickableManager = $rebrickableManager;
}
public function find($path)
{
// try to load image from local mediaFilesystem
if ($this->mediaFilesystem->has('/images/'.$path)) {
return $this->mediaFilesystem->read('/images/'.$path);
}
// try to load image from rebrickable website
try {
if ($this->remoteFileExists($this->rebrickableContext.$path)) {
return file_get_contents($this->rebrickableContext.$path);
}
} catch (\Exception $e) {
throw new NotLoadableException(sprintf('Source image %s could not be loaded.', $path), $e->getCode(), $e);
}
// Load part entity form rebrickable api and get image path from response
try {
if (preg_match('/^(.*)\/(.*).png$/', $path, $match)) {
$part = $this->rebrickableManager->getPart($match[2]);
if ($part && $part->getImgUrl()) {
return file_get_contents($part->getImgUrl());
}
}
} catch (\Exception $e) {
throw new NotLoadableException(sprintf('Source image %s could not be loaded.', $path), $e->getCode(), $e);
}
return $this->mediaFilesystem->read('noimage.png');
}
/**
* @param string $url
*
* @return bool
*/
public function remoteFileExists($url)
{
$resource = curl_init($url);
curl_setopt($resource, CURLOPT_NOBODY, true);
curl_exec($resource);
$status = curl_getinfo($resource, CURLINFO_HTTP_CODE);
curl_close($resource);
return $status === 200 ? true : false;
}
}

View File

@ -2,33 +2,26 @@
namespace AppBundle\Twig; namespace AppBundle\Twig;
use AppBundle\Api\Manager\RebrickableManager;
use AppBundle\Transformer\FormatTransformer; use AppBundle\Transformer\FormatTransformer;
class AppExtension extends \Twig_Extension class AppExtension extends \Twig_Extension
{ {
/** @var RebrickableManager */
private $rebrickableAPIManager;
/** @var FormatTransformer */ /** @var FormatTransformer */
private $formatTransformer; private $formatTransformer;
/** /**
* AppExtension constructor. * AppExtension constructor.
* *
* @param RebrickableManager $rebrickableAPIManager * @param FormatTransformer $formatTransformer
*/ */
public function __construct($rebrickableAPIManager, $formatTransformer) public function __construct($formatTransformer)
{ {
$this->rebrickableAPIManager = $rebrickableAPIManager;
$this->formatTransformer = $formatTransformer; $this->formatTransformer = $formatTransformer;
} }
public function getFilters() public function getFilters()
{ {
return [ return [
new \Twig_SimpleFilter('partImage', [$this, 'partImage']),
new \Twig_SimpleFilter('setImage', [$this, 'setImage']),
new \Twig_SimpleFilter('bytesToSize', [$this, 'bytesToSize']), new \Twig_SimpleFilter('bytesToSize', [$this, 'bytesToSize']),
]; ];
} }
@ -38,23 +31,31 @@ class AppExtension extends \Twig_Extension
return [ return [
new \Twig_SimpleFunction('remoteSize', [$this, 'remoteSize']), new \Twig_SimpleFunction('remoteSize', [$this, 'remoteSize']),
new \Twig_SimpleFunction('remoteFilename', [$this, 'remoteFilename']), new \Twig_SimpleFunction('remoteFilename', [$this, 'remoteFilename']),
new \Twig_SimpleFunction('remoteFileExists', [$this, 'remoteFileExists']),
]; ];
} }
public function partImage($number, $color = null) public function bytesToSize($bytes, $precision = 2)
{ {
return '/parts/ldraw/'.($color !== null ? $color : '-1').'/'.$number.'.png';
}
public function setImage($number)
{
return '/sets/'.strtolower($number).'.jpg';
}
public function bytesToSize($bytes, $precision = 2) {
return $this->formatTransformer->bytesToSize($bytes, $precision); return $this->formatTransformer->bytesToSize($bytes, $precision);
} }
/**
* @param string $url
*
* @return bool
*/
public function remoteFileExists($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $status === 200 ? true : false;
}
public function remoteSize($url) public function remoteSize($url)
{ {
$ch = curl_init($url); $ch = curl_init($url);