partkeepr

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

commit 5b597b4fd35a691371c4aac5dd91f1a75e97d81b
parent 42ed0e723ff5e9bab19c9cebc88adcc38bf0b62a
Author: Felicitus <felicitus@felicitus.org>
Date:   Thu,  2 Jul 2015 00:30:01 +0200

Added new image controller for PartKeepr images, added ManufacturerIcLogoController

Diffstat:
Mapp/AppKernel.php | 1+
Mapp/config/config.yml | 1+
Aapp/config/partkeepr.yml | 5+++++
Asrc/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr-legacy.css | 228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css | 235+++++--------------------------------------------------------------------------
Asrc/PartKeepr/ImageBundle/Controller/ImageController.php | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/ImageBundle/DependencyInjection/Configuration.php | 39+++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/ImageBundle/DependencyInjection/PartKeeprExtension.php | 25+++++++++++++++++++++++++
Asrc/PartKeepr/ImageBundle/PartKeeprImageBundle.php | 13+++++++++++++
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/LICENSE.txt | 202+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Bold.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-BoldItalic.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-ExtraBold.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-ExtraBoldItalic.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Italic.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Light.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-LightItalic.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Regular.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Semibold.ttf | 0
Asrc/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-SemiboldItalic.ttf | 0
Asrc/PartKeepr/ImageBundle/Response/ImageNotFoundResponse.php | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/PartKeepr/ManufacturerBundle/Controller/ManufacturerIcLogoController.php | 27+++++++++++++++++++++++++++
Msrc/PartKeepr/ManufacturerBundle/Entity/Manufacturer.php | 14++++++++++++--
Msrc/backend/PartKeepr/Image/Image.php | 137+++----------------------------------------------------------------------------
24 files changed, 790 insertions(+), 356 deletions(-)

diff --git a/app/AppKernel.php b/app/AppKernel.php @@ -80,6 +80,7 @@ class AppKernel extends Kernel $bundles[] = new PartKeepr\PartBundle\PartKeeprPartBundle(); $bundles[] = new PartKeepr\DistributorBundle\PartKeeprDistributorBundle(); $bundles[] = new PartKeepr\ManufacturerBundle\PartKeeprManufacturerBundle(); + $bundles[] = new PartKeepr\ImageBundle\PartKeeprImageBundle(); return $bundles; } diff --git a/app/config/config.yml b/app/config/config.yml @@ -1,6 +1,7 @@ imports: - { resource: parameters.yml } - { resource: security.yml } + - { resource: partkeepr.yml } fos_rest: body_listener: true diff --git a/app/config/partkeepr.yml b/app/config/partkeepr.yml @@ -0,0 +1,4 @@ +partkeepr: + image_cache_directory: %kernel.cache_dir%/imagecache/ + images: + iclogo: %kernel.root_dir%/../data/images/iclogo/+ \ No newline at end of file diff --git a/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr-legacy.css b/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr-legacy.css @@ -0,0 +1,228 @@ +.x-form-spinner-down { + right: 16px; +} + +.manufacturer-ic-logos .thumb{ + background: #ffffff; + padding: 3px; + +} + +.x-trigger-cell:last-child .x-form-trigger { + border-bottom-right-radius: 5px; + border-top-right-radius: 5px; + border: 1px solid #B5B8C8; + border-left-width: 0; +} + +.x-form-spinner-up { + border-top-right-radius: 5px; + border-right: 1px solid #B5B8C8 !important; + border-bottom: 0 !important; + border-top: 1px solid #B5B8C8 !important; +} + +.x-form-spinner-down { + border-bottom-right-radius: 5px; + border-bottom-width: 1px !important; + border-top: 0 !important; + border-right: 1px solid #B5B8C8 !important; + border-bottom: 1px solid #B5B8C8 !important; + +} +.x-form-trigger { + background-color: white; + border: 1px solid #B5B8C8; + border-left-width: 0; + border-right-width: 0; +} + +.x-form-trigger-input-cell .x-form-field { + border-right-width: 0; + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.manufacturer-ic-logos .thumb-wrap{ + display: inline-block; + margin: 4px; + margin-right: 0; + padding: 5px; +} + +.manufacturer-ic-logos .thumb-wrap span{ + display: block; + overflow: hidden; + text-align: center; +} + +.manufacturer-ic-logos .x-view-over{ + border:1px solid #dddddd; + background: #efefef url(../../../../../frontend/resources/images/over.gif) repeat-x left top; + padding: 4px; +} + +.manufacturer-ic-logos .x-item-selected{ + background: #eff5fb url(../../../../../frontend/resources/images/selected.gif) no-repeat right bottom; + border:1px solid #99bbe8; + padding: 4px; +} +.manufacturer-ic-logos .x-view-selected .thumb{ + background:transparent; +} + +.manufacturer-ic-logos .thumb-wrap span { + cursor: default; +} + +.partdisplay h1 { + font-size: 2em; +} + +div.partdisplay td { + padding: 2px; + vertical-align: top; +} + +div.partdisplay table { + width: 100%; +} +td.e { + background-color: #eeeeee; +} + +td.e2 { + background-color: #dddddd; +} + +td.o { + background-color: #cccccc; +} + +td.o2 { + background-color: #bbbbbb; +} + +.remoteimagefield { + border: 1px solid black; +} + +#loading { position: absolute; width: 180px; margin: -70px 0 0 -90px; height: 140px; top: 50%; left: 50%; } +#loading .logo { background: url(../../../../../frontend/resources/images/loading.gif) no-repeat; position: absolute; display: block; top: 25px; left: 22px; width: 120px; height: 120px; } + +.icon-footprint { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/fingerprint.png) !important; +} + +.icon-system-monitor { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/system-monitor.png) !important; +} + +.icon-chart-bar { + background-image: url(../../../../../frontend/resources/silkicons/chart_bar.png) !important; +} + +.icon-wooden-box { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/wooden-box.png) !important; +} + +.icon-unit { + background-image: url(../../../../../frontend/resources/icons/unit.png) !important; +} + +.icon-building { + background-image: url(../../../../../frontend/resources/silkicons/building.png) !important; +} + +.icon-lorry { + background-image: url(../../../../../frontend/resources/silkicons/lorry.png) !important; +} + +.icon-user { + background-image: url(../../../../../frontend/resources/silkicons/user.png) !important; +} + +.icon-ruler { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/ruler.png) !important; +} + +.icon-gear { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/gear.png) !important; +} + +.icon-drive-upload { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/drive-upload.png) !important; +} + +.icon-infocard { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/infocard.png) !important; +} + +.icon-drill { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/drill.png) !important; +} + +.icon-service-bell { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/service-bell.png) !important; +} + +.icon-brick { + background-image: url(../../../../../frontend/resources/silkicons/brick.png) !important; +} + +.icon-table { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/table.png) !important; +} + +.icon-attach { + background-image: url(../../../../../frontend/resources/silkicons/attach.png) !important; +} + +.icon-notebook { + background-image: url(../../../../../frontend/resources/fugue-icons/icons/notebook.png) !important; +} + +.x-char-picker { + width:520px; + height:286px; + cursor:pointer +} + +.x-char-picker a { + border:1px solid #fff; + float:left; + padding:2px; + text-decoration:none; + -moz-outline: 0 none; + outline:0 none; + cursor:pointer; + color: black; +} + +.x-char-picker a:hover, .x-char-picker a.x-char-picker-selected { + border-color:#8bb8f3; + background-color:#deecfd; +} + +.x-char-picker em { + display:block; + border:1px solid #aca899 +} + +.x-char-picker em span { + cursor:pointer; + display:block; + height:18px; + vertical-align: top; + text-align: center; + width:18px; + line-height:18px +} + +.x-form-trigger-help { + background-image: url('../../../../../frontend/resources/images/trigger-help.gif'),-webkit-linear-gradient(top, #dee3e6 0%, #fcfcfd 12%, #fff 100%); +} + +.x-form-trigger-link { + background-image: url('../../../../../frontend/resources/images/trigger-link.png'),-webkit-linear-gradient(top, #dee3e6 0%, #fcfcfd 12%, #fff 100%); +} + diff --git a/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css b/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css @@ -1,226 +1,19 @@ -.x-form-spinner-down { - right: 16px; +.dataview-multisort-item { + float: left; + padding: 8px; + margin: 8px 8px 4px 8px; } -.manufacturer-ic-logos .thumb{ - background: #ffffff; - padding: 3px; +.iclogo { + display: flex; + justify-content: center; + align-items: center; + width: 100px; + height: 100px; } -.x-trigger-cell:last-child .x-form-trigger { - border-bottom-right-radius: 5px; - border-top-right-radius: 5px; - border: 1px solid #B5B8C8; - border-left-width: 0; -} - -.x-form-spinner-up { - border-top-right-radius: 5px; - border-right: 1px solid #B5B8C8 !important; - border-bottom: 0 !important; - border-top: 1px solid #B5B8C8 !important; -} - -.x-form-spinner-down { - border-bottom-right-radius: 5px; - border-bottom-width: 1px !important; - border-top: 0 !important; - border-right: 1px solid #B5B8C8 !important; - border-bottom: 1px solid #B5B8C8 !important; - -} -.x-form-trigger { - background-color: white; - border: 1px solid #B5B8C8; - border-left-width: 0; - border-right-width: 0; -} - -.x-form-trigger-input-cell .x-form-field { - border-right-width: 0; - border-bottom-right-radius: 0; - border-top-right-radius: 0; -} -.manufacturer-ic-logos .thumb-wrap{ - display: inline-block; - margin: 4px; - margin-right: 0; - padding: 5px; -} - -.manufacturer-ic-logos .thumb-wrap span{ - display: block; - overflow: hidden; - text-align: center; -} - -.manufacturer-ic-logos .x-view-over{ - border:1px solid #dddddd; - background: #efefef url(../../../../../frontend/resources/images/over.gif) repeat-x left top; - padding: 4px; -} - -.manufacturer-ic-logos .x-item-selected{ - background: #eff5fb url(../../../../../frontend/resources/images/selected.gif) no-repeat right bottom; - border:1px solid #99bbe8; - padding: 4px; -} -.manufacturer-ic-logos .x-view-selected .thumb{ - background:transparent; -} - -.manufacturer-ic-logos .thumb-wrap span { - cursor: default; -} - -.partdisplay h1 { - font-size: 2em; -} - -div.partdisplay td { - padding: 2px; - vertical-align: top; -} - -div.partdisplay table { - width: 100%; -} -td.e { - background-color: #eeeeee; -} - -td.e2 { - background-color: #dddddd; -} - -td.o { - background-color: #cccccc; -} - -td.o2 { - background-color: #bbbbbb; -} - -.remoteimagefield { - border: 1px solid black; -} - -#loading { position: absolute; width: 180px; margin: -70px 0 0 -90px; height: 140px; top: 50%; left: 50%; } -#loading .logo { background: url(../../../../../frontend/resources/images/loading.gif) no-repeat; position: absolute; display: block; top: 25px; left: 22px; width: 120px; height: 120px; } - -.icon-footprint { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/fingerprint.png) !important; -} - -.icon-system-monitor { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/system-monitor.png) !important; -} - -.icon-chart-bar { - background-image: url(../../../../../frontend/resources/silkicons/chart_bar.png) !important; -} - -.icon-wooden-box { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/wooden-box.png) !important; -} - -.icon-unit { - background-image: url(../../../../../frontend/resources/icons/unit.png) !important; -} - -.icon-building { - background-image: url(../../../../../frontend/resources/silkicons/building.png) !important; -} - -.icon-lorry { - background-image: url(../../../../../frontend/resources/silkicons/lorry.png) !important; -} - -.icon-user { - background-image: url(../../../../../frontend/resources/silkicons/user.png) !important; -} - -.icon-ruler { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/ruler.png) !important; -} - -.icon-gear { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/gear.png) !important; -} - -.icon-drive-upload { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/drive-upload.png) !important; -} - -.icon-infocard { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/infocard.png) !important; -} - -.icon-drill { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/drill.png) !important; -} - -.icon-service-bell { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/service-bell.png) !important; -} - -.icon-brick { - background-image: url(../../../../../frontend/resources/silkicons/brick.png) !important; -} - -.icon-table { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/table.png) !important; -} - -.icon-attach { - background-image: url(../../../../../frontend/resources/silkicons/attach.png) !important; -} - -.icon-notebook { - background-image: url(../../../../../frontend/resources/fugue-icons/icons/notebook.png) !important; -} - -.x-char-picker { - width:520px; - height:286px; - cursor:pointer -} - -.x-char-picker a { - border:1px solid #fff; - float:left; - padding:2px; - text-decoration:none; - -moz-outline: 0 none; - outline:0 none; - cursor:pointer; - color: black; -} - -.x-char-picker a:hover, .x-char-picker a.x-char-picker-selected { - border-color:#8bb8f3; - background-color:#deecfd; -} - -.x-char-picker em { - display:block; - border:1px solid #aca899 -} - -.x-char-picker em span { - cursor:pointer; - display:block; - height:18px; - vertical-align: top; - text-align: center; - width:18px; - line-height:18px -} - -.x-form-trigger-help { - background-image: url('../../../../../frontend/resources/images/trigger-help.gif'),-webkit-linear-gradient(top, #dee3e6 0%, #fcfcfd 12%, #fff 100%); -} - -.x-form-trigger-link { - background-image: url('../../../../../frontend/resources/images/trigger-link.png'),-webkit-linear-gradient(top, #dee3e6 0%, #fcfcfd 12%, #fff 100%); +/* @todo Check if this is needed with ExtJS 6 */ +.x-item-selected { + outline: 1px solid #157fcc !important; + outline-offset: -1px; } \ No newline at end of file diff --git a/src/PartKeepr/ImageBundle/Controller/ImageController.php b/src/PartKeepr/ImageBundle/Controller/ImageController.php @@ -0,0 +1,166 @@ +<?php +namespace PartKeepr\ImageBundle\Controller; + +use Doctrine\ORM\EntityManager; +use Imagine\Gd\Imagine; +use Imagine\Image\Box; +use Imagine\Image\Point; +use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use PartKeepr\Image\CachedImage; +use PartKeepr\Image\Image as PartKeeprImage; +use PartKeepr\ImageBundle\Response\ImageNotFoundResponse; +use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +abstract class ImageController extends Controller +{ + /** + * + * @ApiDoc( + * description="Returns a scaled and cached image. Note that the binary data is directly returned.", + * parameters={ + * {"name"="width", "dataType"="integer", "required"=true, "description"="The width in pixels"}, + * {"name"="height", "dataType"="integer", "required"=true, "description"="The height in pixels"} + * } + * ) + * + * @param Request $request + * @param $id + * + * @return ImageNotFoundResponse|Response + */ + public function getImageAction(Request $request, $id) + { + /** + * @var $em EntityManager + */ + $em = $this->getDoctrine()->getManager(); + + /** + * @var $image PartKeeprImage + */ + $image = $em->find($this->getEntityClass(), $id); + + if ($image === null) { + return new ImageNotFoundResponse($request->get("width"), $request->get("height")); + } + + $width = $request->get("width"); + $height = $request->get("height"); + + if ($width == 0) { + $width = 200; + } + + if ($height == 0) { + $height = 200; + } + + $file = $this->fitWithin($image, $width, $height); + + return new Response(file_get_contents($file), 200, array("Content-Type" => "image/png")); + + } + + /** + * Returns the path to the image cache directory. + * @return string + */ + public function getImageCacheDirectory() + { + return $this->container->getParameter("partkeepr.image_cache_directory"); + } + + /** + * Ensures that the image cache directory exists. + * + * @todo Implement checks if the cache directory has actually been created + * @todo 0777 might not be the best solution + */ + public function ensureCacheDirExists() + { + if (!is_dir($this->getImageCacheDirectory())) { + mkdir($this->getImageCacheDirectory(), 0777, true); + } + } + + /** + * Scales the image to fit within the given size. + * + * @param int $width The width + * @param int $height The height + * @param boolean $padding If true, pad the output image to the given size (transparent background). + * + * @return string The path to the scaled file + */ + public function fitWithin(PartKeeprImage $image, $width, $height, $padding = false) + { + $this->ensureCacheDirExists(); + + if ($padding) { + $mode = "fwp"; + } else { + $mode = "fw"; + } + + $outputFile = $this->getImageCacheFilename($image, $width, $height, $mode); + + if (file_exists($outputFile)) { + return $outputFile; + } + + $imagine = new Imagine(); + $imagine->open($this->getFilename($image)) + ->thumbnail(new Box($width, $height)) + ->save($outputFile); + + $cachedImage = new CachedImage($image, $outputFile); + $this->getDoctrine()->getManager()->persist($cachedImage); + + return $outputFile; + } + + /** + * Returns the full path for the image + * @param PartKeeprImage $image + * + * @return string + */ + public function getFilename(PartKeeprImage $image) + { + return realpath($this->getImageStorageDirectory())."/".$image->getPlainFilename().".png"; + } + + /** + * Returns the path to an image which has been cached in a particular width, height and mode. + * + * @param PartKeeprImage $image The image + * @param integer $width The width + * @param integer $height The height + * @param string $mode The mode + * + * @return string + */ + public function getImageCacheFilename(PartKeeprImage $image, $width, $height, $mode) + { + $outputFile = realpath($this->getImageCacheDirectory()); + $outputFile .= "/".sha1($image->getFilename()); + $outputFile .= $width."x".$height."_".$mode.".png"; + + return $outputFile; + } + + /** + * Returns the entity class (FQDN) for operation, e.g. "PartKeepr\\ManufacturerBundle\\Entity\\ManufacturerICLogo" + * + * @return string + */ + abstract public function getEntityClass (); + + /** + * Returns the path to the images. + * @return string + */ + abstract public function getImageStorageDirectory (); +}+ \ No newline at end of file diff --git a/src/PartKeepr/ImageBundle/DependencyInjection/Configuration.php b/src/PartKeepr/ImageBundle/DependencyInjection/Configuration.php @@ -0,0 +1,39 @@ +<?php +namespace PartKeepr\ImageBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + + +/** + * This is the class that validates and merges configuration from your app/config files + * + * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} + */ +class Configuration implements ConfigurationInterface +{ + /** + * {@inheritdoc} + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('partkeepr'); + + $rootNode-> + children() + ->scalarNode('image_cache_directory')->cannotBeEmpty()->isRequired()->info('The image cache directory')->end() + ->arrayNode('images') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('iclogo')->defaultValue('%kernel.root_dir%/../data/images/iclogo/')->cannotBeEmpty()->info('The directory which contains the uploaded ic logos')->end() + ->end() + ->end() + ->end(); + // Here you should define the parameters that are allowed to + // configure your bundle. See the documentation linked above for + // more information on that topic. + + return $treeBuilder; + } +} diff --git a/src/PartKeepr/ImageBundle/DependencyInjection/PartKeeprExtension.php b/src/PartKeepr/ImageBundle/DependencyInjection/PartKeeprExtension.php @@ -0,0 +1,24 @@ +<?php +namespace PartKeepr\ImageBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; + +class PartKeeprExtension extends Extension +{ + /** + * {@inheritDoc} + */ + public function load(array $configs, ContainerBuilder $container) + { + $configuration = new Configuration(); + $config = $this->processConfiguration($configuration, $configs); + + $container->setParameter('partkeepr.image_cache_directory', $config['image_cache_directory']); + $container->setParameter('partkeepr.images.iclogo', $config['images']['iclogo']); + } + + public function getAlias () { + return "partkeepr"; + } +}+ \ No newline at end of file diff --git a/src/PartKeepr/ImageBundle/PartKeeprImageBundle.php b/src/PartKeepr/ImageBundle/PartKeeprImageBundle.php @@ -0,0 +1,13 @@ +<?php +namespace PartKeepr\ImageBundle; + +use PartKeepr\ImageBundle\DependencyInjection\PartKeeprExtension; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class PartKeeprImageBundle extends Bundle +{ + public function getContainerExtension() + { + return new PartKeeprExtension(); + } +} diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/LICENSE.txt b/src/PartKeepr/ImageBundle/Resources/public/fonts/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Bold.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Bold.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-BoldItalic.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-BoldItalic.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-ExtraBold.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-ExtraBold.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-ExtraBoldItalic.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-ExtraBoldItalic.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Italic.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Italic.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Light.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Light.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-LightItalic.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-LightItalic.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Regular.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Regular.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Semibold.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-Semibold.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-SemiboldItalic.ttf b/src/PartKeepr/ImageBundle/Resources/public/fonts/OpenSans-SemiboldItalic.ttf Binary files differ. diff --git a/src/PartKeepr/ImageBundle/Response/ImageNotFoundResponse.php b/src/PartKeepr/ImageBundle/Response/ImageNotFoundResponse.php @@ -0,0 +1,51 @@ +<?php +namespace PartKeepr\ImageBundle\Response; + +use Imagine\Gd\Imagine; +use Imagine\Image\Box; +use Imagine\Image\Point; +use Symfony\Component\HttpFoundation\Response; + +class ImageNotFoundResponse extends Response +{ + /** + * Constructs a new ImageNotFoundResponse + * @param mixed|string $maxWidth + * @param int $maxHeight + */ + public function __construct ($maxWidth, $maxHeight) { + if ($maxWidth == 0) { + $maxWidth = 300; + } + + if ($maxHeight == 0) { + $maxHeight = 300; + } + + $imagine = new Imagine(); + + $size = new Box(300, 300); + $image = $imagine->create($size); + + $black = $image->palette()->color("000"); + + $path = realpath(__DIR__ . + "/../Resources/public/fonts/OpenSans-Regular.ttf" + ); + + $font = $imagine->font($path, 24, $black); + + $image->draw()->text("404 Not Found", $font, new Point(0, 0)); + + $box = $image->getSize(); + $box = $box->widen($maxWidth); + + if ($box->getHeight() > $maxHeight) { + $box = $box->heighten($maxHeight); + } + + $image->resize($box); + + return parent::__construct($image->get("png"), 404, array("Content-Type" => "image/png")); + } +}+ \ No newline at end of file diff --git a/src/PartKeepr/ManufacturerBundle/Controller/ManufacturerIcLogoController.php b/src/PartKeepr/ManufacturerBundle/Controller/ManufacturerIcLogoController.php @@ -0,0 +1,26 @@ +<?php +namespace PartKeepr\ManufacturerBundle\Controller; + + +use PartKeepr\ImageBundle\Controller\ImageController; + + +class ManufacturerIcLogoController extends ImageController +{ + + /** + * @inheritdoc + */ + public function getImageStorageDirectory() + { + return $this->container->getParameter("partkeepr.images.iclogo"); + } + + /** + * @inheritdoc + */ + public function getEntityClass () { + return "PartKeepr\\ManufacturerBundle\\Entity\\ManufacturerICLogo"; + } + +}+ \ No newline at end of file diff --git a/src/PartKeepr/ManufacturerBundle/Entity/Manufacturer.php b/src/PartKeepr/ManufacturerBundle/Entity/Manufacturer.php @@ -1,9 +1,9 @@ <?php namespace PartKeepr\ManufacturerBundle\Entity; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use PartKeepr\DoctrineReflectionBundle\Annotation\TargetService; -use PartKeepr\Manufacturer\ArrayCollection; use PartKeepr\Util\BaseEntity; use Symfony\Component\Serializer\Annotation\Groups; @@ -220,7 +220,7 @@ class Manufacturer extends BaseEntity */ public function setURL($url) { - $this->url = $url; + //$this->url = $url; } /** @@ -242,4 +242,14 @@ class Manufacturer extends BaseEntity { return $this->icLogos; } + + /** + * Sets the IC Logos + * + * @param $array + */ + public function setICLogos($array) + { + $this->icLogos = $array; + } } \ No newline at end of file diff --git a/src/backend/PartKeepr/Image/Image.php b/src/backend/PartKeepr/Image/Image.php @@ -1,12 +1,10 @@ <?php namespace PartKeepr\Image; -use PartKeepr\PartKeepr, - PartKeepr\UploadedFile\UploadedFile, - PartKeepr\Util\Configuration, - PartKeepr\TempImage\TempImage, - PartKeepr\Image\Exceptions\InvalidImageTypeException, - Doctrine\ORM\Mapping as ORM; +use Doctrine\ORM\Mapping as ORM; +use PartKeepr\Image\Exceptions\InvalidImageTypeException; +use PartKeepr\TempImage\TempImage; +use PartKeepr\UploadedFile\UploadedFile; /** * This is only a storage class; actual image rendering is done by the ImageRenderer. @@ -84,133 +82,6 @@ abstract class Image extends UploadedFile implements RenderableImage { } /** - * Returns the full image filename including path. - * This is the image where all scale operations take place on. - * - * @param none - * @return string The full image filename including path. - */ - public function getFilename () { - return $this->getFilePath().$this->getPlainFilename().".png"; - } - - /** - * Returns the path to the image. May be overridden by - * subclasses. - * - * @param none - * @return string The path to the image - */ - public function getFilePath () { - return Configuration::getOption( - "partkeepr.images.path", - PartKeepr::getRootDirectory() . "/data/images/") . $this->getType() . "/"; - } - - /** - * Ensures that the image cache dir exists. - */ - public function ensureCachedirExists () { - if (!is_dir(Configuration::getOption("partkeepr.images.cache"))) { - mkdir(Configuration::getOption("partkeepr.images.cache"), 0777, true); - } - } - - /** - * Scales the image to fit within the given size. - * - * @param int $w The width - * @param int $h The height - * @param boolean $padding If true, pad the output image to the given size (transparent background). - * @return string The path to the scaled file - */ - public function fitWithin ($w, $h, $padding = false) { - $this->ensureCachedirExists(); - - if ($padding) { - $pd = "p"; - } else { - $pd = ""; - } - - $outputFile = Configuration::getOption("partkeepr.images.cache").md5($this->getFilename().$w."x".$h."fw".$pd).".png"; - - if (file_exists($outputFile)) { - return $outputFile; - } - - $this->getRenderer()->fitWithin($outputFile, $w, $h, $padding); - - $cachedImage = new CachedImage($this, $outputFile); - PartKeepr::getEM()->persist($cachedImage); - - return $outputFile; - } - - /** - * Convinience method for fitWithin. Automatically pads the image. - * - * @param int $w The width - * @param int $h The height - * @return string The path to the scaled file - */ - public function fitWithinPadding ($w, $h) { - return $this->fitWithin($w, $h, true); - } - - /** - * Scales the image to fit exactly within the given size. - * - * This method ensures that no blank space is in the output image, - * and that the output image is exactly the width and height specified. - * - * @param string $outputFile The output file - * @param int $w The width - * @param int $h The height - * @return string The path to the scaled file - */ - public function fitWithinExact ($w, $h) { - $this->ensureCachedirExists(); - - $outputFile = Configuration::getOption("partkeepr.images.cache").md5($this->getFilename().$w."x".$h."fwe").".png"; - - if (file_exists($outputFile)) { - return $outputFile; - } - - $this->getRenderer()->fitWithinExact($outputFile, $w, $h); - - $cachedImage = new CachedImage($this, $outputFile); - PartKeepr::getEM()->persist($cachedImage); - - return $outputFile; - } - - /** - * Scales the image to a specific width and height - * - * @param int $w The width - * @param int $h The height - * @return string The path to the scaled file - */ - public function scaleTo ($w, $h) { - $this->ensureCachedirExists(); - - $outputFile = Configuration::getOption("partkeepr.images.cache").md5($this->getFilename().$w."x".$h).".png"; - - if (file_exists($outputFile)) { - return $outputFile; - } - - $this->getRenderer()->scaleTo($outputFile, $w, $h); - - $cachedImage = new CachedImage($this, $outputFile); - PartKeepr::getEM()->persist($cachedImage); - - return $outputFile; - } - - /** * Replaces the file with a given temporary file. * @param string $id The temporary id (prefixed with TMP:) */