From 845a2f9f73c6b45f7d6e1c291034b9ce211869d3 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 10:43:07 +0200 Subject: [PATCH 01/11] Typo: fixed ProdutImage -> ProductImage --- core/lib/Thelia/Model/Base/Product.php | 206 +- core/lib/Thelia/Model/Base/ProductQuery.php | 42 +- core/lib/Thelia/Model/Base/ProdutImage.php | 1990 ----------------- .../lib/Thelia/Model/Base/ProdutImageI18n.php | 1439 ------------ .../Model/Base/ProdutImageI18nQuery.php | 607 ----- .../Thelia/Model/Base/ProdutImageQuery.php | 846 ------- core/lib/Thelia/Model/Map/ProductTableMap.php | 4 +- .../Model/Map/ProdutImageI18nTableMap.php | 497 ---- .../Thelia/Model/Map/ProdutImageTableMap.php | 475 ---- core/lib/Thelia/Model/ProdutImage.php | 10 - core/lib/Thelia/Model/ProdutImageI18n.php | 10 - .../lib/Thelia/Model/ProdutImageI18nQuery.php | 21 - core/lib/Thelia/Model/ProdutImageQuery.php | 21 - local/config/schema.xml | 2 +- 14 files changed, 127 insertions(+), 6043 deletions(-) delete mode 100644 core/lib/Thelia/Model/Base/ProdutImage.php delete mode 100644 core/lib/Thelia/Model/Base/ProdutImageI18n.php delete mode 100644 core/lib/Thelia/Model/Base/ProdutImageI18nQuery.php delete mode 100644 core/lib/Thelia/Model/Base/ProdutImageQuery.php delete mode 100644 core/lib/Thelia/Model/Map/ProdutImageI18nTableMap.php delete mode 100644 core/lib/Thelia/Model/Map/ProdutImageTableMap.php delete mode 100644 core/lib/Thelia/Model/ProdutImage.php delete mode 100644 core/lib/Thelia/Model/ProdutImageI18n.php delete mode 100644 core/lib/Thelia/Model/ProdutImageI18nQuery.php delete mode 100644 core/lib/Thelia/Model/ProdutImageQuery.php diff --git a/core/lib/Thelia/Model/Base/Product.php b/core/lib/Thelia/Model/Base/Product.php index 854c88ccb..9a1828e25 100644 --- a/core/lib/Thelia/Model/Base/Product.php +++ b/core/lib/Thelia/Model/Base/Product.php @@ -34,13 +34,13 @@ use Thelia\Model\ProductDocument as ChildProductDocument; use Thelia\Model\ProductDocumentQuery as ChildProductDocumentQuery; use Thelia\Model\ProductI18n as ChildProductI18n; use Thelia\Model\ProductI18nQuery as ChildProductI18nQuery; +use Thelia\Model\ProductImage as ChildProductImage; +use Thelia\Model\ProductImageQuery as ChildProductImageQuery; use Thelia\Model\ProductQuery as ChildProductQuery; use Thelia\Model\ProductSaleElements as ChildProductSaleElements; use Thelia\Model\ProductSaleElementsQuery as ChildProductSaleElementsQuery; use Thelia\Model\ProductVersion as ChildProductVersion; use Thelia\Model\ProductVersionQuery as ChildProductVersionQuery; -use Thelia\Model\ProdutImage as ChildProdutImage; -use Thelia\Model\ProdutImageQuery as ChildProdutImageQuery; use Thelia\Model\Rewriting as ChildRewriting; use Thelia\Model\RewritingQuery as ChildRewritingQuery; use Thelia\Model\TaxRule as ChildTaxRule; @@ -174,10 +174,10 @@ abstract class Product implements ActiveRecordInterface protected $collContentAssocsPartial; /** - * @var ObjectCollection|ChildProdutImage[] Collection to store aggregation of ChildProdutImage objects. + * @var ObjectCollection|ChildProductImage[] Collection to store aggregation of ChildProductImage objects. */ - protected $collProdutImages; - protected $collProdutImagesPartial; + protected $collProductImages; + protected $collProductImagesPartial; /** * @var ObjectCollection|ChildProductDocument[] Collection to store aggregation of ChildProductDocument objects. @@ -312,7 +312,7 @@ abstract class Product implements ActiveRecordInterface * An array of objects scheduled for deletion. * @var ObjectCollection */ - protected $produtImagesScheduledForDeletion = null; + protected $productImagesScheduledForDeletion = null; /** * An array of objects scheduled for deletion. @@ -1139,7 +1139,7 @@ abstract class Product implements ActiveRecordInterface $this->collContentAssocs = null; - $this->collProdutImages = null; + $this->collProductImages = null; $this->collProductDocuments = null; @@ -1464,17 +1464,17 @@ abstract class Product implements ActiveRecordInterface } } - if ($this->produtImagesScheduledForDeletion !== null) { - if (!$this->produtImagesScheduledForDeletion->isEmpty()) { - \Thelia\Model\ProdutImageQuery::create() - ->filterByPrimaryKeys($this->produtImagesScheduledForDeletion->getPrimaryKeys(false)) + if ($this->productImagesScheduledForDeletion !== null) { + if (!$this->productImagesScheduledForDeletion->isEmpty()) { + \Thelia\Model\ProductImageQuery::create() + ->filterByPrimaryKeys($this->productImagesScheduledForDeletion->getPrimaryKeys(false)) ->delete($con); - $this->produtImagesScheduledForDeletion = null; + $this->productImagesScheduledForDeletion = null; } } - if ($this->collProdutImages !== null) { - foreach ($this->collProdutImages as $referrerFK) { + if ($this->collProductImages !== null) { + foreach ($this->collProductImages as $referrerFK) { if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { $affectedRows += $referrerFK->save($con); } @@ -1851,8 +1851,8 @@ abstract class Product implements ActiveRecordInterface if (null !== $this->collContentAssocs) { $result['ContentAssocs'] = $this->collContentAssocs->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } - if (null !== $this->collProdutImages) { - $result['ProdutImages'] = $this->collProdutImages->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + if (null !== $this->collProductImages) { + $result['ProductImages'] = $this->collProductImages->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } if (null !== $this->collProductDocuments) { $result['ProductDocuments'] = $this->collProductDocuments->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); @@ -2096,9 +2096,9 @@ abstract class Product implements ActiveRecordInterface } } - foreach ($this->getProdutImages() as $relObj) { + foreach ($this->getProductImages() as $relObj) { if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addProdutImage($relObj->copy($deepCopy)); + $copyObj->addProductImage($relObj->copy($deepCopy)); } } @@ -2248,8 +2248,8 @@ abstract class Product implements ActiveRecordInterface if ('ContentAssoc' == $relationName) { return $this->initContentAssocs(); } - if ('ProdutImage' == $relationName) { - return $this->initProdutImages(); + if ('ProductImage' == $relationName) { + return $this->initProductImages(); } if ('ProductDocument' == $relationName) { return $this->initProductDocuments(); @@ -3275,31 +3275,31 @@ abstract class Product implements ActiveRecordInterface } /** - * Clears out the collProdutImages collection + * Clears out the collProductImages collection * * This does not modify the database; however, it will remove any associated objects, causing * them to be refetched by subsequent calls to accessor method. * * @return void - * @see addProdutImages() + * @see addProductImages() */ - public function clearProdutImages() + public function clearProductImages() { - $this->collProdutImages = null; // important to set this to NULL since that means it is uninitialized + $this->collProductImages = null; // important to set this to NULL since that means it is uninitialized } /** - * Reset is the collProdutImages collection loaded partially. + * Reset is the collProductImages collection loaded partially. */ - public function resetPartialProdutImages($v = true) + public function resetPartialProductImages($v = true) { - $this->collProdutImagesPartial = $v; + $this->collProductImagesPartial = $v; } /** - * Initializes the collProdutImages collection. + * Initializes the collProductImages collection. * - * By default this just sets the collProdutImages collection to an empty array (like clearcollProdutImages()); + * By default this just sets the collProductImages collection to an empty array (like clearcollProductImages()); * however, you may wish to override this method in your stub class to provide setting appropriate * to your application -- for example, setting the initial array to the values stored in database. * @@ -3308,17 +3308,17 @@ abstract class Product implements ActiveRecordInterface * * @return void */ - public function initProdutImages($overrideExisting = true) + public function initProductImages($overrideExisting = true) { - if (null !== $this->collProdutImages && !$overrideExisting) { + if (null !== $this->collProductImages && !$overrideExisting) { return; } - $this->collProdutImages = new ObjectCollection(); - $this->collProdutImages->setModel('\Thelia\Model\ProdutImage'); + $this->collProductImages = new ObjectCollection(); + $this->collProductImages->setModel('\Thelia\Model\ProductImage'); } /** - * Gets an array of ChildProdutImage objects which contain a foreign key that references this object. + * Gets an array of ChildProductImage objects which contain a foreign key that references this object. * * If the $criteria is not null, it is used to always fetch the results from the database. * Otherwise the results are fetched from the database the first time, then cached. @@ -3328,109 +3328,109 @@ abstract class Product implements ActiveRecordInterface * * @param Criteria $criteria optional Criteria object to narrow the query * @param ConnectionInterface $con optional connection object - * @return Collection|ChildProdutImage[] List of ChildProdutImage objects + * @return Collection|ChildProductImage[] List of ChildProductImage objects * @throws PropelException */ - public function getProdutImages($criteria = null, ConnectionInterface $con = null) + public function getProductImages($criteria = null, ConnectionInterface $con = null) { - $partial = $this->collProdutImagesPartial && !$this->isNew(); - if (null === $this->collProdutImages || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collProdutImages) { + $partial = $this->collProductImagesPartial && !$this->isNew(); + if (null === $this->collProductImages || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductImages) { // return empty collection - $this->initProdutImages(); + $this->initProductImages(); } else { - $collProdutImages = ChildProdutImageQuery::create(null, $criteria) + $collProductImages = ChildProductImageQuery::create(null, $criteria) ->filterByProduct($this) ->find($con); if (null !== $criteria) { - if (false !== $this->collProdutImagesPartial && count($collProdutImages)) { - $this->initProdutImages(false); + if (false !== $this->collProductImagesPartial && count($collProductImages)) { + $this->initProductImages(false); - foreach ($collProdutImages as $obj) { - if (false == $this->collProdutImages->contains($obj)) { - $this->collProdutImages->append($obj); + foreach ($collProductImages as $obj) { + if (false == $this->collProductImages->contains($obj)) { + $this->collProductImages->append($obj); } } - $this->collProdutImagesPartial = true; + $this->collProductImagesPartial = true; } - $collProdutImages->getInternalIterator()->rewind(); + $collProductImages->getInternalIterator()->rewind(); - return $collProdutImages; + return $collProductImages; } - if ($partial && $this->collProdutImages) { - foreach ($this->collProdutImages as $obj) { + if ($partial && $this->collProductImages) { + foreach ($this->collProductImages as $obj) { if ($obj->isNew()) { - $collProdutImages[] = $obj; + $collProductImages[] = $obj; } } } - $this->collProdutImages = $collProdutImages; - $this->collProdutImagesPartial = false; + $this->collProductImages = $collProductImages; + $this->collProductImagesPartial = false; } } - return $this->collProdutImages; + return $this->collProductImages; } /** - * Sets a collection of ProdutImage objects related by a one-to-many relationship + * Sets a collection of ProductImage objects related by a one-to-many relationship * to the current object. * It will also schedule objects for deletion based on a diff between old objects (aka persisted) * and new objects from the given Propel collection. * - * @param Collection $produtImages A Propel collection. + * @param Collection $productImages A Propel collection. * @param ConnectionInterface $con Optional connection object * @return ChildProduct The current object (for fluent API support) */ - public function setProdutImages(Collection $produtImages, ConnectionInterface $con = null) + public function setProductImages(Collection $productImages, ConnectionInterface $con = null) { - $produtImagesToDelete = $this->getProdutImages(new Criteria(), $con)->diff($produtImages); + $productImagesToDelete = $this->getProductImages(new Criteria(), $con)->diff($productImages); - $this->produtImagesScheduledForDeletion = $produtImagesToDelete; + $this->productImagesScheduledForDeletion = $productImagesToDelete; - foreach ($produtImagesToDelete as $produtImageRemoved) { - $produtImageRemoved->setProduct(null); + foreach ($productImagesToDelete as $productImageRemoved) { + $productImageRemoved->setProduct(null); } - $this->collProdutImages = null; - foreach ($produtImages as $produtImage) { - $this->addProdutImage($produtImage); + $this->collProductImages = null; + foreach ($productImages as $productImage) { + $this->addProductImage($productImage); } - $this->collProdutImages = $produtImages; - $this->collProdutImagesPartial = false; + $this->collProductImages = $productImages; + $this->collProductImagesPartial = false; return $this; } /** - * Returns the number of related ProdutImage objects. + * Returns the number of related ProductImage objects. * * @param Criteria $criteria * @param boolean $distinct * @param ConnectionInterface $con - * @return int Count of related ProdutImage objects. + * @return int Count of related ProductImage objects. * @throws PropelException */ - public function countProdutImages(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + public function countProductImages(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) { - $partial = $this->collProdutImagesPartial && !$this->isNew(); - if (null === $this->collProdutImages || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collProdutImages) { + $partial = $this->collProductImagesPartial && !$this->isNew(); + if (null === $this->collProductImages || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductImages) { return 0; } if ($partial && !$criteria) { - return count($this->getProdutImages()); + return count($this->getProductImages()); } - $query = ChildProdutImageQuery::create(null, $criteria); + $query = ChildProductImageQuery::create(null, $criteria); if ($distinct) { $query->distinct(); } @@ -3440,53 +3440,53 @@ abstract class Product implements ActiveRecordInterface ->count($con); } - return count($this->collProdutImages); + return count($this->collProductImages); } /** - * Method called to associate a ChildProdutImage object to this object - * through the ChildProdutImage foreign key attribute. + * Method called to associate a ChildProductImage object to this object + * through the ChildProductImage foreign key attribute. * - * @param ChildProdutImage $l ChildProdutImage + * @param ChildProductImage $l ChildProductImage * @return \Thelia\Model\Product The current object (for fluent API support) */ - public function addProdutImage(ChildProdutImage $l) + public function addProductImage(ChildProductImage $l) { - if ($this->collProdutImages === null) { - $this->initProdutImages(); - $this->collProdutImagesPartial = true; + if ($this->collProductImages === null) { + $this->initProductImages(); + $this->collProductImagesPartial = true; } - if (!in_array($l, $this->collProdutImages->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddProdutImage($l); + if (!in_array($l, $this->collProductImages->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddProductImage($l); } return $this; } /** - * @param ProdutImage $produtImage The produtImage object to add. + * @param ProductImage $productImage The productImage object to add. */ - protected function doAddProdutImage($produtImage) + protected function doAddProductImage($productImage) { - $this->collProdutImages[]= $produtImage; - $produtImage->setProduct($this); + $this->collProductImages[]= $productImage; + $productImage->setProduct($this); } /** - * @param ProdutImage $produtImage The produtImage object to remove. + * @param ProductImage $productImage The productImage object to remove. * @return ChildProduct The current object (for fluent API support) */ - public function removeProdutImage($produtImage) + public function removeProductImage($productImage) { - if ($this->getProdutImages()->contains($produtImage)) { - $this->collProdutImages->remove($this->collProdutImages->search($produtImage)); - if (null === $this->produtImagesScheduledForDeletion) { - $this->produtImagesScheduledForDeletion = clone $this->collProdutImages; - $this->produtImagesScheduledForDeletion->clear(); + if ($this->getProductImages()->contains($productImage)) { + $this->collProductImages->remove($this->collProductImages->search($productImage)); + if (null === $this->productImagesScheduledForDeletion) { + $this->productImagesScheduledForDeletion = clone $this->collProductImages; + $this->productImagesScheduledForDeletion->clear(); } - $this->produtImagesScheduledForDeletion[]= clone $produtImage; - $produtImage->setProduct(null); + $this->productImagesScheduledForDeletion[]= clone $productImage; + $productImage->setProduct(null); } return $this; @@ -5757,8 +5757,8 @@ abstract class Product implements ActiveRecordInterface $o->clearAllReferences($deep); } } - if ($this->collProdutImages) { - foreach ($this->collProdutImages as $o) { + if ($this->collProductImages) { + foreach ($this->collProductImages as $o) { $o->clearAllReferences($deep); } } @@ -5834,10 +5834,10 @@ abstract class Product implements ActiveRecordInterface $this->collContentAssocs->clearIterator(); } $this->collContentAssocs = null; - if ($this->collProdutImages instanceof Collection) { - $this->collProdutImages->clearIterator(); + if ($this->collProductImages instanceof Collection) { + $this->collProductImages->clearIterator(); } - $this->collProdutImages = null; + $this->collProductImages = null; if ($this->collProductDocuments instanceof Collection) { $this->collProductDocuments->clearIterator(); } diff --git a/core/lib/Thelia/Model/Base/ProductQuery.php b/core/lib/Thelia/Model/Base/ProductQuery.php index 3b3ca6309..3df8ecbae 100644 --- a/core/lib/Thelia/Model/Base/ProductQuery.php +++ b/core/lib/Thelia/Model/Base/ProductQuery.php @@ -68,9 +68,9 @@ use Thelia\Model\Map\ProductTableMap; * @method ChildProductQuery rightJoinContentAssoc($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ContentAssoc relation * @method ChildProductQuery innerJoinContentAssoc($relationAlias = null) Adds a INNER JOIN clause to the query using the ContentAssoc relation * - * @method ChildProductQuery leftJoinProdutImage($relationAlias = null) Adds a LEFT JOIN clause to the query using the ProdutImage relation - * @method ChildProductQuery rightJoinProdutImage($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ProdutImage relation - * @method ChildProductQuery innerJoinProdutImage($relationAlias = null) Adds a INNER JOIN clause to the query using the ProdutImage relation + * @method ChildProductQuery leftJoinProductImage($relationAlias = null) Adds a LEFT JOIN clause to the query using the ProductImage relation + * @method ChildProductQuery rightJoinProductImage($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ProductImage relation + * @method ChildProductQuery innerJoinProductImage($relationAlias = null) Adds a INNER JOIN clause to the query using the ProductImage relation * * @method ChildProductQuery leftJoinProductDocument($relationAlias = null) Adds a LEFT JOIN clause to the query using the ProductDocument relation * @method ChildProductQuery rightJoinProductDocument($relationAlias = null) Adds a RIGHT JOIN clause to the query using the ProductDocument relation @@ -1070,40 +1070,40 @@ abstract class ProductQuery extends ModelCriteria } /** - * Filter the query by a related \Thelia\Model\ProdutImage object + * Filter the query by a related \Thelia\Model\ProductImage object * - * @param \Thelia\Model\ProdutImage|ObjectCollection $produtImage the related object to use as filter + * @param \Thelia\Model\ProductImage|ObjectCollection $productImage the related object to use as filter * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL * * @return ChildProductQuery The current query, for fluid interface */ - public function filterByProdutImage($produtImage, $comparison = null) + public function filterByProductImage($productImage, $comparison = null) { - if ($produtImage instanceof \Thelia\Model\ProdutImage) { + if ($productImage instanceof \Thelia\Model\ProductImage) { return $this - ->addUsingAlias(ProductTableMap::ID, $produtImage->getProductId(), $comparison); - } elseif ($produtImage instanceof ObjectCollection) { + ->addUsingAlias(ProductTableMap::ID, $productImage->getProductId(), $comparison); + } elseif ($productImage instanceof ObjectCollection) { return $this - ->useProdutImageQuery() - ->filterByPrimaryKeys($produtImage->getPrimaryKeys()) + ->useProductImageQuery() + ->filterByPrimaryKeys($productImage->getPrimaryKeys()) ->endUse(); } else { - throw new PropelException('filterByProdutImage() only accepts arguments of type \Thelia\Model\ProdutImage or Collection'); + throw new PropelException('filterByProductImage() only accepts arguments of type \Thelia\Model\ProductImage or Collection'); } } /** - * Adds a JOIN clause to the query using the ProdutImage relation + * Adds a JOIN clause to the query using the ProductImage relation * * @param string $relationAlias optional alias for the relation * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * * @return ChildProductQuery The current query, for fluid interface */ - public function joinProdutImage($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function joinProductImage($relationAlias = null, $joinType = Criteria::INNER_JOIN) { $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('ProdutImage'); + $relationMap = $tableMap->getRelation('ProductImage'); // create a ModelJoin object for this join $join = new ModelJoin(); @@ -1118,14 +1118,14 @@ abstract class ProductQuery extends ModelCriteria $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); $this->addJoinObject($join, $relationAlias); } else { - $this->addJoinObject($join, 'ProdutImage'); + $this->addJoinObject($join, 'ProductImage'); } return $this; } /** - * Use the ProdutImage relation ProdutImage object + * Use the ProductImage relation ProductImage object * * @see useQuery() * @@ -1133,13 +1133,13 @@ abstract class ProductQuery extends ModelCriteria * to be used as main alias in the secondary query * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' * - * @return \Thelia\Model\ProdutImageQuery A secondary query class using the current class as primary query + * @return \Thelia\Model\ProductImageQuery A secondary query class using the current class as primary query */ - public function useProdutImageQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + public function useProductImageQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) { return $this - ->joinProdutImage($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'ProdutImage', '\Thelia\Model\ProdutImageQuery'); + ->joinProductImage($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ProductImage', '\Thelia\Model\ProductImageQuery'); } /** diff --git a/core/lib/Thelia/Model/Base/ProdutImage.php b/core/lib/Thelia/Model/Base/ProdutImage.php deleted file mode 100644 index 99a39d319..000000000 --- a/core/lib/Thelia/Model/Base/ProdutImage.php +++ /dev/null @@ -1,1990 +0,0 @@ -modifiedColumns); - } - - /** - * Has specified column been modified? - * - * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID - * @return boolean True if $col has been modified. - */ - public function isColumnModified($col) - { - return in_array($col, $this->modifiedColumns); - } - - /** - * Get the columns that have been modified in this object. - * @return array A unique list of the modified column names for this object. - */ - public function getModifiedColumns() - { - return array_unique($this->modifiedColumns); - } - - /** - * Returns whether the object has ever been saved. This will - * be false, if the object was retrieved from storage or was created - * and then saved. - * - * @return true, if the object has never been persisted. - */ - public function isNew() - { - return $this->new; - } - - /** - * Setter for the isNew attribute. This method will be called - * by Propel-generated children and objects. - * - * @param boolean $b the state of the object. - */ - public function setNew($b) - { - $this->new = (Boolean) $b; - } - - /** - * Whether this object has been deleted. - * @return boolean The deleted state of this object. - */ - public function isDeleted() - { - return $this->deleted; - } - - /** - * Specify whether this object has been deleted. - * @param boolean $b The deleted state of this object. - * @return void - */ - public function setDeleted($b) - { - $this->deleted = (Boolean) $b; - } - - /** - * Sets the modified state for the object to be false. - * @param string $col If supplied, only the specified column is reset. - * @return void - */ - public function resetModified($col = null) - { - if (null !== $col) { - while (false !== ($offset = array_search($col, $this->modifiedColumns))) { - array_splice($this->modifiedColumns, $offset, 1); - } - } else { - $this->modifiedColumns = array(); - } - } - - /** - * Compares this with another ProdutImage instance. If - * obj is an instance of ProdutImage, delegates to - * equals(ProdutImage). Otherwise, returns false. - * - * @param obj The object to compare to. - * @return Whether equal to the object specified. - */ - public function equals($obj) - { - $thisclazz = get_class($this); - if (!is_object($obj) || !($obj instanceof $thisclazz)) { - return false; - } - - if ($this === $obj) { - return true; - } - - if (null === $this->getPrimaryKey() - || null === $obj->getPrimaryKey()) { - return false; - } - - return $this->getPrimaryKey() === $obj->getPrimaryKey(); - } - - /** - * If the primary key is not null, return the hashcode of the - * primary key. Otherwise, return the hash code of the object. - * - * @return int Hashcode - */ - public function hashCode() - { - if (null !== $this->getPrimaryKey()) { - return crc32(serialize($this->getPrimaryKey())); - } - - return crc32(serialize(clone $this)); - } - - /** - * Get the associative array of the virtual columns in this object - * - * @param string $name The virtual column name - * - * @return array - */ - public function getVirtualColumns() - { - return $this->virtualColumns; - } - - /** - * Checks the existence of a virtual column in this object - * - * @return boolean - */ - public function hasVirtualColumn($name) - { - return isset($this->virtualColumns[$name]); - } - - /** - * Get the value of a virtual column in this object - * - * @return mixed - */ - public function getVirtualColumn($name) - { - if (!$this->hasVirtualColumn($name)) { - throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); - } - - return $this->virtualColumns[$name]; - } - - /** - * Set the value of a virtual column in this object - * - * @param string $name The virtual column name - * @param mixed $value The value to give to the virtual column - * - * @return ProdutImage The current object, for fluid interface - */ - public function setVirtualColumn($name, $value) - { - $this->virtualColumns[$name] = $value; - - return $this; - } - - /** - * Logs a message using Propel::log(). - * - * @param string $msg - * @param int $priority One of the Propel::LOG_* logging levels - * @return boolean - */ - protected function log($msg, $priority = Propel::LOG_INFO) - { - return Propel::log(get_class($this) . ': ' . $msg, $priority); - } - - /** - * Populate the current object from a string, using a given parser format - * - * $book = new Book(); - * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); - * - * - * @param mixed $parser A AbstractParser instance, - * or a format name ('XML', 'YAML', 'JSON', 'CSV') - * @param string $data The source data to import from - * - * @return ProdutImage The current object, for fluid interface - */ - public function importFrom($parser, $data) - { - if (!$parser instanceof AbstractParser) { - $parser = AbstractParser::getParser($parser); - } - - return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); - } - - /** - * Export the current object properties to a string, using a given parser format - * - * $book = BookQuery::create()->findPk(9012); - * echo $book->exportTo('JSON'); - * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); - * - * - * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. - * @return string The exported data - */ - public function exportTo($parser, $includeLazyLoadColumns = true) - { - if (!$parser instanceof AbstractParser) { - $parser = AbstractParser::getParser($parser); - } - - return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); - } - - /** - * Clean up internal collections prior to serializing - * Avoids recursive loops that turn into segmentation faults when serializing - */ - public function __sleep() - { - $this->clearAllReferences(); - - return array_keys(get_object_vars($this)); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getId() - { - - return $this->id; - } - - /** - * Get the [product_id] column value. - * - * @return int - */ - public function getProductId() - { - - return $this->product_id; - } - - /** - * Get the [file] column value. - * - * @return string - */ - public function getFile() - { - - return $this->file; - } - - /** - * Get the [position] column value. - * - * @return int - */ - public function getPosition() - { - - return $this->position; - } - - /** - * Get the [optionally formatted] temporal [created_at] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw \DateTime object will be returned. - * - * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 - * - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getCreatedAt($format = NULL) - { - if ($format === null) { - return $this->created_at; - } else { - return $this->created_at !== null ? $this->created_at->format($format) : null; - } - } - - /** - * Get the [optionally formatted] temporal [updated_at] column value. - * - * - * @param string $format The date/time format string (either date()-style or strftime()-style). - * If format is NULL, then the raw \DateTime object will be returned. - * - * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 - * - * @throws PropelException - if unable to parse/validate the date/time value. - */ - public function getUpdatedAt($format = NULL) - { - if ($format === null) { - return $this->updated_at; - } else { - return $this->updated_at !== null ? $this->updated_at->format($format) : null; - } - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = ProdutImageTableMap::ID; - } - - - return $this; - } // setId() - - /** - * Set the value of [product_id] column. - * - * @param int $v new value - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function setProductId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->product_id !== $v) { - $this->product_id = $v; - $this->modifiedColumns[] = ProdutImageTableMap::PRODUCT_ID; - } - - if ($this->aProduct !== null && $this->aProduct->getId() !== $v) { - $this->aProduct = null; - } - - - return $this; - } // setProductId() - - /** - * Set the value of [file] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function setFile($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->file !== $v) { - $this->file = $v; - $this->modifiedColumns[] = ProdutImageTableMap::FILE; - } - - - return $this; - } // setFile() - - /** - * Set the value of [position] column. - * - * @param int $v new value - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function setPosition($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->position !== $v) { - $this->position = $v; - $this->modifiedColumns[] = ProdutImageTableMap::POSITION; - } - - - return $this; - } // setPosition() - - /** - * Sets the value of [created_at] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or \DateTime value. - * Empty strings are treated as NULL. - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function setCreatedAt($v) - { - $dt = PropelDateTime::newInstance($v, null, '\DateTime'); - if ($this->created_at !== null || $dt !== null) { - if ($dt !== $this->created_at) { - $this->created_at = $dt; - $this->modifiedColumns[] = ProdutImageTableMap::CREATED_AT; - } - } // if either are not null - - - return $this; - } // setCreatedAt() - - /** - * Sets the value of [updated_at] column to a normalized version of the date/time value specified. - * - * @param mixed $v string, integer (timestamp), or \DateTime value. - * Empty strings are treated as NULL. - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function setUpdatedAt($v) - { - $dt = PropelDateTime::newInstance($v, null, '\DateTime'); - if ($this->updated_at !== null || $dt !== null) { - if ($dt !== $this->updated_at) { - $this->updated_at = $dt; - $this->modifiedColumns[] = ProdutImageTableMap::UPDATED_AT; - } - } // if either are not null - - - return $this; - } // setUpdatedAt() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by DataFetcher->fetch(). - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). - One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) - { - try { - - - $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ProdutImageTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; - $this->id = (null !== $col) ? (int) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProdutImageTableMap::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType)]; - $this->product_id = (null !== $col) ? (int) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProdutImageTableMap::translateFieldName('File', TableMap::TYPE_PHPNAME, $indexType)]; - $this->file = (null !== $col) ? (string) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProdutImageTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; - $this->position = (null !== $col) ? (int) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProdutImageTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; - if ($col === '0000-00-00 00:00:00') { - $col = null; - } - $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProdutImageTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; - if ($col === '0000-00-00 00:00:00') { - $col = null; - } - $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 6; // 6 = ProdutImageTableMap::NUM_HYDRATE_COLUMNS. - - } catch (Exception $e) { - throw new PropelException("Error populating \Thelia\Model\ProdutImage object", 0, $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - if ($this->aProduct !== null && $this->product_id !== $this->aProduct->getId()) { - $this->aProduct = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, ConnectionInterface $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(ProdutImageTableMap::DATABASE_NAME); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $dataFetcher = ChildProdutImageQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); - $row = $dataFetcher->fetch(); - $dataFetcher->close(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aProduct = null; - $this->collProdutImageI18ns = null; - - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param ConnectionInterface $con - * @return void - * @throws PropelException - * @see ProdutImage::setDeleted() - * @see ProdutImage::isDeleted() - */ - public function delete(ConnectionInterface $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageTableMap::DATABASE_NAME); - } - - $con->beginTransaction(); - try { - $deleteQuery = ChildProdutImageQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()); - $ret = $this->preDelete($con); - if ($ret) { - $deleteQuery->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (Exception $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param ConnectionInterface $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(ConnectionInterface $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageTableMap::DATABASE_NAME); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - // timestampable behavior - if (!$this->isColumnModified(ProdutImageTableMap::CREATED_AT)) { - $this->setCreatedAt(time()); - } - if (!$this->isColumnModified(ProdutImageTableMap::UPDATED_AT)) { - $this->setUpdatedAt(time()); - } - } else { - $ret = $ret && $this->preUpdate($con); - // timestampable behavior - if ($this->isModified() && !$this->isColumnModified(ProdutImageTableMap::UPDATED_AT)) { - $this->setUpdatedAt(time()); - } - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - ProdutImageTableMap::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - - return $affectedRows; - } catch (Exception $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param ConnectionInterface $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(ConnectionInterface $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their corresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aProduct !== null) { - if ($this->aProduct->isModified() || $this->aProduct->isNew()) { - $affectedRows += $this->aProduct->save($con); - } - $this->setProduct($this->aProduct); - } - - if ($this->isNew() || $this->isModified()) { - // persist changes - if ($this->isNew()) { - $this->doInsert($con); - } else { - $this->doUpdate($con); - } - $affectedRows += 1; - $this->resetModified(); - } - - if ($this->produtImageI18nsScheduledForDeletion !== null) { - if (!$this->produtImageI18nsScheduledForDeletion->isEmpty()) { - \Thelia\Model\ProdutImageI18nQuery::create() - ->filterByPrimaryKeys($this->produtImageI18nsScheduledForDeletion->getPrimaryKeys(false)) - ->delete($con); - $this->produtImageI18nsScheduledForDeletion = null; - } - } - - if ($this->collProdutImageI18ns !== null) { - foreach ($this->collProdutImageI18ns as $referrerFK) { - if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { - $affectedRows += $referrerFK->save($con); - } - } - } - - $this->alreadyInSave = false; - - } - - return $affectedRows; - } // doSave() - - /** - * Insert the row in the database. - * - * @param ConnectionInterface $con - * - * @throws PropelException - * @see doSave() - */ - protected function doInsert(ConnectionInterface $con) - { - $modifiedColumns = array(); - $index = 0; - - $this->modifiedColumns[] = ProdutImageTableMap::ID; - if (null !== $this->id) { - throw new PropelException('Cannot insert a value for auto-increment primary key (' . ProdutImageTableMap::ID . ')'); - } - - // check the columns in natural order for more readable SQL queries - if ($this->isColumnModified(ProdutImageTableMap::ID)) { - $modifiedColumns[':p' . $index++] = 'ID'; - } - if ($this->isColumnModified(ProdutImageTableMap::PRODUCT_ID)) { - $modifiedColumns[':p' . $index++] = 'PRODUCT_ID'; - } - if ($this->isColumnModified(ProdutImageTableMap::FILE)) { - $modifiedColumns[':p' . $index++] = 'FILE'; - } - if ($this->isColumnModified(ProdutImageTableMap::POSITION)) { - $modifiedColumns[':p' . $index++] = 'POSITION'; - } - if ($this->isColumnModified(ProdutImageTableMap::CREATED_AT)) { - $modifiedColumns[':p' . $index++] = 'CREATED_AT'; - } - if ($this->isColumnModified(ProdutImageTableMap::UPDATED_AT)) { - $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; - } - - $sql = sprintf( - 'INSERT INTO produt_image (%s) VALUES (%s)', - implode(', ', $modifiedColumns), - implode(', ', array_keys($modifiedColumns)) - ); - - try { - $stmt = $con->prepare($sql); - foreach ($modifiedColumns as $identifier => $columnName) { - switch ($columnName) { - case 'ID': - $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); - break; - case 'PRODUCT_ID': - $stmt->bindValue($identifier, $this->product_id, PDO::PARAM_INT); - break; - case 'FILE': - $stmt->bindValue($identifier, $this->file, PDO::PARAM_STR); - break; - case 'POSITION': - $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); - break; - case 'CREATED_AT': - $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); - break; - case 'UPDATED_AT': - $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); - break; - } - } - $stmt->execute(); - } catch (Exception $e) { - Propel::log($e->getMessage(), Propel::LOG_ERR); - throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); - } - - try { - $pk = $con->lastInsertId(); - } catch (Exception $e) { - throw new PropelException('Unable to get autoincrement id.', 0, $e); - } - $this->setId($pk); - - $this->setNew(false); - } - - /** - * Update the row in the database. - * - * @param ConnectionInterface $con - * - * @return Integer Number of updated rows - * @see doSave() - */ - protected function doUpdate(ConnectionInterface $con) - { - $selectCriteria = $this->buildPkeyCriteria(); - $valuesCriteria = $this->buildCriteria(); - - return $selectCriteria->doUpdate($valuesCriteria, $con); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * Defaults to TableMap::TYPE_PHPNAME. - * @return mixed Value of field. - */ - public function getByName($name, $type = TableMap::TYPE_PHPNAME) - { - $pos = ProdutImageTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); - $field = $this->getByPosition($pos); - - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch ($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getProductId(); - break; - case 2: - return $this->getFile(); - break; - case 3: - return $this->getPosition(); - break; - case 4: - return $this->getCreatedAt(); - break; - case 5: - return $this->getUpdatedAt(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * Defaults to TableMap::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) - { - if (isset($alreadyDumpedObjects['ProdutImage'][$this->getPrimaryKey()])) { - return '*RECURSION*'; - } - $alreadyDumpedObjects['ProdutImage'][$this->getPrimaryKey()] = true; - $keys = ProdutImageTableMap::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getProductId(), - $keys[2] => $this->getFile(), - $keys[3] => $this->getPosition(), - $keys[4] => $this->getCreatedAt(), - $keys[5] => $this->getUpdatedAt(), - ); - $virtualColumns = $this->virtualColumns; - foreach($virtualColumns as $key => $virtualColumn) - { - $result[$key] = $virtualColumn; - } - - if ($includeForeignObjects) { - if (null !== $this->aProduct) { - $result['Product'] = $this->aProduct->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); - } - if (null !== $this->collProdutImageI18ns) { - $result['ProdutImageI18ns'] = $this->collProdutImageI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); - } - } - - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * Defaults to TableMap::TYPE_PHPNAME. - * @return void - */ - public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) - { - $pos = ProdutImageTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); - - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch ($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setProductId($value); - break; - case 2: - $this->setFile($value); - break; - case 3: - $this->setPosition($value); - break; - case 4: - $this->setCreatedAt($value); - break; - case 5: - $this->setUpdatedAt($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * The default key type is the column's TableMap::TYPE_PHPNAME. - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) - { - $keys = ProdutImageTableMap::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setProductId($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setFile($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setPosition($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setCreatedAt($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setUpdatedAt($arr[$keys[5]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(ProdutImageTableMap::DATABASE_NAME); - - if ($this->isColumnModified(ProdutImageTableMap::ID)) $criteria->add(ProdutImageTableMap::ID, $this->id); - if ($this->isColumnModified(ProdutImageTableMap::PRODUCT_ID)) $criteria->add(ProdutImageTableMap::PRODUCT_ID, $this->product_id); - if ($this->isColumnModified(ProdutImageTableMap::FILE)) $criteria->add(ProdutImageTableMap::FILE, $this->file); - if ($this->isColumnModified(ProdutImageTableMap::POSITION)) $criteria->add(ProdutImageTableMap::POSITION, $this->position); - if ($this->isColumnModified(ProdutImageTableMap::CREATED_AT)) $criteria->add(ProdutImageTableMap::CREATED_AT, $this->created_at); - if ($this->isColumnModified(ProdutImageTableMap::UPDATED_AT)) $criteria->add(ProdutImageTableMap::UPDATED_AT, $this->updated_at); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(ProdutImageTableMap::DATABASE_NAME); - $criteria->add(ProdutImageTableMap::ID, $this->id); - - return $criteria; - } - - /** - * Returns the primary key for this object (row). - * @return int - */ - public function getPrimaryKey() - { - return $this->getId(); - } - - /** - * Generic method to set the primary key (id column). - * - * @param int $key Primary key. - * @return void - */ - public function setPrimaryKey($key) - { - $this->setId($key); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - - return null === $this->getId(); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of \Thelia\Model\ProdutImage (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false, $makeNew = true) - { - $copyObj->setProductId($this->getProductId()); - $copyObj->setFile($this->getFile()); - $copyObj->setPosition($this->getPosition()); - $copyObj->setCreatedAt($this->getCreatedAt()); - $copyObj->setUpdatedAt($this->getUpdatedAt()); - - if ($deepCopy) { - // important: temporarily setNew(false) because this affects the behavior of - // the getter/setter methods for fkey referrer objects. - $copyObj->setNew(false); - - foreach ($this->getProdutImageI18ns() as $relObj) { - if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves - $copyObj->addProdutImageI18n($relObj->copy($deepCopy)); - } - } - - } // if ($deepCopy) - - if ($makeNew) { - $copyObj->setNew(true); - $copyObj->setId(NULL); // this is a auto-increment column, so set to default value - } - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return \Thelia\Model\ProdutImage Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - - return $copyObj; - } - - /** - * Declares an association between this object and a ChildProduct object. - * - * @param ChildProduct $v - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - * @throws PropelException - */ - public function setProduct(ChildProduct $v = null) - { - if ($v === null) { - $this->setProductId(NULL); - } else { - $this->setProductId($v->getId()); - } - - $this->aProduct = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the ChildProduct object, it will not be re-added. - if ($v !== null) { - $v->addProdutImage($this); - } - - - return $this; - } - - - /** - * Get the associated ChildProduct object - * - * @param ConnectionInterface $con Optional Connection object. - * @return ChildProduct The associated ChildProduct object. - * @throws PropelException - */ - public function getProduct(ConnectionInterface $con = null) - { - if ($this->aProduct === null && ($this->product_id !== null)) { - $this->aProduct = ChildProductQuery::create()->findPk($this->product_id, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aProduct->addProdutImages($this); - */ - } - - return $this->aProduct; - } - - - /** - * Initializes a collection based on the name of a relation. - * Avoids crafting an 'init[$relationName]s' method name - * that wouldn't work when StandardEnglishPluralizer is used. - * - * @param string $relationName The name of the relation to initialize - * @return void - */ - public function initRelation($relationName) - { - if ('ProdutImageI18n' == $relationName) { - return $this->initProdutImageI18ns(); - } - } - - /** - * Clears out the collProdutImageI18ns collection - * - * This does not modify the database; however, it will remove any associated objects, causing - * them to be refetched by subsequent calls to accessor method. - * - * @return void - * @see addProdutImageI18ns() - */ - public function clearProdutImageI18ns() - { - $this->collProdutImageI18ns = null; // important to set this to NULL since that means it is uninitialized - } - - /** - * Reset is the collProdutImageI18ns collection loaded partially. - */ - public function resetPartialProdutImageI18ns($v = true) - { - $this->collProdutImageI18nsPartial = $v; - } - - /** - * Initializes the collProdutImageI18ns collection. - * - * By default this just sets the collProdutImageI18ns collection to an empty array (like clearcollProdutImageI18ns()); - * however, you may wish to override this method in your stub class to provide setting appropriate - * to your application -- for example, setting the initial array to the values stored in database. - * - * @param boolean $overrideExisting If set to true, the method call initializes - * the collection even if it is not empty - * - * @return void - */ - public function initProdutImageI18ns($overrideExisting = true) - { - if (null !== $this->collProdutImageI18ns && !$overrideExisting) { - return; - } - $this->collProdutImageI18ns = new ObjectCollection(); - $this->collProdutImageI18ns->setModel('\Thelia\Model\ProdutImageI18n'); - } - - /** - * Gets an array of ChildProdutImageI18n objects which contain a foreign key that references this object. - * - * If the $criteria is not null, it is used to always fetch the results from the database. - * Otherwise the results are fetched from the database the first time, then cached. - * Next time the same method is called without $criteria, the cached collection is returned. - * If this ChildProdutImage is new, it will return - * an empty collection or the current collection; the criteria is ignored on a new object. - * - * @param Criteria $criteria optional Criteria object to narrow the query - * @param ConnectionInterface $con optional connection object - * @return Collection|ChildProdutImageI18n[] List of ChildProdutImageI18n objects - * @throws PropelException - */ - public function getProdutImageI18ns($criteria = null, ConnectionInterface $con = null) - { - $partial = $this->collProdutImageI18nsPartial && !$this->isNew(); - if (null === $this->collProdutImageI18ns || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collProdutImageI18ns) { - // return empty collection - $this->initProdutImageI18ns(); - } else { - $collProdutImageI18ns = ChildProdutImageI18nQuery::create(null, $criteria) - ->filterByProdutImage($this) - ->find($con); - - if (null !== $criteria) { - if (false !== $this->collProdutImageI18nsPartial && count($collProdutImageI18ns)) { - $this->initProdutImageI18ns(false); - - foreach ($collProdutImageI18ns as $obj) { - if (false == $this->collProdutImageI18ns->contains($obj)) { - $this->collProdutImageI18ns->append($obj); - } - } - - $this->collProdutImageI18nsPartial = true; - } - - $collProdutImageI18ns->getInternalIterator()->rewind(); - - return $collProdutImageI18ns; - } - - if ($partial && $this->collProdutImageI18ns) { - foreach ($this->collProdutImageI18ns as $obj) { - if ($obj->isNew()) { - $collProdutImageI18ns[] = $obj; - } - } - } - - $this->collProdutImageI18ns = $collProdutImageI18ns; - $this->collProdutImageI18nsPartial = false; - } - } - - return $this->collProdutImageI18ns; - } - - /** - * Sets a collection of ProdutImageI18n objects related by a one-to-many relationship - * to the current object. - * It will also schedule objects for deletion based on a diff between old objects (aka persisted) - * and new objects from the given Propel collection. - * - * @param Collection $produtImageI18ns A Propel collection. - * @param ConnectionInterface $con Optional connection object - * @return ChildProdutImage The current object (for fluent API support) - */ - public function setProdutImageI18ns(Collection $produtImageI18ns, ConnectionInterface $con = null) - { - $produtImageI18nsToDelete = $this->getProdutImageI18ns(new Criteria(), $con)->diff($produtImageI18ns); - - - //since at least one column in the foreign key is at the same time a PK - //we can not just set a PK to NULL in the lines below. We have to store - //a backup of all values, so we are able to manipulate these items based on the onDelete value later. - $this->produtImageI18nsScheduledForDeletion = clone $produtImageI18nsToDelete; - - foreach ($produtImageI18nsToDelete as $produtImageI18nRemoved) { - $produtImageI18nRemoved->setProdutImage(null); - } - - $this->collProdutImageI18ns = null; - foreach ($produtImageI18ns as $produtImageI18n) { - $this->addProdutImageI18n($produtImageI18n); - } - - $this->collProdutImageI18ns = $produtImageI18ns; - $this->collProdutImageI18nsPartial = false; - - return $this; - } - - /** - * Returns the number of related ProdutImageI18n objects. - * - * @param Criteria $criteria - * @param boolean $distinct - * @param ConnectionInterface $con - * @return int Count of related ProdutImageI18n objects. - * @throws PropelException - */ - public function countProdutImageI18ns(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) - { - $partial = $this->collProdutImageI18nsPartial && !$this->isNew(); - if (null === $this->collProdutImageI18ns || null !== $criteria || $partial) { - if ($this->isNew() && null === $this->collProdutImageI18ns) { - return 0; - } - - if ($partial && !$criteria) { - return count($this->getProdutImageI18ns()); - } - - $query = ChildProdutImageI18nQuery::create(null, $criteria); - if ($distinct) { - $query->distinct(); - } - - return $query - ->filterByProdutImage($this) - ->count($con); - } - - return count($this->collProdutImageI18ns); - } - - /** - * Method called to associate a ChildProdutImageI18n object to this object - * through the ChildProdutImageI18n foreign key attribute. - * - * @param ChildProdutImageI18n $l ChildProdutImageI18n - * @return \Thelia\Model\ProdutImage The current object (for fluent API support) - */ - public function addProdutImageI18n(ChildProdutImageI18n $l) - { - if ($l && $locale = $l->getLocale()) { - $this->setLocale($locale); - $this->currentTranslations[$locale] = $l; - } - if ($this->collProdutImageI18ns === null) { - $this->initProdutImageI18ns(); - $this->collProdutImageI18nsPartial = true; - } - - if (!in_array($l, $this->collProdutImageI18ns->getArrayCopy(), true)) { // only add it if the **same** object is not already associated - $this->doAddProdutImageI18n($l); - } - - return $this; - } - - /** - * @param ProdutImageI18n $produtImageI18n The produtImageI18n object to add. - */ - protected function doAddProdutImageI18n($produtImageI18n) - { - $this->collProdutImageI18ns[]= $produtImageI18n; - $produtImageI18n->setProdutImage($this); - } - - /** - * @param ProdutImageI18n $produtImageI18n The produtImageI18n object to remove. - * @return ChildProdutImage The current object (for fluent API support) - */ - public function removeProdutImageI18n($produtImageI18n) - { - if ($this->getProdutImageI18ns()->contains($produtImageI18n)) { - $this->collProdutImageI18ns->remove($this->collProdutImageI18ns->search($produtImageI18n)); - if (null === $this->produtImageI18nsScheduledForDeletion) { - $this->produtImageI18nsScheduledForDeletion = clone $this->collProdutImageI18ns; - $this->produtImageI18nsScheduledForDeletion->clear(); - } - $this->produtImageI18nsScheduledForDeletion[]= clone $produtImageI18n; - $produtImageI18n->setProdutImage(null); - } - - return $this; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->product_id = null; - $this->file = null; - $this->position = null; - $this->created_at = null; - $this->updated_at = null; - $this->alreadyInSave = false; - $this->clearAllReferences(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all references to other model objects or collections of model objects. - * - * This method is a user-space workaround for PHP's inability to garbage collect - * objects with circular references (even in PHP 5.3). This is currently necessary - * when using Propel in certain daemon or large-volume/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all referrer objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - if ($this->collProdutImageI18ns) { - foreach ($this->collProdutImageI18ns as $o) { - $o->clearAllReferences($deep); - } - } - } // if ($deep) - - // i18n behavior - $this->currentLocale = 'en_US'; - $this->currentTranslations = null; - - if ($this->collProdutImageI18ns instanceof Collection) { - $this->collProdutImageI18ns->clearIterator(); - } - $this->collProdutImageI18ns = null; - $this->aProduct = null; - } - - /** - * Return the string representation of this object - * - * @return string - */ - public function __toString() - { - return (string) $this->exportTo(ProdutImageTableMap::DEFAULT_STRING_FORMAT); - } - - // timestampable behavior - - /** - * Mark the current object so that the update date doesn't get updated during next save - * - * @return ChildProdutImage The current object (for fluent API support) - */ - public function keepUpdateDateUnchanged() - { - $this->modifiedColumns[] = ProdutImageTableMap::UPDATED_AT; - - return $this; - } - - // i18n behavior - - /** - * Sets the locale for translations - * - * @param string $locale Locale to use for the translation, e.g. 'fr_FR' - * - * @return ChildProdutImage The current object (for fluent API support) - */ - public function setLocale($locale = 'en_US') - { - $this->currentLocale = $locale; - - return $this; - } - - /** - * Gets the locale for translations - * - * @return string $locale Locale to use for the translation, e.g. 'fr_FR' - */ - public function getLocale() - { - return $this->currentLocale; - } - - /** - * Returns the current translation for a given locale - * - * @param string $locale Locale to use for the translation, e.g. 'fr_FR' - * @param ConnectionInterface $con an optional connection object - * - * @return ChildProdutImageI18n */ - public function getTranslation($locale = 'en_US', ConnectionInterface $con = null) - { - if (!isset($this->currentTranslations[$locale])) { - if (null !== $this->collProdutImageI18ns) { - foreach ($this->collProdutImageI18ns as $translation) { - if ($translation->getLocale() == $locale) { - $this->currentTranslations[$locale] = $translation; - - return $translation; - } - } - } - if ($this->isNew()) { - $translation = new ChildProdutImageI18n(); - $translation->setLocale($locale); - } else { - $translation = ChildProdutImageI18nQuery::create() - ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) - ->findOneOrCreate($con); - $this->currentTranslations[$locale] = $translation; - } - $this->addProdutImageI18n($translation); - } - - return $this->currentTranslations[$locale]; - } - - /** - * Remove the translation for a given locale - * - * @param string $locale Locale to use for the translation, e.g. 'fr_FR' - * @param ConnectionInterface $con an optional connection object - * - * @return ChildProdutImage The current object (for fluent API support) - */ - public function removeTranslation($locale = 'en_US', ConnectionInterface $con = null) - { - if (!$this->isNew()) { - ChildProdutImageI18nQuery::create() - ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) - ->delete($con); - } - if (isset($this->currentTranslations[$locale])) { - unset($this->currentTranslations[$locale]); - } - foreach ($this->collProdutImageI18ns as $key => $translation) { - if ($translation->getLocale() == $locale) { - unset($this->collProdutImageI18ns[$key]); - break; - } - } - - return $this; - } - - /** - * Returns the current translation - * - * @param ConnectionInterface $con an optional connection object - * - * @return ChildProdutImageI18n */ - public function getCurrentTranslation(ConnectionInterface $con = null) - { - return $this->getTranslation($this->getLocale(), $con); - } - - - /** - * Get the [title] column value. - * - * @return string - */ - public function getTitle() - { - return $this->getCurrentTranslation()->getTitle(); - } - - - /** - * Set the value of [title] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setTitle($v) - { $this->getCurrentTranslation()->setTitle($v); - - return $this; - } - - - /** - * Get the [description] column value. - * - * @return string - */ - public function getDescription() - { - return $this->getCurrentTranslation()->getDescription(); - } - - - /** - * Set the value of [description] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setDescription($v) - { $this->getCurrentTranslation()->setDescription($v); - - return $this; - } - - - /** - * Get the [chapo] column value. - * - * @return string - */ - public function getChapo() - { - return $this->getCurrentTranslation()->getChapo(); - } - - - /** - * Set the value of [chapo] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setChapo($v) - { $this->getCurrentTranslation()->setChapo($v); - - return $this; - } - - - /** - * Get the [postscriptum] column value. - * - * @return string - */ - public function getPostscriptum() - { - return $this->getCurrentTranslation()->getPostscriptum(); - } - - - /** - * Set the value of [postscriptum] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setPostscriptum($v) - { $this->getCurrentTranslation()->setPostscriptum($v); - - return $this; - } - - /** - * Code to be run before persisting the object - * @param ConnectionInterface $con - * @return boolean - */ - public function preSave(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after persisting the object - * @param ConnectionInterface $con - */ - public function postSave(ConnectionInterface $con = null) - { - - } - - /** - * Code to be run before inserting to database - * @param ConnectionInterface $con - * @return boolean - */ - public function preInsert(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after inserting to database - * @param ConnectionInterface $con - */ - public function postInsert(ConnectionInterface $con = null) - { - - } - - /** - * Code to be run before updating the object in database - * @param ConnectionInterface $con - * @return boolean - */ - public function preUpdate(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after updating the object in database - * @param ConnectionInterface $con - */ - public function postUpdate(ConnectionInterface $con = null) - { - - } - - /** - * Code to be run before deleting the object in database - * @param ConnectionInterface $con - * @return boolean - */ - public function preDelete(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after deleting the object in database - * @param ConnectionInterface $con - */ - public function postDelete(ConnectionInterface $con = null) - { - - } - - - /** - * Derived method to catches calls to undefined methods. - * - * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). - * Allows to define default __call() behavior if you overwrite __call() - * - * @param string $name - * @param mixed $params - * - * @return array|string - */ - public function __call($name, $params) - { - if (0 === strpos($name, 'get')) { - $virtualColumn = substr($name, 3); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - - $virtualColumn = lcfirst($virtualColumn); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - - if (0 === strpos($name, 'from')) { - $format = substr($name, 4); - - return $this->importFrom($format, reset($params)); - } - - if (0 === strpos($name, 'to')) { - $format = substr($name, 2); - $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; - - return $this->exportTo($format, $includeLazyLoadColumns); - } - - throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); - } - -} diff --git a/core/lib/Thelia/Model/Base/ProdutImageI18n.php b/core/lib/Thelia/Model/Base/ProdutImageI18n.php deleted file mode 100644 index 819081db2..000000000 --- a/core/lib/Thelia/Model/Base/ProdutImageI18n.php +++ /dev/null @@ -1,1439 +0,0 @@ -locale = 'en_US'; - } - - /** - * Initializes internal state of Thelia\Model\Base\ProdutImageI18n object. - * @see applyDefaults() - */ - public function __construct() - { - $this->applyDefaultValues(); - } - - /** - * Returns whether the object has been modified. - * - * @return boolean True if the object has been modified. - */ - public function isModified() - { - return !empty($this->modifiedColumns); - } - - /** - * Has specified column been modified? - * - * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID - * @return boolean True if $col has been modified. - */ - public function isColumnModified($col) - { - return in_array($col, $this->modifiedColumns); - } - - /** - * Get the columns that have been modified in this object. - * @return array A unique list of the modified column names for this object. - */ - public function getModifiedColumns() - { - return array_unique($this->modifiedColumns); - } - - /** - * Returns whether the object has ever been saved. This will - * be false, if the object was retrieved from storage or was created - * and then saved. - * - * @return true, if the object has never been persisted. - */ - public function isNew() - { - return $this->new; - } - - /** - * Setter for the isNew attribute. This method will be called - * by Propel-generated children and objects. - * - * @param boolean $b the state of the object. - */ - public function setNew($b) - { - $this->new = (Boolean) $b; - } - - /** - * Whether this object has been deleted. - * @return boolean The deleted state of this object. - */ - public function isDeleted() - { - return $this->deleted; - } - - /** - * Specify whether this object has been deleted. - * @param boolean $b The deleted state of this object. - * @return void - */ - public function setDeleted($b) - { - $this->deleted = (Boolean) $b; - } - - /** - * Sets the modified state for the object to be false. - * @param string $col If supplied, only the specified column is reset. - * @return void - */ - public function resetModified($col = null) - { - if (null !== $col) { - while (false !== ($offset = array_search($col, $this->modifiedColumns))) { - array_splice($this->modifiedColumns, $offset, 1); - } - } else { - $this->modifiedColumns = array(); - } - } - - /** - * Compares this with another ProdutImageI18n instance. If - * obj is an instance of ProdutImageI18n, delegates to - * equals(ProdutImageI18n). Otherwise, returns false. - * - * @param obj The object to compare to. - * @return Whether equal to the object specified. - */ - public function equals($obj) - { - $thisclazz = get_class($this); - if (!is_object($obj) || !($obj instanceof $thisclazz)) { - return false; - } - - if ($this === $obj) { - return true; - } - - if (null === $this->getPrimaryKey() - || null === $obj->getPrimaryKey()) { - return false; - } - - return $this->getPrimaryKey() === $obj->getPrimaryKey(); - } - - /** - * If the primary key is not null, return the hashcode of the - * primary key. Otherwise, return the hash code of the object. - * - * @return int Hashcode - */ - public function hashCode() - { - if (null !== $this->getPrimaryKey()) { - return crc32(serialize($this->getPrimaryKey())); - } - - return crc32(serialize(clone $this)); - } - - /** - * Get the associative array of the virtual columns in this object - * - * @param string $name The virtual column name - * - * @return array - */ - public function getVirtualColumns() - { - return $this->virtualColumns; - } - - /** - * Checks the existence of a virtual column in this object - * - * @return boolean - */ - public function hasVirtualColumn($name) - { - return isset($this->virtualColumns[$name]); - } - - /** - * Get the value of a virtual column in this object - * - * @return mixed - */ - public function getVirtualColumn($name) - { - if (!$this->hasVirtualColumn($name)) { - throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); - } - - return $this->virtualColumns[$name]; - } - - /** - * Set the value of a virtual column in this object - * - * @param string $name The virtual column name - * @param mixed $value The value to give to the virtual column - * - * @return ProdutImageI18n The current object, for fluid interface - */ - public function setVirtualColumn($name, $value) - { - $this->virtualColumns[$name] = $value; - - return $this; - } - - /** - * Logs a message using Propel::log(). - * - * @param string $msg - * @param int $priority One of the Propel::LOG_* logging levels - * @return boolean - */ - protected function log($msg, $priority = Propel::LOG_INFO) - { - return Propel::log(get_class($this) . ': ' . $msg, $priority); - } - - /** - * Populate the current object from a string, using a given parser format - * - * $book = new Book(); - * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); - * - * - * @param mixed $parser A AbstractParser instance, - * or a format name ('XML', 'YAML', 'JSON', 'CSV') - * @param string $data The source data to import from - * - * @return ProdutImageI18n The current object, for fluid interface - */ - public function importFrom($parser, $data) - { - if (!$parser instanceof AbstractParser) { - $parser = AbstractParser::getParser($parser); - } - - return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); - } - - /** - * Export the current object properties to a string, using a given parser format - * - * $book = BookQuery::create()->findPk(9012); - * echo $book->exportTo('JSON'); - * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); - * - * - * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. - * @return string The exported data - */ - public function exportTo($parser, $includeLazyLoadColumns = true) - { - if (!$parser instanceof AbstractParser) { - $parser = AbstractParser::getParser($parser); - } - - return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); - } - - /** - * Clean up internal collections prior to serializing - * Avoids recursive loops that turn into segmentation faults when serializing - */ - public function __sleep() - { - $this->clearAllReferences(); - - return array_keys(get_object_vars($this)); - } - - /** - * Get the [id] column value. - * - * @return int - */ - public function getId() - { - - return $this->id; - } - - /** - * Get the [locale] column value. - * - * @return string - */ - public function getLocale() - { - - return $this->locale; - } - - /** - * Get the [title] column value. - * - * @return string - */ - public function getTitle() - { - - return $this->title; - } - - /** - * Get the [description] column value. - * - * @return string - */ - public function getDescription() - { - - return $this->description; - } - - /** - * Get the [chapo] column value. - * - * @return string - */ - public function getChapo() - { - - return $this->chapo; - } - - /** - * Get the [postscriptum] column value. - * - * @return string - */ - public function getPostscriptum() - { - - return $this->postscriptum; - } - - /** - * Set the value of [id] column. - * - * @param int $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setId($v) - { - if ($v !== null) { - $v = (int) $v; - } - - if ($this->id !== $v) { - $this->id = $v; - $this->modifiedColumns[] = ProdutImageI18nTableMap::ID; - } - - if ($this->aProdutImage !== null && $this->aProdutImage->getId() !== $v) { - $this->aProdutImage = null; - } - - - return $this; - } // setId() - - /** - * Set the value of [locale] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setLocale($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->locale !== $v) { - $this->locale = $v; - $this->modifiedColumns[] = ProdutImageI18nTableMap::LOCALE; - } - - - return $this; - } // setLocale() - - /** - * Set the value of [title] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setTitle($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->title !== $v) { - $this->title = $v; - $this->modifiedColumns[] = ProdutImageI18nTableMap::TITLE; - } - - - return $this; - } // setTitle() - - /** - * Set the value of [description] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setDescription($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->description !== $v) { - $this->description = $v; - $this->modifiedColumns[] = ProdutImageI18nTableMap::DESCRIPTION; - } - - - return $this; - } // setDescription() - - /** - * Set the value of [chapo] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setChapo($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->chapo !== $v) { - $this->chapo = $v; - $this->modifiedColumns[] = ProdutImageI18nTableMap::CHAPO; - } - - - return $this; - } // setChapo() - - /** - * Set the value of [postscriptum] column. - * - * @param string $v new value - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - */ - public function setPostscriptum($v) - { - if ($v !== null) { - $v = (string) $v; - } - - if ($this->postscriptum !== $v) { - $this->postscriptum = $v; - $this->modifiedColumns[] = ProdutImageI18nTableMap::POSTSCRIPTUM; - } - - - return $this; - } // setPostscriptum() - - /** - * Indicates whether the columns in this object are only set to default values. - * - * This method can be used in conjunction with isModified() to indicate whether an object is both - * modified _and_ has some values set which are non-default. - * - * @return boolean Whether the columns in this object are only been set with default values. - */ - public function hasOnlyDefaultValues() - { - if ($this->locale !== 'en_US') { - return false; - } - - // otherwise, everything was equal, so return TRUE - return true; - } // hasOnlyDefaultValues() - - /** - * Hydrates (populates) the object variables with values from the database resultset. - * - * An offset (0-based "start column") is specified so that objects can be hydrated - * with a subset of the columns in the resultset rows. This is needed, for example, - * for results of JOIN queries where the resultset row includes columns from two or - * more tables. - * - * @param array $row The row returned by DataFetcher->fetch(). - * @param int $startcol 0-based offset column which indicates which restultset column to start with. - * @param boolean $rehydrate Whether this object is being re-hydrated from the database. - * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). - One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * - * @return int next starting column - * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. - */ - public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) - { - try { - - - $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ProdutImageI18nTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; - $this->id = (null !== $col) ? (int) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProdutImageI18nTableMap::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)]; - $this->locale = (null !== $col) ? (string) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProdutImageI18nTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; - $this->title = (null !== $col) ? (string) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProdutImageI18nTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; - $this->description = (null !== $col) ? (string) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProdutImageI18nTableMap::translateFieldName('Chapo', TableMap::TYPE_PHPNAME, $indexType)]; - $this->chapo = (null !== $col) ? (string) $col : null; - - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProdutImageI18nTableMap::translateFieldName('Postscriptum', TableMap::TYPE_PHPNAME, $indexType)]; - $this->postscriptum = (null !== $col) ? (string) $col : null; - $this->resetModified(); - - $this->setNew(false); - - if ($rehydrate) { - $this->ensureConsistency(); - } - - return $startcol + 6; // 6 = ProdutImageI18nTableMap::NUM_HYDRATE_COLUMNS. - - } catch (Exception $e) { - throw new PropelException("Error populating \Thelia\Model\ProdutImageI18n object", 0, $e); - } - } - - /** - * Checks and repairs the internal consistency of the object. - * - * This method is executed after an already-instantiated object is re-hydrated - * from the database. It exists to check any foreign keys to make sure that - * the objects related to the current object are correct based on foreign key. - * - * You can override this method in the stub class, but you should always invoke - * the base method from the overridden method (i.e. parent::ensureConsistency()), - * in case your model changes. - * - * @throws PropelException - */ - public function ensureConsistency() - { - if ($this->aProdutImage !== null && $this->id !== $this->aProdutImage->getId()) { - $this->aProdutImage = null; - } - } // ensureConsistency - - /** - * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. - * - * This will only work if the object has been saved and has a valid primary key set. - * - * @param boolean $deep (optional) Whether to also de-associated any related objects. - * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. - * @return void - * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db - */ - public function reload($deep = false, ConnectionInterface $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("Cannot reload a deleted object."); - } - - if ($this->isNew()) { - throw new PropelException("Cannot reload an unsaved object."); - } - - if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - - // We don't need to alter the object instance pool; we're just modifying this instance - // already in the pool. - - $dataFetcher = ChildProdutImageI18nQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); - $row = $dataFetcher->fetch(); - $dataFetcher->close(); - if (!$row) { - throw new PropelException('Cannot find matching row in the database to reload object values.'); - } - $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate - - if ($deep) { // also de-associate any related objects? - - $this->aProdutImage = null; - } // if (deep) - } - - /** - * Removes this object from datastore and sets delete attribute. - * - * @param ConnectionInterface $con - * @return void - * @throws PropelException - * @see ProdutImageI18n::setDeleted() - * @see ProdutImageI18n::isDeleted() - */ - public function delete(ConnectionInterface $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("This object has already been deleted."); - } - - if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - - $con->beginTransaction(); - try { - $deleteQuery = ChildProdutImageI18nQuery::create() - ->filterByPrimaryKey($this->getPrimaryKey()); - $ret = $this->preDelete($con); - if ($ret) { - $deleteQuery->delete($con); - $this->postDelete($con); - $con->commit(); - $this->setDeleted(true); - } else { - $con->commit(); - } - } catch (Exception $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Persists this object to the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All modified related objects will also be persisted in the doSave() - * method. This method wraps all precipitate database operations in a - * single transaction. - * - * @param ConnectionInterface $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see doSave() - */ - public function save(ConnectionInterface $con = null) - { - if ($this->isDeleted()) { - throw new PropelException("You cannot save an object that has been deleted."); - } - - if ($con === null) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - - $con->beginTransaction(); - $isInsert = $this->isNew(); - try { - $ret = $this->preSave($con); - if ($isInsert) { - $ret = $ret && $this->preInsert($con); - } else { - $ret = $ret && $this->preUpdate($con); - } - if ($ret) { - $affectedRows = $this->doSave($con); - if ($isInsert) { - $this->postInsert($con); - } else { - $this->postUpdate($con); - } - $this->postSave($con); - ProdutImageI18nTableMap::addInstanceToPool($this); - } else { - $affectedRows = 0; - } - $con->commit(); - - return $affectedRows; - } catch (Exception $e) { - $con->rollBack(); - throw $e; - } - } - - /** - * Performs the work of inserting or updating the row in the database. - * - * If the object is new, it inserts it; otherwise an update is performed. - * All related objects are also updated in this method. - * - * @param ConnectionInterface $con - * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. - * @throws PropelException - * @see save() - */ - protected function doSave(ConnectionInterface $con) - { - $affectedRows = 0; // initialize var to track total num of affected rows - if (!$this->alreadyInSave) { - $this->alreadyInSave = true; - - // We call the save method on the following object(s) if they - // were passed to this object by their corresponding set - // method. This object relates to these object(s) by a - // foreign key reference. - - if ($this->aProdutImage !== null) { - if ($this->aProdutImage->isModified() || $this->aProdutImage->isNew()) { - $affectedRows += $this->aProdutImage->save($con); - } - $this->setProdutImage($this->aProdutImage); - } - - if ($this->isNew() || $this->isModified()) { - // persist changes - if ($this->isNew()) { - $this->doInsert($con); - } else { - $this->doUpdate($con); - } - $affectedRows += 1; - $this->resetModified(); - } - - $this->alreadyInSave = false; - - } - - return $affectedRows; - } // doSave() - - /** - * Insert the row in the database. - * - * @param ConnectionInterface $con - * - * @throws PropelException - * @see doSave() - */ - protected function doInsert(ConnectionInterface $con) - { - $modifiedColumns = array(); - $index = 0; - - - // check the columns in natural order for more readable SQL queries - if ($this->isColumnModified(ProdutImageI18nTableMap::ID)) { - $modifiedColumns[':p' . $index++] = 'ID'; - } - if ($this->isColumnModified(ProdutImageI18nTableMap::LOCALE)) { - $modifiedColumns[':p' . $index++] = 'LOCALE'; - } - if ($this->isColumnModified(ProdutImageI18nTableMap::TITLE)) { - $modifiedColumns[':p' . $index++] = 'TITLE'; - } - if ($this->isColumnModified(ProdutImageI18nTableMap::DESCRIPTION)) { - $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; - } - if ($this->isColumnModified(ProdutImageI18nTableMap::CHAPO)) { - $modifiedColumns[':p' . $index++] = 'CHAPO'; - } - if ($this->isColumnModified(ProdutImageI18nTableMap::POSTSCRIPTUM)) { - $modifiedColumns[':p' . $index++] = 'POSTSCRIPTUM'; - } - - $sql = sprintf( - 'INSERT INTO produt_image_i18n (%s) VALUES (%s)', - implode(', ', $modifiedColumns), - implode(', ', array_keys($modifiedColumns)) - ); - - try { - $stmt = $con->prepare($sql); - foreach ($modifiedColumns as $identifier => $columnName) { - switch ($columnName) { - case 'ID': - $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); - break; - case 'LOCALE': - $stmt->bindValue($identifier, $this->locale, PDO::PARAM_STR); - break; - case 'TITLE': - $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); - break; - case 'DESCRIPTION': - $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); - break; - case 'CHAPO': - $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); - break; - case 'POSTSCRIPTUM': - $stmt->bindValue($identifier, $this->postscriptum, PDO::PARAM_STR); - break; - } - } - $stmt->execute(); - } catch (Exception $e) { - Propel::log($e->getMessage(), Propel::LOG_ERR); - throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); - } - - $this->setNew(false); - } - - /** - * Update the row in the database. - * - * @param ConnectionInterface $con - * - * @return Integer Number of updated rows - * @see doSave() - */ - protected function doUpdate(ConnectionInterface $con) - { - $selectCriteria = $this->buildPkeyCriteria(); - $valuesCriteria = $this->buildCriteria(); - - return $selectCriteria->doUpdate($valuesCriteria, $con); - } - - /** - * Retrieves a field from the object by name passed in as a string. - * - * @param string $name name - * @param string $type The type of fieldname the $name is of: - * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * Defaults to TableMap::TYPE_PHPNAME. - * @return mixed Value of field. - */ - public function getByName($name, $type = TableMap::TYPE_PHPNAME) - { - $pos = ProdutImageI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); - $field = $this->getByPosition($pos); - - return $field; - } - - /** - * Retrieves a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @return mixed Value of field at $pos - */ - public function getByPosition($pos) - { - switch ($pos) { - case 0: - return $this->getId(); - break; - case 1: - return $this->getLocale(); - break; - case 2: - return $this->getTitle(); - break; - case 3: - return $this->getDescription(); - break; - case 4: - return $this->getChapo(); - break; - case 5: - return $this->getPostscriptum(); - break; - default: - return null; - break; - } // switch() - } - - /** - * Exports the object as an array. - * - * You can specify the key type of the array by passing one of the class - * type constants. - * - * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * Defaults to TableMap::TYPE_PHPNAME. - * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. - * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion - * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. - * - * @return array an associative array containing the field names (as keys) and field values - */ - public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) - { - if (isset($alreadyDumpedObjects['ProdutImageI18n'][serialize($this->getPrimaryKey())])) { - return '*RECURSION*'; - } - $alreadyDumpedObjects['ProdutImageI18n'][serialize($this->getPrimaryKey())] = true; - $keys = ProdutImageI18nTableMap::getFieldNames($keyType); - $result = array( - $keys[0] => $this->getId(), - $keys[1] => $this->getLocale(), - $keys[2] => $this->getTitle(), - $keys[3] => $this->getDescription(), - $keys[4] => $this->getChapo(), - $keys[5] => $this->getPostscriptum(), - ); - $virtualColumns = $this->virtualColumns; - foreach($virtualColumns as $key => $virtualColumn) - { - $result[$key] = $virtualColumn; - } - - if ($includeForeignObjects) { - if (null !== $this->aProdutImage) { - $result['ProdutImage'] = $this->aProdutImage->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); - } - } - - return $result; - } - - /** - * Sets a field from the object by name passed in as a string. - * - * @param string $name - * @param mixed $value field value - * @param string $type The type of fieldname the $name is of: - * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * Defaults to TableMap::TYPE_PHPNAME. - * @return void - */ - public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) - { - $pos = ProdutImageI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); - - return $this->setByPosition($pos, $value); - } - - /** - * Sets a field from the object by Position as specified in the xml schema. - * Zero-based. - * - * @param int $pos position in xml schema - * @param mixed $value field value - * @return void - */ - public function setByPosition($pos, $value) - { - switch ($pos) { - case 0: - $this->setId($value); - break; - case 1: - $this->setLocale($value); - break; - case 2: - $this->setTitle($value); - break; - case 3: - $this->setDescription($value); - break; - case 4: - $this->setChapo($value); - break; - case 5: - $this->setPostscriptum($value); - break; - } // switch() - } - - /** - * Populates the object using an array. - * - * This is particularly useful when populating an object from one of the - * request arrays (e.g. $_POST). This method goes through the column - * names, checking to see whether a matching key exists in populated - * array. If so the setByName() method is called for that column. - * - * You can specify the key type of the array by additionally passing one - * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * The default key type is the column's TableMap::TYPE_PHPNAME. - * - * @param array $arr An array to populate the object from. - * @param string $keyType The type of keys the array uses. - * @return void - */ - public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) - { - $keys = ProdutImageI18nTableMap::getFieldNames($keyType); - - if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); - if (array_key_exists($keys[1], $arr)) $this->setLocale($arr[$keys[1]]); - if (array_key_exists($keys[2], $arr)) $this->setTitle($arr[$keys[2]]); - if (array_key_exists($keys[3], $arr)) $this->setDescription($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setChapo($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setPostscriptum($arr[$keys[5]]); - } - - /** - * Build a Criteria object containing the values of all modified columns in this object. - * - * @return Criteria The Criteria object containing all modified values. - */ - public function buildCriteria() - { - $criteria = new Criteria(ProdutImageI18nTableMap::DATABASE_NAME); - - if ($this->isColumnModified(ProdutImageI18nTableMap::ID)) $criteria->add(ProdutImageI18nTableMap::ID, $this->id); - if ($this->isColumnModified(ProdutImageI18nTableMap::LOCALE)) $criteria->add(ProdutImageI18nTableMap::LOCALE, $this->locale); - if ($this->isColumnModified(ProdutImageI18nTableMap::TITLE)) $criteria->add(ProdutImageI18nTableMap::TITLE, $this->title); - if ($this->isColumnModified(ProdutImageI18nTableMap::DESCRIPTION)) $criteria->add(ProdutImageI18nTableMap::DESCRIPTION, $this->description); - if ($this->isColumnModified(ProdutImageI18nTableMap::CHAPO)) $criteria->add(ProdutImageI18nTableMap::CHAPO, $this->chapo); - if ($this->isColumnModified(ProdutImageI18nTableMap::POSTSCRIPTUM)) $criteria->add(ProdutImageI18nTableMap::POSTSCRIPTUM, $this->postscriptum); - - return $criteria; - } - - /** - * Builds a Criteria object containing the primary key for this object. - * - * Unlike buildCriteria() this method includes the primary key values regardless - * of whether or not they have been modified. - * - * @return Criteria The Criteria object containing value(s) for primary key(s). - */ - public function buildPkeyCriteria() - { - $criteria = new Criteria(ProdutImageI18nTableMap::DATABASE_NAME); - $criteria->add(ProdutImageI18nTableMap::ID, $this->id); - $criteria->add(ProdutImageI18nTableMap::LOCALE, $this->locale); - - return $criteria; - } - - /** - * Returns the composite primary key for this object. - * The array elements will be in same order as specified in XML. - * @return array - */ - public function getPrimaryKey() - { - $pks = array(); - $pks[0] = $this->getId(); - $pks[1] = $this->getLocale(); - - return $pks; - } - - /** - * Set the [composite] primary key. - * - * @param array $keys The elements of the composite key (order must match the order in XML file). - * @return void - */ - public function setPrimaryKey($keys) - { - $this->setId($keys[0]); - $this->setLocale($keys[1]); - } - - /** - * Returns true if the primary key for this object is null. - * @return boolean - */ - public function isPrimaryKeyNull() - { - - return (null === $this->getId()) && (null === $this->getLocale()); - } - - /** - * Sets contents of passed object to values from current object. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param object $copyObj An object of \Thelia\Model\ProdutImageI18n (or compatible) type. - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. - * @throws PropelException - */ - public function copyInto($copyObj, $deepCopy = false, $makeNew = true) - { - $copyObj->setId($this->getId()); - $copyObj->setLocale($this->getLocale()); - $copyObj->setTitle($this->getTitle()); - $copyObj->setDescription($this->getDescription()); - $copyObj->setChapo($this->getChapo()); - $copyObj->setPostscriptum($this->getPostscriptum()); - if ($makeNew) { - $copyObj->setNew(true); - } - } - - /** - * Makes a copy of this object that will be inserted as a new row in table when saved. - * It creates a new object filling in the simple attributes, but skipping any primary - * keys that are defined for the table. - * - * If desired, this method can also make copies of all associated (fkey referrers) - * objects. - * - * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. - * @return \Thelia\Model\ProdutImageI18n Clone of current object. - * @throws PropelException - */ - public function copy($deepCopy = false) - { - // we use get_class(), because this might be a subclass - $clazz = get_class($this); - $copyObj = new $clazz(); - $this->copyInto($copyObj, $deepCopy); - - return $copyObj; - } - - /** - * Declares an association between this object and a ChildProdutImage object. - * - * @param ChildProdutImage $v - * @return \Thelia\Model\ProdutImageI18n The current object (for fluent API support) - * @throws PropelException - */ - public function setProdutImage(ChildProdutImage $v = null) - { - if ($v === null) { - $this->setId(NULL); - } else { - $this->setId($v->getId()); - } - - $this->aProdutImage = $v; - - // Add binding for other direction of this n:n relationship. - // If this object has already been added to the ChildProdutImage object, it will not be re-added. - if ($v !== null) { - $v->addProdutImageI18n($this); - } - - - return $this; - } - - - /** - * Get the associated ChildProdutImage object - * - * @param ConnectionInterface $con Optional Connection object. - * @return ChildProdutImage The associated ChildProdutImage object. - * @throws PropelException - */ - public function getProdutImage(ConnectionInterface $con = null) - { - if ($this->aProdutImage === null && ($this->id !== null)) { - $this->aProdutImage = ChildProdutImageQuery::create()->findPk($this->id, $con); - /* The following can be used additionally to - guarantee the related object contains a reference - to this object. This level of coupling may, however, be - undesirable since it could result in an only partially populated collection - in the referenced object. - $this->aProdutImage->addProdutImageI18ns($this); - */ - } - - return $this->aProdutImage; - } - - /** - * Clears the current object and sets all attributes to their default values - */ - public function clear() - { - $this->id = null; - $this->locale = null; - $this->title = null; - $this->description = null; - $this->chapo = null; - $this->postscriptum = null; - $this->alreadyInSave = false; - $this->clearAllReferences(); - $this->applyDefaultValues(); - $this->resetModified(); - $this->setNew(true); - $this->setDeleted(false); - } - - /** - * Resets all references to other model objects or collections of model objects. - * - * This method is a user-space workaround for PHP's inability to garbage collect - * objects with circular references (even in PHP 5.3). This is currently necessary - * when using Propel in certain daemon or large-volume/high-memory operations. - * - * @param boolean $deep Whether to also clear the references on all referrer objects. - */ - public function clearAllReferences($deep = false) - { - if ($deep) { - } // if ($deep) - - $this->aProdutImage = null; - } - - /** - * Return the string representation of this object - * - * @return string - */ - public function __toString() - { - return (string) $this->exportTo(ProdutImageI18nTableMap::DEFAULT_STRING_FORMAT); - } - - /** - * Code to be run before persisting the object - * @param ConnectionInterface $con - * @return boolean - */ - public function preSave(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after persisting the object - * @param ConnectionInterface $con - */ - public function postSave(ConnectionInterface $con = null) - { - - } - - /** - * Code to be run before inserting to database - * @param ConnectionInterface $con - * @return boolean - */ - public function preInsert(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after inserting to database - * @param ConnectionInterface $con - */ - public function postInsert(ConnectionInterface $con = null) - { - - } - - /** - * Code to be run before updating the object in database - * @param ConnectionInterface $con - * @return boolean - */ - public function preUpdate(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after updating the object in database - * @param ConnectionInterface $con - */ - public function postUpdate(ConnectionInterface $con = null) - { - - } - - /** - * Code to be run before deleting the object in database - * @param ConnectionInterface $con - * @return boolean - */ - public function preDelete(ConnectionInterface $con = null) - { - return true; - } - - /** - * Code to be run after deleting the object in database - * @param ConnectionInterface $con - */ - public function postDelete(ConnectionInterface $con = null) - { - - } - - - /** - * Derived method to catches calls to undefined methods. - * - * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). - * Allows to define default __call() behavior if you overwrite __call() - * - * @param string $name - * @param mixed $params - * - * @return array|string - */ - public function __call($name, $params) - { - if (0 === strpos($name, 'get')) { - $virtualColumn = substr($name, 3); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - - $virtualColumn = lcfirst($virtualColumn); - if ($this->hasVirtualColumn($virtualColumn)) { - return $this->getVirtualColumn($virtualColumn); - } - } - - if (0 === strpos($name, 'from')) { - $format = substr($name, 4); - - return $this->importFrom($format, reset($params)); - } - - if (0 === strpos($name, 'to')) { - $format = substr($name, 2); - $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; - - return $this->exportTo($format, $includeLazyLoadColumns); - } - - throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); - } - -} diff --git a/core/lib/Thelia/Model/Base/ProdutImageI18nQuery.php b/core/lib/Thelia/Model/Base/ProdutImageI18nQuery.php deleted file mode 100644 index 438a7d91b..000000000 --- a/core/lib/Thelia/Model/Base/ProdutImageI18nQuery.php +++ /dev/null @@ -1,607 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - - return $query; - } - - /** - * Find object by primary key. - * Propel uses the instance pool to skip the database if the object exists. - * Go fast if the query is untouched. - * - * - * $obj = $c->findPk(array(12, 34), $con); - * - * - * @param array[$id, $locale] $key Primary key to use for the query - * @param ConnectionInterface $con an optional connection object - * - * @return ChildProdutImageI18n|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ($key === null) { - return null; - } - if ((null !== ($obj = ProdutImageI18nTableMap::getInstanceFromPool(serialize(array((string) $key[0], (string) $key[1]))))) && !$this->formatter) { - // the object is already in the instance pool - return $obj; - } - if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - $this->basePreSelect($con); - if ($this->formatter || $this->modelAlias || $this->with || $this->select - || $this->selectColumns || $this->asColumns || $this->selectModifiers - || $this->map || $this->having || $this->joins) { - return $this->findPkComplex($key, $con); - } else { - return $this->findPkSimple($key, $con); - } - } - - /** - * Find object by primary key using raw SQL to go fast. - * Bypass doSelect() and the object formatter by using generated code. - * - * @param mixed $key Primary key to use for the query - * @param ConnectionInterface $con A connection object - * - * @return ChildProdutImageI18n A model object, or null if the key is not found - */ - protected function findPkSimple($key, $con) - { - $sql = 'SELECT ID, LOCALE, TITLE, DESCRIPTION, CHAPO, POSTSCRIPTUM FROM produt_image_i18n WHERE ID = :p0 AND LOCALE = :p1'; - try { - $stmt = $con->prepare($sql); - $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); - $stmt->bindValue(':p1', $key[1], PDO::PARAM_STR); - $stmt->execute(); - } catch (Exception $e) { - Propel::log($e->getMessage(), Propel::LOG_ERR); - throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); - } - $obj = null; - if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { - $obj = new ChildProdutImageI18n(); - $obj->hydrate($row); - ProdutImageI18nTableMap::addInstanceToPool($obj, serialize(array((string) $key[0], (string) $key[1]))); - } - $stmt->closeCursor(); - - return $obj; - } - - /** - * Find object by primary key. - * - * @param mixed $key Primary key to use for the query - * @param ConnectionInterface $con A connection object - * - * @return ChildProdutImageI18n|array|mixed the result, formatted by the current formatter - */ - protected function findPkComplex($key, $con) - { - // As the query uses a PK condition, no limit(1) is necessary. - $criteria = $this->isKeepQuery() ? clone $this : $this; - $dataFetcher = $criteria - ->filterByPrimaryKey($key) - ->doSelect($con); - - return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(array(12, 56), array(832, 123), array(123, 456)), $con); - * - * @param array $keys Primary keys to use for the query - * @param ConnectionInterface $con an optional connection object - * - * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); - } - $this->basePreSelect($con); - $criteria = $this->isKeepQuery() ? clone $this : $this; - $dataFetcher = $criteria - ->filterByPrimaryKeys($keys) - ->doSelect($con); - - return $criteria->getFormatter()->init($criteria)->format($dataFetcher); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - $this->addUsingAlias(ProdutImageI18nTableMap::ID, $key[0], Criteria::EQUAL); - $this->addUsingAlias(ProdutImageI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); - - return $this; - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - if (empty($keys)) { - return $this->add(null, '1<>1', Criteria::CUSTOM); - } - foreach ($keys as $key) { - $cton0 = $this->getNewCriterion(ProdutImageI18nTableMap::ID, $key[0], Criteria::EQUAL); - $cton1 = $this->getNewCriterion(ProdutImageI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); - $cton0->addAnd($cton1); - $this->addOr($cton0); - } - - return $this; - } - - /** - * Filter the query on the id column - * - * Example usage: - * - * $query->filterById(1234); // WHERE id = 1234 - * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) - * $query->filterById(array('min' => 12)); // WHERE id > 12 - * - * - * @see filterByProdutImage() - * - * @param mixed $id The value to use as filter. - * Use scalar values for equality. - * Use array values for in_array() equivalent. - * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id)) { - $useMinMax = false; - if (isset($id['min'])) { - $this->addUsingAlias(ProdutImageI18nTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($id['max'])) { - $this->addUsingAlias(ProdutImageI18nTableMap::ID, $id['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - - return $this->addUsingAlias(ProdutImageI18nTableMap::ID, $id, $comparison); - } - - /** - * Filter the query on the locale column - * - * Example usage: - * - * $query->filterByLocale('fooValue'); // WHERE locale = 'fooValue' - * $query->filterByLocale('%fooValue%'); // WHERE locale LIKE '%fooValue%' - * - * - * @param string $locale The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByLocale($locale = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($locale)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $locale)) { - $locale = str_replace('*', '%', $locale); - $comparison = Criteria::LIKE; - } - } - - return $this->addUsingAlias(ProdutImageI18nTableMap::LOCALE, $locale, $comparison); - } - - /** - * Filter the query on the title column - * - * Example usage: - * - * $query->filterByTitle('fooValue'); // WHERE title = 'fooValue' - * $query->filterByTitle('%fooValue%'); // WHERE title LIKE '%fooValue%' - * - * - * @param string $title The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByTitle($title = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($title)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $title)) { - $title = str_replace('*', '%', $title); - $comparison = Criteria::LIKE; - } - } - - return $this->addUsingAlias(ProdutImageI18nTableMap::TITLE, $title, $comparison); - } - - /** - * Filter the query on the description column - * - * Example usage: - * - * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' - * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' - * - * - * @param string $description The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByDescription($description = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($description)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $description)) { - $description = str_replace('*', '%', $description); - $comparison = Criteria::LIKE; - } - } - - return $this->addUsingAlias(ProdutImageI18nTableMap::DESCRIPTION, $description, $comparison); - } - - /** - * Filter the query on the chapo column - * - * Example usage: - * - * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' - * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' - * - * - * @param string $chapo The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByChapo($chapo = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($chapo)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $chapo)) { - $chapo = str_replace('*', '%', $chapo); - $comparison = Criteria::LIKE; - } - } - - return $this->addUsingAlias(ProdutImageI18nTableMap::CHAPO, $chapo, $comparison); - } - - /** - * Filter the query on the postscriptum column - * - * Example usage: - * - * $query->filterByPostscriptum('fooValue'); // WHERE postscriptum = 'fooValue' - * $query->filterByPostscriptum('%fooValue%'); // WHERE postscriptum LIKE '%fooValue%' - * - * - * @param string $postscriptum The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByPostscriptum($postscriptum = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($postscriptum)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $postscriptum)) { - $postscriptum = str_replace('*', '%', $postscriptum); - $comparison = Criteria::LIKE; - } - } - - return $this->addUsingAlias(ProdutImageI18nTableMap::POSTSCRIPTUM, $postscriptum, $comparison); - } - - /** - * Filter the query by a related \Thelia\Model\ProdutImage object - * - * @param \Thelia\Model\ProdutImage|ObjectCollection $produtImage The related object(s) to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function filterByProdutImage($produtImage, $comparison = null) - { - if ($produtImage instanceof \Thelia\Model\ProdutImage) { - return $this - ->addUsingAlias(ProdutImageI18nTableMap::ID, $produtImage->getId(), $comparison); - } elseif ($produtImage instanceof ObjectCollection) { - if (null === $comparison) { - $comparison = Criteria::IN; - } - - return $this - ->addUsingAlias(ProdutImageI18nTableMap::ID, $produtImage->toKeyValue('PrimaryKey', 'Id'), $comparison); - } else { - throw new PropelException('filterByProdutImage() only accepts arguments of type \Thelia\Model\ProdutImage or Collection'); - } - } - - /** - * Adds a JOIN clause to the query using the ProdutImage relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function joinProdutImage($relationAlias = null, $joinType = 'LEFT JOIN') - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('ProdutImage'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if ($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'ProdutImage'); - } - - return $this; - } - - /** - * Use the ProdutImage relation ProdutImage object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return \Thelia\Model\ProdutImageQuery A secondary query class using the current class as primary query - */ - public function useProdutImageQuery($relationAlias = null, $joinType = 'LEFT JOIN') - { - return $this - ->joinProdutImage($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'ProdutImage', '\Thelia\Model\ProdutImageQuery'); - } - - /** - * Exclude object from result - * - * @param ChildProdutImageI18n $produtImageI18n Object to remove from the list of results - * - * @return ChildProdutImageI18nQuery The current query, for fluid interface - */ - public function prune($produtImageI18n = null) - { - if ($produtImageI18n) { - $this->addCond('pruneCond0', $this->getAliasedColName(ProdutImageI18nTableMap::ID), $produtImageI18n->getId(), Criteria::NOT_EQUAL); - $this->addCond('pruneCond1', $this->getAliasedColName(ProdutImageI18nTableMap::LOCALE), $produtImageI18n->getLocale(), Criteria::NOT_EQUAL); - $this->combine(array('pruneCond0', 'pruneCond1'), Criteria::LOGICAL_OR); - } - - return $this; - } - - /** - * Deletes all rows from the produt_image_i18n table. - * - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). - */ - public function doDeleteAll(ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += parent::doDeleteAll($con); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - ProdutImageI18nTableMap::clearInstancePool(); - ProdutImageI18nTableMap::clearRelatedInstancePool(); - - $con->commit(); - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $affectedRows; - } - - /** - * Performs a DELETE on the database, given a ChildProdutImageI18n or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or ChildProdutImageI18n object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public function delete(ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - - $criteria = $this; - - // Set the correct dbName - $criteria->setDbName(ProdutImageI18nTableMap::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - - ProdutImageI18nTableMap::removeInstanceFromPool($criteria); - - $affectedRows += ModelCriteria::delete($con); - ProdutImageI18nTableMap::clearRelatedInstancePool(); - $con->commit(); - - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - -} // ProdutImageI18nQuery diff --git a/core/lib/Thelia/Model/Base/ProdutImageQuery.php b/core/lib/Thelia/Model/Base/ProdutImageQuery.php deleted file mode 100644 index 65376b641..000000000 --- a/core/lib/Thelia/Model/Base/ProdutImageQuery.php +++ /dev/null @@ -1,846 +0,0 @@ -setModelAlias($modelAlias); - } - if ($criteria instanceof Criteria) { - $query->mergeWith($criteria); - } - - return $query; - } - - /** - * Find object by primary key. - * Propel uses the instance pool to skip the database if the object exists. - * Go fast if the query is untouched. - * - * - * $obj = $c->findPk(12, $con); - * - * - * @param mixed $key Primary key to use for the query - * @param ConnectionInterface $con an optional connection object - * - * @return ChildProdutImage|array|mixed the result, formatted by the current formatter - */ - public function findPk($key, $con = null) - { - if ($key === null) { - return null; - } - if ((null !== ($obj = ProdutImageTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { - // the object is already in the instance pool - return $obj; - } - if ($con === null) { - $con = Propel::getServiceContainer()->getReadConnection(ProdutImageTableMap::DATABASE_NAME); - } - $this->basePreSelect($con); - if ($this->formatter || $this->modelAlias || $this->with || $this->select - || $this->selectColumns || $this->asColumns || $this->selectModifiers - || $this->map || $this->having || $this->joins) { - return $this->findPkComplex($key, $con); - } else { - return $this->findPkSimple($key, $con); - } - } - - /** - * Find object by primary key using raw SQL to go fast. - * Bypass doSelect() and the object formatter by using generated code. - * - * @param mixed $key Primary key to use for the query - * @param ConnectionInterface $con A connection object - * - * @return ChildProdutImage A model object, or null if the key is not found - */ - protected function findPkSimple($key, $con) - { - $sql = 'SELECT ID, PRODUCT_ID, FILE, POSITION, CREATED_AT, UPDATED_AT FROM produt_image WHERE ID = :p0'; - try { - $stmt = $con->prepare($sql); - $stmt->bindValue(':p0', $key, PDO::PARAM_INT); - $stmt->execute(); - } catch (Exception $e) { - Propel::log($e->getMessage(), Propel::LOG_ERR); - throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); - } - $obj = null; - if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { - $obj = new ChildProdutImage(); - $obj->hydrate($row); - ProdutImageTableMap::addInstanceToPool($obj, (string) $key); - } - $stmt->closeCursor(); - - return $obj; - } - - /** - * Find object by primary key. - * - * @param mixed $key Primary key to use for the query - * @param ConnectionInterface $con A connection object - * - * @return ChildProdutImage|array|mixed the result, formatted by the current formatter - */ - protected function findPkComplex($key, $con) - { - // As the query uses a PK condition, no limit(1) is necessary. - $criteria = $this->isKeepQuery() ? clone $this : $this; - $dataFetcher = $criteria - ->filterByPrimaryKey($key) - ->doSelect($con); - - return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); - } - - /** - * Find objects by primary key - * - * $objs = $c->findPks(array(12, 56, 832), $con); - * - * @param array $keys Primary keys to use for the query - * @param ConnectionInterface $con an optional connection object - * - * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter - */ - public function findPks($keys, $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); - } - $this->basePreSelect($con); - $criteria = $this->isKeepQuery() ? clone $this : $this; - $dataFetcher = $criteria - ->filterByPrimaryKeys($keys) - ->doSelect($con); - - return $criteria->getFormatter()->init($criteria)->format($dataFetcher); - } - - /** - * Filter the query by primary key - * - * @param mixed $key Primary key to use for the query - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByPrimaryKey($key) - { - - return $this->addUsingAlias(ProdutImageTableMap::ID, $key, Criteria::EQUAL); - } - - /** - * Filter the query by a list of primary keys - * - * @param array $keys The list of primary key to use for the query - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByPrimaryKeys($keys) - { - - return $this->addUsingAlias(ProdutImageTableMap::ID, $keys, Criteria::IN); - } - - /** - * Filter the query on the id column - * - * Example usage: - * - * $query->filterById(1234); // WHERE id = 1234 - * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) - * $query->filterById(array('min' => 12)); // WHERE id > 12 - * - * - * @param mixed $id The value to use as filter. - * Use scalar values for equality. - * Use array values for in_array() equivalent. - * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterById($id = null, $comparison = null) - { - if (is_array($id)) { - $useMinMax = false; - if (isset($id['min'])) { - $this->addUsingAlias(ProdutImageTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($id['max'])) { - $this->addUsingAlias(ProdutImageTableMap::ID, $id['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - - return $this->addUsingAlias(ProdutImageTableMap::ID, $id, $comparison); - } - - /** - * Filter the query on the product_id column - * - * Example usage: - * - * $query->filterByProductId(1234); // WHERE product_id = 1234 - * $query->filterByProductId(array(12, 34)); // WHERE product_id IN (12, 34) - * $query->filterByProductId(array('min' => 12)); // WHERE product_id > 12 - * - * - * @see filterByProduct() - * - * @param mixed $productId The value to use as filter. - * Use scalar values for equality. - * Use array values for in_array() equivalent. - * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByProductId($productId = null, $comparison = null) - { - if (is_array($productId)) { - $useMinMax = false; - if (isset($productId['min'])) { - $this->addUsingAlias(ProdutImageTableMap::PRODUCT_ID, $productId['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($productId['max'])) { - $this->addUsingAlias(ProdutImageTableMap::PRODUCT_ID, $productId['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - - return $this->addUsingAlias(ProdutImageTableMap::PRODUCT_ID, $productId, $comparison); - } - - /** - * Filter the query on the file column - * - * Example usage: - * - * $query->filterByFile('fooValue'); // WHERE file = 'fooValue' - * $query->filterByFile('%fooValue%'); // WHERE file LIKE '%fooValue%' - * - * - * @param string $file The value to use as filter. - * Accepts wildcards (* and % trigger a LIKE) - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByFile($file = null, $comparison = null) - { - if (null === $comparison) { - if (is_array($file)) { - $comparison = Criteria::IN; - } elseif (preg_match('/[\%\*]/', $file)) { - $file = str_replace('*', '%', $file); - $comparison = Criteria::LIKE; - } - } - - return $this->addUsingAlias(ProdutImageTableMap::FILE, $file, $comparison); - } - - /** - * Filter the query on the position column - * - * Example usage: - * - * $query->filterByPosition(1234); // WHERE position = 1234 - * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) - * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 - * - * - * @param mixed $position The value to use as filter. - * Use scalar values for equality. - * Use array values for in_array() equivalent. - * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByPosition($position = null, $comparison = null) - { - if (is_array($position)) { - $useMinMax = false; - if (isset($position['min'])) { - $this->addUsingAlias(ProdutImageTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($position['max'])) { - $this->addUsingAlias(ProdutImageTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - - return $this->addUsingAlias(ProdutImageTableMap::POSITION, $position, $comparison); - } - - /** - * Filter the query on the created_at column - * - * Example usage: - * - * $query->filterByCreatedAt('2011-03-14'); // WHERE created_at = '2011-03-14' - * $query->filterByCreatedAt('now'); // WHERE created_at = '2011-03-14' - * $query->filterByCreatedAt(array('max' => 'yesterday')); // WHERE created_at > '2011-03-13' - * - * - * @param mixed $createdAt The value to use as filter. - * Values can be integers (unix timestamps), DateTime objects, or strings. - * Empty strings are treated as NULL. - * Use scalar values for equality. - * Use array values for in_array() equivalent. - * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByCreatedAt($createdAt = null, $comparison = null) - { - if (is_array($createdAt)) { - $useMinMax = false; - if (isset($createdAt['min'])) { - $this->addUsingAlias(ProdutImageTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($createdAt['max'])) { - $this->addUsingAlias(ProdutImageTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - - return $this->addUsingAlias(ProdutImageTableMap::CREATED_AT, $createdAt, $comparison); - } - - /** - * Filter the query on the updated_at column - * - * Example usage: - * - * $query->filterByUpdatedAt('2011-03-14'); // WHERE updated_at = '2011-03-14' - * $query->filterByUpdatedAt('now'); // WHERE updated_at = '2011-03-14' - * $query->filterByUpdatedAt(array('max' => 'yesterday')); // WHERE updated_at > '2011-03-13' - * - * - * @param mixed $updatedAt The value to use as filter. - * Values can be integers (unix timestamps), DateTime objects, or strings. - * Empty strings are treated as NULL. - * Use scalar values for equality. - * Use array values for in_array() equivalent. - * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByUpdatedAt($updatedAt = null, $comparison = null) - { - if (is_array($updatedAt)) { - $useMinMax = false; - if (isset($updatedAt['min'])) { - $this->addUsingAlias(ProdutImageTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); - $useMinMax = true; - } - if (isset($updatedAt['max'])) { - $this->addUsingAlias(ProdutImageTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); - $useMinMax = true; - } - if ($useMinMax) { - return $this; - } - if (null === $comparison) { - $comparison = Criteria::IN; - } - } - - return $this->addUsingAlias(ProdutImageTableMap::UPDATED_AT, $updatedAt, $comparison); - } - - /** - * Filter the query by a related \Thelia\Model\Product object - * - * @param \Thelia\Model\Product|ObjectCollection $product The related object(s) to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByProduct($product, $comparison = null) - { - if ($product instanceof \Thelia\Model\Product) { - return $this - ->addUsingAlias(ProdutImageTableMap::PRODUCT_ID, $product->getId(), $comparison); - } elseif ($product instanceof ObjectCollection) { - if (null === $comparison) { - $comparison = Criteria::IN; - } - - return $this - ->addUsingAlias(ProdutImageTableMap::PRODUCT_ID, $product->toKeyValue('PrimaryKey', 'Id'), $comparison); - } else { - throw new PropelException('filterByProduct() only accepts arguments of type \Thelia\Model\Product or Collection'); - } - } - - /** - * Adds a JOIN clause to the query using the Product relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function joinProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('Product'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if ($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'Product'); - } - - return $this; - } - - /** - * Use the Product relation Product object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return \Thelia\Model\ProductQuery A secondary query class using the current class as primary query - */ - public function useProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) - { - return $this - ->joinProduct($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'Product', '\Thelia\Model\ProductQuery'); - } - - /** - * Filter the query by a related \Thelia\Model\ProdutImageI18n object - * - * @param \Thelia\Model\ProdutImageI18n|ObjectCollection $produtImageI18n the related object to use as filter - * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function filterByProdutImageI18n($produtImageI18n, $comparison = null) - { - if ($produtImageI18n instanceof \Thelia\Model\ProdutImageI18n) { - return $this - ->addUsingAlias(ProdutImageTableMap::ID, $produtImageI18n->getId(), $comparison); - } elseif ($produtImageI18n instanceof ObjectCollection) { - return $this - ->useProdutImageI18nQuery() - ->filterByPrimaryKeys($produtImageI18n->getPrimaryKeys()) - ->endUse(); - } else { - throw new PropelException('filterByProdutImageI18n() only accepts arguments of type \Thelia\Model\ProdutImageI18n or Collection'); - } - } - - /** - * Adds a JOIN clause to the query using the ProdutImageI18n relation - * - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function joinProdutImageI18n($relationAlias = null, $joinType = 'LEFT JOIN') - { - $tableMap = $this->getTableMap(); - $relationMap = $tableMap->getRelation('ProdutImageI18n'); - - // create a ModelJoin object for this join - $join = new ModelJoin(); - $join->setJoinType($joinType); - $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); - if ($previousJoin = $this->getPreviousJoin()) { - $join->setPreviousJoin($previousJoin); - } - - // add the ModelJoin to the current object - if ($relationAlias) { - $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); - $this->addJoinObject($join, $relationAlias); - } else { - $this->addJoinObject($join, 'ProdutImageI18n'); - } - - return $this; - } - - /** - * Use the ProdutImageI18n relation ProdutImageI18n object - * - * @see useQuery() - * - * @param string $relationAlias optional alias for the relation, - * to be used as main alias in the secondary query - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' - * - * @return \Thelia\Model\ProdutImageI18nQuery A secondary query class using the current class as primary query - */ - public function useProdutImageI18nQuery($relationAlias = null, $joinType = 'LEFT JOIN') - { - return $this - ->joinProdutImageI18n($relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'ProdutImageI18n', '\Thelia\Model\ProdutImageI18nQuery'); - } - - /** - * Exclude object from result - * - * @param ChildProdutImage $produtImage Object to remove from the list of results - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function prune($produtImage = null) - { - if ($produtImage) { - $this->addUsingAlias(ProdutImageTableMap::ID, $produtImage->getId(), Criteria::NOT_EQUAL); - } - - return $this; - } - - /** - * Deletes all rows from the produt_image table. - * - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). - */ - public function doDeleteAll(ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageTableMap::DATABASE_NAME); - } - $affectedRows = 0; // initialize var to track total num of affected rows - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - $affectedRows += parent::doDeleteAll($con); - // Because this db requires some delete cascade/set null emulation, we have to - // clear the cached instance *after* the emulation has happened (since - // instances get re-added by the select statement contained therein). - ProdutImageTableMap::clearInstancePool(); - ProdutImageTableMap::clearRelatedInstancePool(); - - $con->commit(); - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $affectedRows; - } - - /** - * Performs a DELETE on the database, given a ChildProdutImage or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or ChildProdutImage object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public function delete(ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageTableMap::DATABASE_NAME); - } - - $criteria = $this; - - // Set the correct dbName - $criteria->setDbName(ProdutImageTableMap::DATABASE_NAME); - - $affectedRows = 0; // initialize var to track total num of affected rows - - try { - // use transaction because $criteria could contain info - // for more than one table or we could emulating ON DELETE CASCADE, etc. - $con->beginTransaction(); - - - ProdutImageTableMap::removeInstanceFromPool($criteria); - - $affectedRows += ModelCriteria::delete($con); - ProdutImageTableMap::clearRelatedInstancePool(); - $con->commit(); - - return $affectedRows; - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - } - - // timestampable behavior - - /** - * Filter by the latest updated - * - * @param int $nbDays Maximum age of the latest update in days - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function recentlyUpdated($nbDays = 7) - { - return $this->addUsingAlias(ProdutImageTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); - } - - /** - * Filter by the latest created - * - * @param int $nbDays Maximum age of in days - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function recentlyCreated($nbDays = 7) - { - return $this->addUsingAlias(ProdutImageTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); - } - - /** - * Order by update date desc - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function lastUpdatedFirst() - { - return $this->addDescendingOrderByColumn(ProdutImageTableMap::UPDATED_AT); - } - - /** - * Order by update date asc - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function firstUpdatedFirst() - { - return $this->addAscendingOrderByColumn(ProdutImageTableMap::UPDATED_AT); - } - - /** - * Order by create date desc - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function lastCreatedFirst() - { - return $this->addDescendingOrderByColumn(ProdutImageTableMap::CREATED_AT); - } - - /** - * Order by create date asc - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function firstCreatedFirst() - { - return $this->addAscendingOrderByColumn(ProdutImageTableMap::CREATED_AT); - } - - // i18n behavior - - /** - * Adds a JOIN clause to the query using the i18n relation - * - * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function joinI18n($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) - { - $relationName = $relationAlias ? $relationAlias : 'ProdutImageI18n'; - - return $this - ->joinProdutImageI18n($relationAlias, $joinType) - ->addJoinCondition($relationName, $relationName . '.Locale = ?', $locale); - } - - /** - * Adds a JOIN clause to the query and hydrates the related I18n object. - * Shortcut for $c->joinI18n($locale)->with() - * - * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. - * - * @return ChildProdutImageQuery The current query, for fluid interface - */ - public function joinWithI18n($locale = 'en_US', $joinType = Criteria::LEFT_JOIN) - { - $this - ->joinI18n($locale, null, $joinType) - ->with('ProdutImageI18n'); - $this->with['ProdutImageI18n']->setIsWithOneToMany(false); - - return $this; - } - - /** - * Use the I18n relation query object - * - * @see useQuery() - * - * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' - * @param string $relationAlias optional alias for the relation - * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. - * - * @return ChildProdutImageI18nQuery A secondary query class using the current class as primary query - */ - public function useI18nQuery($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) - { - return $this - ->joinI18n($locale, $relationAlias, $joinType) - ->useQuery($relationAlias ? $relationAlias : 'ProdutImageI18n', '\Thelia\Model\ProdutImageI18nQuery'); - } - -} // ProdutImageQuery diff --git a/core/lib/Thelia/Model/Map/ProductTableMap.php b/core/lib/Thelia/Model/Map/ProductTableMap.php index 5fa712cce..75bf5e4e6 100644 --- a/core/lib/Thelia/Model/Map/ProductTableMap.php +++ b/core/lib/Thelia/Model/Map/ProductTableMap.php @@ -201,7 +201,7 @@ class ProductTableMap extends TableMap $this->addRelation('FeatureProduct', '\\Thelia\\Model\\FeatureProduct', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'FeatureProducts'); $this->addRelation('ProductSaleElements', '\\Thelia\\Model\\ProductSaleElements', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ProductSaleElementss'); $this->addRelation('ContentAssoc', '\\Thelia\\Model\\ContentAssoc', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ContentAssocs'); - $this->addRelation('ProdutImage', '\\Thelia\\Model\\ProdutImage', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ProdutImages'); + $this->addRelation('ProductImage', '\\Thelia\\Model\\ProductImage', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ProductImages'); $this->addRelation('ProductDocument', '\\Thelia\\Model\\ProductDocument', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'ProductDocuments'); $this->addRelation('AccessoryRelatedByProductId', '\\Thelia\\Model\\Accessory', RelationMap::ONE_TO_MANY, array('id' => 'product_id', ), 'CASCADE', 'RESTRICT', 'AccessoriesRelatedByProductId'); $this->addRelation('AccessoryRelatedByAccessory', '\\Thelia\\Model\\Accessory', RelationMap::ONE_TO_MANY, array('id' => 'accessory', ), 'CASCADE', 'RESTRICT', 'AccessoriesRelatedByAccessory'); @@ -239,7 +239,7 @@ class ProductTableMap extends TableMap FeatureProductTableMap::clearInstancePool(); ProductSaleElementsTableMap::clearInstancePool(); ContentAssocTableMap::clearInstancePool(); - ProdutImageTableMap::clearInstancePool(); + ProductImageTableMap::clearInstancePool(); ProductDocumentTableMap::clearInstancePool(); AccessoryTableMap::clearInstancePool(); RewritingTableMap::clearInstancePool(); diff --git a/core/lib/Thelia/Model/Map/ProdutImageI18nTableMap.php b/core/lib/Thelia/Model/Map/ProdutImageI18nTableMap.php deleted file mode 100644 index affc799e2..000000000 --- a/core/lib/Thelia/Model/Map/ProdutImageI18nTableMap.php +++ /dev/null @@ -1,497 +0,0 @@ - array('Id', 'Locale', 'Title', 'Description', 'Chapo', 'Postscriptum', ), - self::TYPE_STUDLYPHPNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), - self::TYPE_COLNAME => array(ProdutImageI18nTableMap::ID, ProdutImageI18nTableMap::LOCALE, ProdutImageI18nTableMap::TITLE, ProdutImageI18nTableMap::DESCRIPTION, ProdutImageI18nTableMap::CHAPO, ProdutImageI18nTableMap::POSTSCRIPTUM, ), - self::TYPE_RAW_COLNAME => array('ID', 'LOCALE', 'TITLE', 'DESCRIPTION', 'CHAPO', 'POSTSCRIPTUM', ), - self::TYPE_FIELDNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 - */ - protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Locale' => 1, 'Title' => 2, 'Description' => 3, 'Chapo' => 4, 'Postscriptum' => 5, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), - self::TYPE_COLNAME => array(ProdutImageI18nTableMap::ID => 0, ProdutImageI18nTableMap::LOCALE => 1, ProdutImageI18nTableMap::TITLE => 2, ProdutImageI18nTableMap::DESCRIPTION => 3, ProdutImageI18nTableMap::CHAPO => 4, ProdutImageI18nTableMap::POSTSCRIPTUM => 5, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'LOCALE' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'CHAPO' => 4, 'POSTSCRIPTUM' => 5, ), - self::TYPE_FIELDNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) - ); - - /** - * Initialize the table attributes and columns - * Relations are not initialized by this method since they are lazy loaded - * - * @return void - * @throws PropelException - */ - public function initialize() - { - // attributes - $this->setName('produt_image_i18n'); - $this->setPhpName('ProdutImageI18n'); - $this->setClassName('\\Thelia\\Model\\ProdutImageI18n'); - $this->setPackage('Thelia.Model'); - $this->setUseIdGenerator(false); - // columns - $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'produt_image', 'ID', true, null, null); - $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); - $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); - $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); - $this->addColumn('CHAPO', 'Chapo', 'LONGVARCHAR', false, null, null); - $this->addColumn('POSTSCRIPTUM', 'Postscriptum', 'LONGVARCHAR', false, null, null); - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('ProdutImage', '\\Thelia\\Model\\ProdutImage', RelationMap::MANY_TO_ONE, array('id' => 'id', ), 'CASCADE', null); - } // buildRelations() - - /** - * Adds an object to the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases you may need to explicitly add objects - * to the cache in order to ensure that the same objects are always returned by find*() - * and findPk*() calls. - * - * @param \Thelia\Model\ProdutImageI18n $obj A \Thelia\Model\ProdutImageI18n object. - * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). - */ - public static function addInstanceToPool($obj, $key = null) - { - if (Propel::isInstancePoolingEnabled()) { - if (null === $key) { - $key = serialize(array((string) $obj->getId(), (string) $obj->getLocale())); - } // if key === null - self::$instances[$key] = $obj; - } - } - - /** - * Removes an object from the instance pool. - * - * Propel keeps cached copies of objects in an instance pool when they are retrieved - * from the database. In some cases -- especially when you override doDelete - * methods in your stub classes -- you may need to explicitly remove objects - * from the cache in order to prevent returning objects that no longer exist. - * - * @param mixed $value A \Thelia\Model\ProdutImageI18n object or a primary key value. - */ - public static function removeInstanceFromPool($value) - { - if (Propel::isInstancePoolingEnabled() && null !== $value) { - if (is_object($value) && $value instanceof \Thelia\Model\ProdutImageI18n) { - $key = serialize(array((string) $value->getId(), (string) $value->getLocale())); - - } elseif (is_array($value) && count($value) === 2) { - // assume we've been passed a primary key"; - $key = serialize(array((string) $value[0], (string) $value[1])); - } elseif ($value instanceof Criteria) { - self::$instances = []; - - return; - } else { - $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or \Thelia\Model\ProdutImageI18n object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value, true))); - throw $e; - } - - unset(self::$instances[$key]); - } - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row resultset row. - * @param int $offset The 0-based offset for reading from the resultset row. - * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM - */ - public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)] === null) { - return null; - } - - return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)])); - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row resultset row. - * @param int $offset The 0-based offset for reading from the resultset row. - * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM - * - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) - { - - return $pks; - } - - /** - * The class that the tableMap will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is translated into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? ProdutImageI18nTableMap::CLASS_DEFAULT : ProdutImageI18nTableMap::OM_CLASS; - } - - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row row returned by DataFetcher->fetch(). - * @param int $offset The 0-based offset for reading from the resultset row. - * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). - One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (ProdutImageI18n object, last column rank) - */ - public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) - { - $key = ProdutImageI18nTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); - if (null !== ($obj = ProdutImageI18nTableMap::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $offset, true); // rehydrate - $col = $offset + ProdutImageI18nTableMap::NUM_HYDRATE_COLUMNS; - } else { - $cls = ProdutImageI18nTableMap::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $offset, false, $indexType); - ProdutImageI18nTableMap::addInstanceToPool($obj, $key); - } - - return array($obj, $col); - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @param DataFetcherInterface $dataFetcher - * @return array - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(DataFetcherInterface $dataFetcher) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = static::getOMClass(false); - // populate the object(s) - while ($row = $dataFetcher->fetch()) { - $key = ProdutImageI18nTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); - if (null !== ($obj = ProdutImageI18nTableMap::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - ProdutImageI18nTableMap::addInstanceToPool($obj, $key); - } // if key exists - } - - return $results; - } - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(ProdutImageI18nTableMap::ID); - $criteria->addSelectColumn(ProdutImageI18nTableMap::LOCALE); - $criteria->addSelectColumn(ProdutImageI18nTableMap::TITLE); - $criteria->addSelectColumn(ProdutImageI18nTableMap::DESCRIPTION); - $criteria->addSelectColumn(ProdutImageI18nTableMap::CHAPO); - $criteria->addSelectColumn(ProdutImageI18nTableMap::POSTSCRIPTUM); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.LOCALE'); - $criteria->addSelectColumn($alias . '.TITLE'); - $criteria->addSelectColumn($alias . '.DESCRIPTION'); - $criteria->addSelectColumn($alias . '.CHAPO'); - $criteria->addSelectColumn($alias . '.POSTSCRIPTUM'); - } - } - - /** - * Returns the TableMap related to this object. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getServiceContainer()->getDatabaseMap(ProdutImageI18nTableMap::DATABASE_NAME)->getTable(ProdutImageI18nTableMap::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this tableMap class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getServiceContainer()->getDatabaseMap(ProdutImageI18nTableMap::DATABASE_NAME); - if (!$dbMap->hasTable(ProdutImageI18nTableMap::TABLE_NAME)) { - $dbMap->addTableObject(new ProdutImageI18nTableMap()); - } - } - - /** - * Performs a DELETE on the database, given a ProdutImageI18n or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or ProdutImageI18n object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - - if ($values instanceof Criteria) { - // rename for clarity - $criteria = $values; - } elseif ($values instanceof \Thelia\Model\ProdutImageI18n) { // it's a model object - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(ProdutImageI18nTableMap::DATABASE_NAME); - // primary key is composite; we therefore, expect - // the primary key passed to be an array of pkey values - if (count($values) == count($values, COUNT_RECURSIVE)) { - // array is not multi-dimensional - $values = array($values); - } - foreach ($values as $value) { - $criterion = $criteria->getNewCriterion(ProdutImageI18nTableMap::ID, $value[0]); - $criterion->addAnd($criteria->getNewCriterion(ProdutImageI18nTableMap::LOCALE, $value[1])); - $criteria->addOr($criterion); - } - } - - $query = ProdutImageI18nQuery::create()->mergeWith($criteria); - - if ($values instanceof Criteria) { ProdutImageI18nTableMap::clearInstancePool(); - } elseif (!is_object($values)) { // it's a primary key, or an array of pks - foreach ((array) $values as $singleval) { ProdutImageI18nTableMap::removeInstanceFromPool($singleval); - } - } - - return $query->delete($con); - } - - /** - * Deletes all rows from the produt_image_i18n table. - * - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll(ConnectionInterface $con = null) - { - return ProdutImageI18nQuery::create()->doDeleteAll($con); - } - - /** - * Performs an INSERT on the database, given a ProdutImageI18n or Criteria object. - * - * @param mixed $criteria Criteria or ProdutImageI18n object containing data that is used to create the INSERT statement. - * @param ConnectionInterface $con the ConnectionInterface connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($criteria, ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageI18nTableMap::DATABASE_NAME); - } - - if ($criteria instanceof Criteria) { - $criteria = clone $criteria; // rename for clarity - } else { - $criteria = $criteria->buildCriteria(); // build Criteria from ProdutImageI18n object - } - - - // Set the correct dbName - $query = ProdutImageI18nQuery::create()->mergeWith($criteria); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = $query->doInsert($con); - $con->commit(); - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - -} // ProdutImageI18nTableMap -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -ProdutImageI18nTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/ProdutImageTableMap.php b/core/lib/Thelia/Model/Map/ProdutImageTableMap.php deleted file mode 100644 index a415ba991..000000000 --- a/core/lib/Thelia/Model/Map/ProdutImageTableMap.php +++ /dev/null @@ -1,475 +0,0 @@ - array('Id', 'ProductId', 'File', 'Position', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'file', 'position', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(ProdutImageTableMap::ID, ProdutImageTableMap::PRODUCT_ID, ProdutImageTableMap::FILE, ProdutImageTableMap::POSITION, ProdutImageTableMap::CREATED_AT, ProdutImageTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'FILE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'product_id', 'file', 'position', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) - ); - - /** - * holds an array of keys for quick access to the fieldnames array - * - * first dimension keys are the type constants - * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 - */ - protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'File' => 2, 'Position' => 3, 'CreatedAt' => 4, 'UpdatedAt' => 5, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'file' => 2, 'position' => 3, 'createdAt' => 4, 'updatedAt' => 5, ), - self::TYPE_COLNAME => array(ProdutImageTableMap::ID => 0, ProdutImageTableMap::PRODUCT_ID => 1, ProdutImageTableMap::FILE => 2, ProdutImageTableMap::POSITION => 3, ProdutImageTableMap::CREATED_AT => 4, ProdutImageTableMap::UPDATED_AT => 5, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'FILE' => 2, 'POSITION' => 3, 'CREATED_AT' => 4, 'UPDATED_AT' => 5, ), - self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'file' => 2, 'position' => 3, 'created_at' => 4, 'updated_at' => 5, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) - ); - - /** - * Initialize the table attributes and columns - * Relations are not initialized by this method since they are lazy loaded - * - * @return void - * @throws PropelException - */ - public function initialize() - { - // attributes - $this->setName('produt_image'); - $this->setPhpName('ProdutImage'); - $this->setClassName('\\Thelia\\Model\\ProdutImage'); - $this->setPackage('Thelia.Model'); - $this->setUseIdGenerator(true); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addForeignKey('PRODUCT_ID', 'ProductId', 'INTEGER', 'product', 'ID', true, null, null); - $this->addColumn('FILE', 'File', 'VARCHAR', true, 255, null); - $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); - $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); - $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::MANY_TO_ONE, array('product_id' => 'id', ), 'CASCADE', 'RESTRICT'); - $this->addRelation('ProdutImageI18n', '\\Thelia\\Model\\ProdutImageI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'ProdutImageI18ns'); - } // buildRelations() - - /** - * - * Gets the list of behaviors registered for this table - * - * @return array Associative array (name => parameters) of behaviors - */ - public function getBehaviors() - { - return array( - 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), - 'i18n' => array('i18n_table' => '%TABLE%_i18n', 'i18n_phpname' => '%PHPNAME%I18n', 'i18n_columns' => 'title, description, chapo, postscriptum', 'locale_column' => 'locale', 'locale_length' => '5', 'default_locale' => '', 'locale_alias' => '', ), - ); - } // getBehaviors() - /** - * Method to invalidate the instance pool of all tables related to produt_image * by a foreign key with ON DELETE CASCADE - */ - public static function clearRelatedInstancePool() - { - // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, - // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. - ProdutImageI18nTableMap::clearInstancePool(); - } - - /** - * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. - * - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, a serialize()d version of the primary key will be returned. - * - * @param array $row resultset row. - * @param int $offset The 0-based offset for reading from the resultset row. - * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM - */ - public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) - { - // If the PK cannot be derived from the row, return NULL. - if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { - return null; - } - - return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; - } - - /** - * Retrieves the primary key from the DB resultset row - * For tables with a single-column primary key, that simple pkey value will be returned. For tables with - * a multi-column primary key, an array of the primary key columns will be returned. - * - * @param array $row resultset row. - * @param int $offset The 0-based offset for reading from the resultset row. - * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM - * - * @return mixed The primary key of the row - */ - public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) - { - - return (int) $row[ - $indexType == TableMap::TYPE_NUM - ? 0 + $offset - : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) - ]; - } - - /** - * The class that the tableMap will make instances of. - * - * If $withPrefix is true, the returned path - * uses a dot-path notation which is translated into a path - * relative to a location on the PHP include_path. - * (e.g. path.to.MyClass -> 'path/to/MyClass.php') - * - * @param boolean $withPrefix Whether or not to return the path with the class name - * @return string path.to.ClassName - */ - public static function getOMClass($withPrefix = true) - { - return $withPrefix ? ProdutImageTableMap::CLASS_DEFAULT : ProdutImageTableMap::OM_CLASS; - } - - /** - * Populates an object of the default type or an object that inherit from the default. - * - * @param array $row row returned by DataFetcher->fetch(). - * @param int $offset The 0-based offset for reading from the resultset row. - * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). - One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME - * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. - * - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - * @return array (ProdutImage object, last column rank) - */ - public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) - { - $key = ProdutImageTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); - if (null !== ($obj = ProdutImageTableMap::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, $offset, true); // rehydrate - $col = $offset + ProdutImageTableMap::NUM_HYDRATE_COLUMNS; - } else { - $cls = ProdutImageTableMap::OM_CLASS; - $obj = new $cls(); - $col = $obj->hydrate($row, $offset, false, $indexType); - ProdutImageTableMap::addInstanceToPool($obj, $key); - } - - return array($obj, $col); - } - - /** - * The returned array will contain objects of the default type or - * objects that inherit from the default. - * - * @param DataFetcherInterface $dataFetcher - * @return array - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function populateObjects(DataFetcherInterface $dataFetcher) - { - $results = array(); - - // set the class once to avoid overhead in the loop - $cls = static::getOMClass(false); - // populate the object(s) - while ($row = $dataFetcher->fetch()) { - $key = ProdutImageTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); - if (null !== ($obj = ProdutImageTableMap::getInstanceFromPool($key))) { - // We no longer rehydrate the object, since this can cause data loss. - // See http://www.propelorm.org/ticket/509 - // $obj->hydrate($row, 0, true); // rehydrate - $results[] = $obj; - } else { - $obj = new $cls(); - $obj->hydrate($row); - $results[] = $obj; - ProdutImageTableMap::addInstanceToPool($obj, $key); - } // if key exists - } - - return $results; - } - /** - * Add all the columns needed to create a new object. - * - * Note: any columns that were marked with lazyLoad="true" in the - * XML schema will not be added to the select list and only loaded - * on demand. - * - * @param Criteria $criteria object containing the columns to add. - * @param string $alias optional table alias - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function addSelectColumns(Criteria $criteria, $alias = null) - { - if (null === $alias) { - $criteria->addSelectColumn(ProdutImageTableMap::ID); - $criteria->addSelectColumn(ProdutImageTableMap::PRODUCT_ID); - $criteria->addSelectColumn(ProdutImageTableMap::FILE); - $criteria->addSelectColumn(ProdutImageTableMap::POSITION); - $criteria->addSelectColumn(ProdutImageTableMap::CREATED_AT); - $criteria->addSelectColumn(ProdutImageTableMap::UPDATED_AT); - } else { - $criteria->addSelectColumn($alias . '.ID'); - $criteria->addSelectColumn($alias . '.PRODUCT_ID'); - $criteria->addSelectColumn($alias . '.FILE'); - $criteria->addSelectColumn($alias . '.POSITION'); - $criteria->addSelectColumn($alias . '.CREATED_AT'); - $criteria->addSelectColumn($alias . '.UPDATED_AT'); - } - } - - /** - * Returns the TableMap related to this object. - * This method is not needed for general use but a specific application could have a need. - * @return TableMap - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function getTableMap() - { - return Propel::getServiceContainer()->getDatabaseMap(ProdutImageTableMap::DATABASE_NAME)->getTable(ProdutImageTableMap::TABLE_NAME); - } - - /** - * Add a TableMap instance to the database for this tableMap class. - */ - public static function buildTableMap() - { - $dbMap = Propel::getServiceContainer()->getDatabaseMap(ProdutImageTableMap::DATABASE_NAME); - if (!$dbMap->hasTable(ProdutImageTableMap::TABLE_NAME)) { - $dbMap->addTableObject(new ProdutImageTableMap()); - } - } - - /** - * Performs a DELETE on the database, given a ProdutImage or Criteria object OR a primary key value. - * - * @param mixed $values Criteria or ProdutImage object or primary key or array of primary keys - * which is used to create the DELETE statement - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows - * if supported by native driver or if emulated using Propel. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doDelete($values, ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageTableMap::DATABASE_NAME); - } - - if ($values instanceof Criteria) { - // rename for clarity - $criteria = $values; - } elseif ($values instanceof \Thelia\Model\ProdutImage) { // it's a model object - // create criteria based on pk values - $criteria = $values->buildPkeyCriteria(); - } else { // it's a primary key, or an array of pks - $criteria = new Criteria(ProdutImageTableMap::DATABASE_NAME); - $criteria->add(ProdutImageTableMap::ID, (array) $values, Criteria::IN); - } - - $query = ProdutImageQuery::create()->mergeWith($criteria); - - if ($values instanceof Criteria) { ProdutImageTableMap::clearInstancePool(); - } elseif (!is_object($values)) { // it's a primary key, or an array of pks - foreach ((array) $values as $singleval) { ProdutImageTableMap::removeInstanceFromPool($singleval); - } - } - - return $query->delete($con); - } - - /** - * Deletes all rows from the produt_image table. - * - * @param ConnectionInterface $con the connection to use - * @return int The number of affected rows (if supported by underlying database driver). - */ - public static function doDeleteAll(ConnectionInterface $con = null) - { - return ProdutImageQuery::create()->doDeleteAll($con); - } - - /** - * Performs an INSERT on the database, given a ProdutImage or Criteria object. - * - * @param mixed $criteria Criteria or ProdutImage object containing data that is used to create the INSERT statement. - * @param ConnectionInterface $con the ConnectionInterface connection to use - * @return mixed The new primary key. - * @throws PropelException Any exceptions caught during processing will be - * rethrown wrapped into a PropelException. - */ - public static function doInsert($criteria, ConnectionInterface $con = null) - { - if (null === $con) { - $con = Propel::getServiceContainer()->getWriteConnection(ProdutImageTableMap::DATABASE_NAME); - } - - if ($criteria instanceof Criteria) { - $criteria = clone $criteria; // rename for clarity - } else { - $criteria = $criteria->buildCriteria(); // build Criteria from ProdutImage object - } - - if ($criteria->containsKey(ProdutImageTableMap::ID) && $criteria->keyContainsValue(ProdutImageTableMap::ID) ) { - throw new PropelException('Cannot insert a value for auto-increment primary key ('.ProdutImageTableMap::ID.')'); - } - - - // Set the correct dbName - $query = ProdutImageQuery::create()->mergeWith($criteria); - - try { - // use transaction because $criteria could contain info - // for more than one table (I guess, conceivably) - $con->beginTransaction(); - $pk = $query->doInsert($con); - $con->commit(); - } catch (PropelException $e) { - $con->rollBack(); - throw $e; - } - - return $pk; - } - -} // ProdutImageTableMap -// This is the static code needed to register the TableMap for this table with the main Propel class. -// -ProdutImageTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/ProdutImage.php b/core/lib/Thelia/Model/ProdutImage.php deleted file mode 100644 index 46909f15d..000000000 --- a/core/lib/Thelia/Model/ProdutImage.php +++ /dev/null @@ -1,10 +0,0 @@ - - +
From e2083d4cbf62bcb3152370e8d73ad13351a93570 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 11:10:32 +0200 Subject: [PATCH 02/11] Typo: fixed ProdutImage -> ProductImage --- install/thelia.sql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/install/thelia.sql b/install/thelia.sql index 547f22786..1e80ab01d 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -603,12 +603,12 @@ CREATE TABLE `content_assoc` ) ENGINE=InnoDB; -- --------------------------------------------------------------------- --- produt_image +-- product_image -- --------------------------------------------------------------------- -DROP TABLE IF EXISTS `produt_image`; +DROP TABLE IF EXISTS `product_image`; -CREATE TABLE `produt_image` +CREATE TABLE `product_image` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `product_id` INTEGER NOT NULL, @@ -1721,12 +1721,12 @@ CREATE TABLE `content_i18n` ) ENGINE=InnoDB; -- --------------------------------------------------------------------- --- produt_image_i18n +-- product_image_i18n -- --------------------------------------------------------------------- -DROP TABLE IF EXISTS `produt_image_i18n`; +DROP TABLE IF EXISTS `product_image_i18n`; -CREATE TABLE `produt_image_i18n` +CREATE TABLE `product_image_i18n` ( `id` INTEGER NOT NULL, `locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL, @@ -1735,9 +1735,9 @@ CREATE TABLE `produt_image_i18n` `chapo` TEXT, `postscriptum` TEXT, PRIMARY KEY (`id`,`locale`), - CONSTRAINT `produt_image_i18n_FK_1` + CONSTRAINT `product_image_i18n_FK_1` FOREIGN KEY (`id`) - REFERENCES `produt_image` (`id`) + REFERENCES `product_image` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB; From bceb65dad699e28c0198d539b02bb246e45c5a25 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 11:27:30 +0200 Subject: [PATCH 03/11] Reverted symfony/validator from 2.3 to 2.2, because of failures in dependencies. --- composer.json | 6 +- composer.lock | 328 +++++++++++++++++++++++++++++--------------------- 2 files changed, 197 insertions(+), 137 deletions(-) diff --git a/composer.json b/composer.json index 5e86dad43..cf7822189 100755 --- a/composer.json +++ b/composer.json @@ -27,14 +27,16 @@ "symfony-cmf/routing": "1.0.0", "symfony/form": "2.2.*", - "symfony/validator": "2.3.*", + "symfony/validator": "2.2.*", "smarty/smarty": "v3.1.14", "kriswallsmith/assetic": "1.2.*@dev", "leafo/lessphp": "0.3.*@dev", "ptachoire/cssembed": "dev-master", - "simplepie/simplepie": "dev-master" + "simplepie/simplepie": "dev-master", + + "imagine/imagine": "dev-master" }, "require-dev" : { "phpunit/phpunit": "3.7.*", diff --git a/composer.lock b/composer.lock index 45044d90c..054d1f71f 100755 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "b20fbb4995fbf676a7028034f21cfbe0", + "hash": "21a698b038efa96e592a3673a760c065", "packages": [ { "name": "ezyang/htmlpurifier", @@ -49,6 +49,58 @@ ], "time": "2013-07-27 04:54:53" }, + { + "name": "imagine/imagine", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/avalanche123/Imagine.git", + "reference": "v0.5.0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/v0.5.0", + "reference": "v0.5.0", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "sami/sami": "dev-master" + }, + "suggest": { + "ext-gd": "to use the GD implementation", + "ext-gmagick": "to use the Gmagick implementation", + "ext-imagick": "to use the Imagick implementation" + }, + "type": "library", + "autoload": { + "psr-0": { + "Imagine": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bulat Shakirzyanov", + "email": "mallluhuct@gmail.com", + "homepage": "http://avalanche123.com" + } + ], + "description": "Image processing for PHP 5.3", + "homepage": "http://imagine.readthedocs.org/", + "keywords": [ + "drawing", + "graphics", + "image manipulation", + "image processing" + ], + "time": "2013-07-10 17:25:36" + }, { "name": "ircmaxell/password-compat", "version": "dev-master", @@ -165,12 +217,12 @@ "source": { "type": "git", "url": "https://github.com/leafo/lessphp.git", - "reference": "366fb52798d4f120503af0703da11cba4ad06f8d" + "reference": "v0.4.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/leafo/lessphp/zipball/366fb52798d4f120503af0703da11cba4ad06f8d", - "reference": "366fb52798d4f120503af0703da11cba4ad06f8d", + "url": "https://api.github.com/repos/leafo/lessphp/zipball/v0.4.0", + "reference": "v0.4.0", "shasum": "" }, "type": "library", @@ -198,7 +250,7 @@ ], "description": "lessphp is a compiler for LESS written in PHP.", "homepage": "http://leafo.net/lessphp/", - "time": "2013-07-09 16:25:09" + "time": "2013-08-09 17:09:19" }, { "name": "propel/propel", @@ -206,12 +258,12 @@ "source": { "type": "git", "url": "https://github.com/propelorm/Propel2.git", - "reference": "4cf5fca150ed93b33dc54206e3d9d943d0712621" + "reference": "c33b5ade89d0d6c1be7dd9252102ddee6b620890" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/propelorm/Propel2/zipball/4cf5fca150ed93b33dc54206e3d9d943d0712621", - "reference": "4cf5fca150ed93b33dc54206e3d9d943d0712621", + "url": "https://api.github.com/repos/propelorm/Propel2/zipball/c33b5ade89d0d6c1be7dd9252102ddee6b620890", + "reference": "c33b5ade89d0d6c1be7dd9252102ddee6b620890", "shasum": "" }, "require": { @@ -220,7 +272,7 @@ "symfony/console": "~2.2", "symfony/filesystem": "~2.2", "symfony/finder": "~2.2", - "symfony/validator": "~2.2", + "symfony/validator": "2.2.*@dev", "symfony/yaml": "~2.2" }, "require-dev": { @@ -258,7 +310,7 @@ "orm", "persistence" ], - "time": "2013-07-10 11:32:06" + "time": "2013-08-14 23:15:50" }, { "name": "psr/log", @@ -488,17 +540,17 @@ }, { "name": "symfony/class-loader", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/ClassLoader", "source": { "type": "git", "url": "https://github.com/symfony/ClassLoader.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -538,17 +590,17 @@ }, { "name": "symfony/config", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Config/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -581,21 +633,21 @@ ], "description": "Symfony Config Component", "homepage": "http://symfony.com", - "time": "2013-07-10 14:03:01" + "time": "2013-08-06 02:31:28" }, { "name": "symfony/console", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Console/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -632,17 +684,17 @@ }, { "name": "symfony/dependency-injection", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -683,21 +735,21 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "http://symfony.com", - "time": "2013-05-06 08:37:50" + "time": "2013-07-21 09:38:59" }, { "name": "symfony/event-dispatcher", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -741,17 +793,17 @@ }, { "name": "symfony/filesystem", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Filesystem", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -788,17 +840,17 @@ }, { "name": "symfony/finder", - "version": "v2.3.2", + "version": "v2.3.3", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "v2.3.2" + "reference": "v2.3.3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.2", - "reference": "v2.3.2", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.3", + "reference": "v2.3.3", "shasum": "" }, "require": { @@ -831,21 +883,21 @@ ], "description": "Symfony Finder Component", "homepage": "http://symfony.com", - "time": "2013-07-01 12:17:23" + "time": "2013-07-21 12:12:18" }, { "name": "symfony/form", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Form", "source": { "type": "git", "url": "https://github.com/symfony/Form.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Form/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Form/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -890,21 +942,21 @@ ], "description": "Symfony Form Component", "homepage": "http://symfony.com", - "time": "2013-06-23 07:35:41" + "time": "2013-08-02 13:12:51" }, { "name": "symfony/http-foundation", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -940,21 +992,21 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "http://symfony.com", - "time": "2013-07-15 12:12:07" + "time": "2013-08-07 14:00:53" }, { "name": "symfony/http-kernel", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -972,7 +1024,8 @@ "symfony/finder": "~2.0", "symfony/process": "~2.0", "symfony/routing": ">=2.2,<2.3-dev", - "symfony/stopwatch": ">=2.2,<2.3-dev" + "symfony/stopwatch": ">=2.2,<2.3-dev", + "symfony/templating": "~2.2" }, "suggest": { "symfony/browser-kit": "2.2.*", @@ -1009,25 +1062,24 @@ ], "description": "Symfony HttpKernel Component", "homepage": "http://symfony.com", - "time": "2013-07-15 12:28:01" + "time": "2013-08-07 15:57:43" }, { "name": "symfony/icu", - "version": "v1.2.0", + "version": "v1.0.0", "target-dir": "Symfony/Component/Icu", "source": { "type": "git", "url": "https://github.com/symfony/Icu.git", - "reference": "v1.2.0" + "reference": "v1.0.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Icu/zipball/v1.2.0", - "reference": "v1.2.0", + "url": "https://api.github.com/repos/symfony/Icu/zipball/v1.0.0", + "reference": "v1.0.0", "shasum": "" }, "require": { - "lib-icu": ">=4.4", "php": ">=5.3.3", "symfony/intl": ">=2.3,<3.0" }, @@ -1057,21 +1109,21 @@ "icu", "intl" ], - "time": "2013-06-03 18:32:58" + "time": "2013-06-03 18:32:07" }, { "name": "symfony/intl", - "version": "v2.3.2", + "version": "v2.3.3", "target-dir": "Symfony/Component/Intl", "source": { "type": "git", "url": "https://github.com/symfony/Intl.git", - "reference": "v2.3.2" + "reference": "v2.3.3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.2", - "reference": "v2.3.2", + "url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.3", + "reference": "v2.3.3", "shasum": "" }, "require": { @@ -1134,21 +1186,21 @@ "l10n", "localization" ], - "time": "2013-07-08 13:00:35" + "time": "2013-08-01 12:40:45" }, { "name": "symfony/locale", - "version": "v2.3.2", + "version": "v2.3.3", "target-dir": "Symfony/Component/Locale", "source": { "type": "git", "url": "https://github.com/symfony/Locale.git", - "reference": "v2.3.2" + "reference": "v2.3.3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Locale/zipball/v2.3.2", - "reference": "v2.3.2", + "url": "https://api.github.com/repos/symfony/Locale/zipball/v2.3.3", + "reference": "v2.3.3", "shasum": "" }, "require": { @@ -1186,17 +1238,17 @@ }, { "name": "symfony/options-resolver", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/OptionsResolver", "source": { "type": "git", "url": "https://github.com/symfony/OptionsResolver.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -1238,17 +1290,17 @@ }, { "name": "symfony/process", - "version": "v2.3.2", + "version": "v2.3.3", "target-dir": "Symfony/Component/Process", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "v2.3.2" + "reference": "v2.3.3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.2", - "reference": "v2.3.2", + "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.3", + "reference": "v2.3.3", "shasum": "" }, "require": { @@ -1281,21 +1333,21 @@ ], "description": "Symfony Process Component", "homepage": "http://symfony.com", - "time": "2013-07-01 12:24:43" + "time": "2013-08-02 21:51:01" }, { "name": "symfony/property-access", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/PropertyAccess", "source": { "type": "git", "url": "https://github.com/symfony/PropertyAccess.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -1339,21 +1391,21 @@ "property path", "reflection" ], - "time": "2013-04-07 22:02:49" + "time": "2013-07-28 18:26:16" }, { "name": "symfony/routing", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Routing", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -1397,21 +1449,21 @@ ], "description": "Symfony Routing Component", "homepage": "http://symfony.com", - "time": "2013-06-23 06:56:04" + "time": "2013-07-30 11:22:46" }, { "name": "symfony/translation", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -1452,21 +1504,21 @@ ], "description": "Symfony Translation Component", "homepage": "http://symfony.com", - "time": "2013-05-10 16:49:00" + "time": "2013-07-28 18:26:16" }, { "name": "symfony/validator", - "version": "v2.3.2", + "version": "v2.2.5", "target-dir": "Symfony/Component/Validator", "source": { "type": "git", "url": "https://github.com/symfony/Validator.git", - "reference": "v2.3.2" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/v2.3.2", - "reference": "v2.3.2", + "url": "https://api.github.com/repos/symfony/Validator/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -1474,22 +1526,22 @@ "symfony/translation": "~2.0" }, "require-dev": { - "symfony/config": "~2.2", + "symfony/config": ">=2.2,<2.3-dev", "symfony/http-foundation": "~2.1", - "symfony/intl": "~2.3", + "symfony/locale": "~2.0", "symfony/yaml": "~2.0" }, "suggest": { - "doctrine/common": "", - "symfony/config": "", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/yaml": "" + "doctrine/common": "~2.2", + "symfony/config": "2.2.*", + "symfony/http-foundation": "2.2.*", + "symfony/locale": "2.2.*", + "symfony/yaml": "2.2.*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "2.2-dev" } }, "autoload": { @@ -1513,21 +1565,21 @@ ], "description": "Symfony Validator Component", "homepage": "http://symfony.com", - "time": "2013-07-08 13:36:15" + "time": "2013-08-06 05:59:38" }, { "name": "symfony/yaml", - "version": "v2.2.4", + "version": "v2.2.5", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "v2.2.4" + "reference": "v2.2.5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.4", - "reference": "v2.2.4", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.5", + "reference": "v2.2.5", "shasum": "" }, "require": { @@ -1570,12 +1622,12 @@ "source": { "type": "git", "url": "https://github.com/fzaninotto/Faker.git", - "reference": "3613b1466d5e9518b83f87d828f93f962ff0f997" + "reference": "feb6492762a77db946bc13cc44a20a01546be0e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/3613b1466d5e9518b83f87d828f93f962ff0f997", - "reference": "3613b1466d5e9518b83f87d828f93f962ff0f997", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/feb6492762a77db946bc13cc44a20a01546be0e6", + "reference": "feb6492762a77db946bc13cc44a20a01546be0e6", "shasum": "" }, "require": { @@ -1608,7 +1660,7 @@ "faker", "fixtures" ], - "time": "2013-07-15 16:26:12" + "time": "2013-08-12 10:05:47" }, { "name": "phpunit/php-code-coverage", @@ -1762,16 +1814,16 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.4", + "version": "1.0.5", "source": { "type": "git", - "url": "git://github.com/sebastianbergmann/php-timer.git", - "reference": "1.0.4" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1.0.5" }, "dist": { "type": "zip", - "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", - "reference": "1.0.4", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1.0.5", + "reference": "1.0.5", "shasum": "" }, "require": { @@ -1798,24 +1850,24 @@ } ], "description": "Utility class for timing", - "homepage": "http://www.phpunit.de/", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ "timer" ], - "time": "2012-10-11 04:45:58" + "time": "2013-08-02 07:42:54" }, { "name": "phpunit/php-token-stream", - "version": "1.1.7", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1.1.7" + "reference": "1.2.0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1.1.7", - "reference": "1.1.7", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1.2.0", + "reference": "1.2.0", "shasum": "" }, "require": { @@ -1823,6 +1875,11 @@ "php": ">=5.3.3" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, "autoload": { "classmap": [ "PHP/" @@ -1847,20 +1904,20 @@ "keywords": [ "tokenizer" ], - "time": "2013-07-29 14:27:06" + "time": "2013-08-04 05:57:48" }, { "name": "phpunit/phpunit", - "version": "3.7.22", + "version": "3.7.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "3.7.22" + "reference": "3.7.24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.22", - "reference": "3.7.22", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.24", + "reference": "3.7.24", "shasum": "" }, "require": { @@ -1872,7 +1929,7 @@ "phpunit/php-code-coverage": "~1.2.1", "phpunit/php-file-iterator": ">=1.3.1", "phpunit/php-text-template": ">=1.1.1", - "phpunit/php-timer": "~1.0.2", + "phpunit/php-timer": ">=1.0.4", "phpunit/phpunit-mock-objects": "~1.2.0", "symfony/yaml": "~2.0" }, @@ -1921,7 +1978,7 @@ "testing", "xunit" ], - "time": "2013-07-06 06:29:15" + "time": "2013-08-09 06:58:24" }, { "name": "phpunit/phpunit-mock-objects", @@ -1985,6 +2042,7 @@ "leafo/lessphp": 20, "ptachoire/cssembed": 20, "simplepie/simplepie": 20, + "imagine/imagine": 20, "fzaninotto/faker": 20 }, "platform": { From 47bc54501942929aea5d5ac72ef48cac2146be3f Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 11:44:46 +0200 Subject: [PATCH 04/11] Added image processing actgion and loop --- core/lib/Thelia/Action/BaseAction.php | 1 - core/lib/Thelia/Core/Event/TheliaEvents.php | 6 ++ .../Thelia/Core/Template/Element/BaseLoop.php | 10 ++-- .../Thelia/Core/Template/Loop/Category.php | 6 +- .../lib/Thelia/Core/Template/Loop/Content.php | 4 +- .../lib/Thelia/Core/Template/Loop/Feature.php | 4 +- .../Core/Template/Loop/FeatureAvailable.php | 4 +- .../Core/Template/Loop/FeatureValue.php | 4 +- core/lib/Thelia/Core/Template/Loop/Folder.php | 4 +- .../lib/Thelia/Core/Template/Loop/Product.php | 4 +- .../Thelia/Tests/Command/CacheClearTest.php | 58 +++++++++++-------- install/INSTALL-TODO.txt | 2 + install/insert.sql | 5 ++ local/config/database.yml.sample | 6 -- 14 files changed, 66 insertions(+), 52 deletions(-) delete mode 100755 local/config/database.yml.sample diff --git a/core/lib/Thelia/Action/BaseAction.php b/core/lib/Thelia/Action/BaseAction.php index fde3607c8..bef57b30d 100644 --- a/core/lib/Thelia/Action/BaseAction.php +++ b/core/lib/Thelia/Action/BaseAction.php @@ -30,7 +30,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; class BaseAction { - /** * @var The container */ diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index ac3306c6a..0f512fab3 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -134,4 +134,10 @@ final class TheliaEvents const CART_CHANGEITEM = "action.changeArticle"; const CART_DELETEITEM = "action.deleteArticle"; + + /** + * Sent on image processing + */ + const IMAGE_PROCESS = "action.processImage"; + } diff --git a/core/lib/Thelia/Core/Template/Element/BaseLoop.php b/core/lib/Thelia/Core/Template/Element/BaseLoop.php index bcc7837dc..b5ee03955 100755 --- a/core/lib/Thelia/Core/Template/Element/BaseLoop.php +++ b/core/lib/Thelia/Core/Template/Element/BaseLoop.php @@ -163,7 +163,7 @@ abstract class BaseLoop * @throws \InvalidArgumentException if argument is not found in loop argument list * @return Argument the loop argument. */ - public function getArg($argumentName) + protected function getArg($argumentName) { $arg = $this->args->get($argumentName); @@ -181,7 +181,7 @@ abstract class BaseLoop * @throws \InvalidArgumentException if argument is not found in loop argument list * @return Argument the loop argument. */ - public function getArgValue($argumentName) + protected function getArgValue($argumentName) { return $this->getArg($argumentName)->getValue(); } @@ -192,7 +192,7 @@ abstract class BaseLoop * * @return array|mixed|\PropelModelPager|\PropelObjectCollection */ - public function search(ModelCriteria $search, &$pagination = null) + protected function search(ModelCriteria $search, &$pagination = null) { if ($this->getArgValue('page') !== null) { return $this->searchWithPagination($search, $pagination); @@ -206,7 +206,7 @@ abstract class BaseLoop * * @return array|mixed|\PropelObjectCollection */ - public function searchWithOffset(ModelCriteria $search) + protected function searchWithOffset(ModelCriteria $search) { if ($this->getArgValue('limit') >= 0) { $search->limit($this->getArgValue('limit')); @@ -222,7 +222,7 @@ abstract class BaseLoop * * @return array|\PropelModelPager */ - public function searchWithPagination(ModelCriteria $search, &$pagination) + protected function searchWithPagination(ModelCriteria $search, &$pagination) { $pagination = $search->paginate($this->getArgValue('page'), $this->getArgValue('limit')); diff --git a/core/lib/Thelia/Core/Template/Loop/Category.php b/core/lib/Thelia/Core/Template/Loop/Category.php index a0e636926..4cde51824 100755 --- a/core/lib/Thelia/Core/Template/Loop/Category.php +++ b/core/lib/Thelia/Core/Template/Loop/Category.php @@ -46,7 +46,7 @@ use Thelia\Type\BooleanOrBothType; * - current : current id is used if you are on a category page * - not_empty : if value is 1, category and subcategories must have at least 1 product * - visible : default 1, if you want category not visible put 0 - * - order : all value available : 'alpha', 'alpha_reverse', 'manual' (default), 'manual-reverse', 'random' + * - order : all value available : 'alpha', 'alpha-reverse', 'manual' (default), 'manual-reverse', 'random' * - exclude : all category id you want to exclude (as for id, an integer or a "string list" can be used) * * example : @@ -77,7 +77,7 @@ class Category extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual-reverse', 'random')) + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) ), 'manual' ), @@ -130,7 +130,7 @@ class Category extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\CategoryI18nTableMap::TITLE); break; case "manual-reverse": diff --git a/core/lib/Thelia/Core/Template/Loop/Content.php b/core/lib/Thelia/Core/Template/Loop/Content.php index 7131c1d7e..15bb2068c 100755 --- a/core/lib/Thelia/Core/Template/Loop/Content.php +++ b/core/lib/Thelia/Core/Template/Loop/Content.php @@ -66,7 +66,7 @@ class Content extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'random', 'given_id')) + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse', 'random', 'given_id')) ), 'alpha' ), @@ -155,7 +155,7 @@ class Content extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\ContentI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\ContentI18nTableMap::TITLE); break; case "manual": diff --git a/core/lib/Thelia/Core/Template/Loop/Feature.php b/core/lib/Thelia/Core/Template/Loop/Feature.php index 15ef6af99..cf8dcc563 100755 --- a/core/lib/Thelia/Core/Template/Loop/Feature.php +++ b/core/lib/Thelia/Core/Template/Loop/Feature.php @@ -65,7 +65,7 @@ class Feature extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse')) ), 'manual' ) @@ -124,7 +124,7 @@ class Feature extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\FeatureI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\FeatureI18nTableMap::TITLE); break; case "manual": diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php b/core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php index 2ef701cc9..838937558 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureAvailable.php @@ -59,7 +59,7 @@ class FeatureAvailable extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse')) ), 'manual' ) @@ -100,7 +100,7 @@ class FeatureAvailable extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\FeatureAvI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\FeatureAvI18nTableMap::TITLE); break; case "manual": diff --git a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php index 43f6df506..9988c500f 100755 --- a/core/lib/Thelia/Core/Template/Loop/FeatureValue.php +++ b/core/lib/Thelia/Core/Template/Loop/FeatureValue.php @@ -61,7 +61,7 @@ class FeatureValue extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual_reverse')) + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual_reverse')) ), 'manual' ) @@ -108,7 +108,7 @@ class FeatureValue extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\FeatureI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\FeatureI18nTableMap::TITLE); break; case "manual": diff --git a/core/lib/Thelia/Core/Template/Loop/Folder.php b/core/lib/Thelia/Core/Template/Loop/Folder.php index 7f4ee120d..c2f45682a 100755 --- a/core/lib/Thelia/Core/Template/Loop/Folder.php +++ b/core/lib/Thelia/Core/Template/Loop/Folder.php @@ -59,7 +59,7 @@ class Folder extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', 'manual', 'manual-reverse', 'random')) + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) ), 'manual' ), @@ -113,7 +113,7 @@ class Folder extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\FolderI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\FolderI18nTableMap::TITLE); break; case "manual-reverse": diff --git a/core/lib/Thelia/Core/Template/Loop/Product.php b/core/lib/Thelia/Core/Template/Loop/Product.php index 1d93515cb..88f33c3b3 100755 --- a/core/lib/Thelia/Core/Template/Loop/Product.php +++ b/core/lib/Thelia/Core/Template/Loop/Product.php @@ -79,7 +79,7 @@ class Product extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha_reverse', /*'min_price', 'max_price',*/ 'manual', 'manual_reverse', 'ref', /*'promo', 'new',*/ 'random', 'given_id')) + new Type\EnumListType(array('alpha', 'alpha-reverse', /*'min_price', 'max_price',*/ 'manual', 'manual_reverse', 'ref', /*'promo', 'new',*/ 'random', 'given_id')) ), 'alpha' ), @@ -256,7 +256,7 @@ class Product extends BaseLoop case "alpha": $search->addAscendingOrderByColumn(\Thelia\Model\Map\ProductI18nTableMap::TITLE); break; - case "alpha_reverse": + case "alpha-reverse": $search->addDescendingOrderByColumn(\Thelia\Model\Map\ProductI18nTableMap::TITLE); break; /*case "min_price": diff --git a/core/lib/Thelia/Tests/Command/CacheClearTest.php b/core/lib/Thelia/Tests/Command/CacheClearTest.php index 8d0fbb925..4e05e5611 100755 --- a/core/lib/Thelia/Tests/Command/CacheClearTest.php +++ b/core/lib/Thelia/Tests/Command/CacheClearTest.php @@ -44,24 +44,26 @@ class CacheClearTest extends \PHPUnit_Framework_TestCase public function testCacheClear() { - $application = new Application($this->getKernel()); + // Fails on windows - do not execute this test on windows + if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + $application = new Application($this->getKernel()); - $cacheClear = new CacheClear(); - $cacheClear->setContainer($this->getContainer()); + $cacheClear = new CacheClear(); + $cacheClear->setContainer($this->getContainer()); - $application->add($cacheClear); + $application->add($cacheClear); - $command = $application->find("cache:clear"); - $commandTester = new CommandTester($command); - $commandTester->execute(array( - "command" => $command->getName(), - "--env" => "test" - )); + $command = $application->find("cache:clear"); + $commandTester = new CommandTester($command); + $commandTester->execute(array( + "command" => $command->getName(), + "--env" => "test" + )); - $fs = new Filesystem(); - - $this->assertFalse($fs->exists($this->cache_dir)); + $fs = new Filesystem(); + $this->assertFalse($fs->exists($this->cache_dir)); + } } /** @@ -69,22 +71,28 @@ class CacheClearTest extends \PHPUnit_Framework_TestCase */ public function testCacheClearWithoutWritePermission() { - $fs = new Filesystem(); - $fs->chmod($this->cache_dir,0100); + // Fails on windows - mock this test on windows + if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + $fs = new Filesystem(); + $fs->chmod($this->cache_dir,0100); - $application = new Application($this->getKernel()); + $application = new Application($this->getKernel()); - $cacheClear = new CacheClear(); - $cacheClear->setContainer($this->getContainer()); + $cacheClear = new CacheClear(); + $cacheClear->setContainer($this->getContainer()); - $application->add($cacheClear); + $application->add($cacheClear); - $command = $application->find("cache:clear"); - $commandTester = new CommandTester($command); - $commandTester->execute(array( - "command" => $command->getName(), - "--env" => "test" - )); + $command = $application->find("cache:clear"); + $commandTester = new CommandTester($command); + $commandTester->execute(array( + "command" => $command->getName(), + "--env" => "test" + )); + } + else { + throw new \RuntimeException(""); + } } public function getKernel() diff --git a/install/INSTALL-TODO.txt b/install/INSTALL-TODO.txt index e1ffb2202..ba319c228 100644 --- a/install/INSTALL-TODO.txt +++ b/install/INSTALL-TODO.txt @@ -19,3 +19,5 @@ Variables Config à initialiser: - password.length : longueur du mot de passe, défaut 4 - form.secret : token csrf - verifyStock : vérification du stock lors du paiement/ajout au panier. Defaut 1 +- default_images_quality_percent : qualité par défaut des images générées (0 à 100, défaut: 75). +- original_image_delivery_mode : mode de mise à disposition des images originales (full resolution) dans le cache. 'symlink' pour un lien symbolique, 'copy' pour une copie \ No newline at end of file diff --git a/install/insert.sql b/install/insert.sql index ab349e09a..1263f47df 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -7,6 +7,11 @@ INSERT INTO `lang`(`id`,`title`,`code`,`locale`,`url`,`by_default`,`position`,`c INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES ('session_config.default', '1', 1, 1, NOW(), NOW()), ('verifyStock', '1', 1, 0, NOW(), NOW()); +('imagine_driver', 'gd', 1, 0, NOW(), NOW()); +('default_images_quality_percent', '75', 1, 0, NOW(), NOW()); +('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()); + + INSERT INTO `module` (`code`, `type`, `activate`, `position`, `created_at`, `updated_at`) VALUES ('test', '1', '1', '1', NOW(), NOW()); diff --git a/local/config/database.yml.sample b/local/config/database.yml.sample deleted file mode 100755 index 3bb829965..000000000 --- a/local/config/database.yml.sample +++ /dev/null @@ -1,6 +0,0 @@ -database: - connection: - driver: %DRIVER% - user: %USERNAME% - password: %PASSWORD% - dsn: %DSN% From a56e05b36b9514f21ad8c59f36e9c0ab5b71c9a7 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 11:46:46 +0200 Subject: [PATCH 05/11] Added image action and loop --- .gitignore | 1 + core/lib/Thelia/Action/Image.php | 417 ++++ core/lib/Thelia/Core/Event/ImageEvent.php | 237 ++ core/lib/Thelia/Core/Template/Loop/Image.php | 263 +++ core/lib/Thelia/Exception/ImageException.php | 28 + core/lib/Thelia/Model/Base/ProductImage.php | 1990 +++++++++++++++++ .../Thelia/Model/Base/ProductImageI18n.php | 1439 ++++++++++++ .../Model/Base/ProductImageI18nQuery.php | 607 +++++ .../Thelia/Model/Base/ProductImageQuery.php | 846 +++++++ .../Model/Map/ProductImageI18nTableMap.php | 497 ++++ .../Thelia/Model/Map/ProductImageTableMap.php | 475 ++++ core/lib/Thelia/Model/ProductImage.php | 10 + core/lib/Thelia/Model/ProductImageI18n.php | 10 + .../Thelia/Model/ProductImageI18nQuery.php | 21 + core/lib/Thelia/Model/ProductImageQuery.php | 21 + core/lib/Thelia/Tests/Action/ImageTest.php | 318 +++ .../assets/images/sources/test-image-1.png | Bin 0 -> 13736 bytes .../assets/images/sources/test-image-2.png | Bin 0 -> 13736 bytes .../assets/images/sources/test-image-3.png | Bin 0 -> 11126 bytes .../assets/images/sources/test-image-4.png | Bin 0 -> 11126 bytes .../assets/images/sources/test-image-5.png | Bin 0 -> 11052 bytes .../assets/images/sources/test-image-6.png | Bin 0 -> 11126 bytes .../assets/images/sources/test-image-7.png | Bin 0 -> 11052 bytes .../assets/images/sources/test-image-8.png | Bin 0 -> 11126 bytes .../assets/images/sources/test-image-9.png | Bin 0 -> 11126 bytes 25 files changed, 7180 insertions(+) create mode 100644 core/lib/Thelia/Action/Image.php create mode 100644 core/lib/Thelia/Core/Event/ImageEvent.php create mode 100644 core/lib/Thelia/Core/Template/Loop/Image.php create mode 100644 core/lib/Thelia/Exception/ImageException.php create mode 100644 core/lib/Thelia/Model/Base/ProductImage.php create mode 100644 core/lib/Thelia/Model/Base/ProductImageI18n.php create mode 100644 core/lib/Thelia/Model/Base/ProductImageI18nQuery.php create mode 100644 core/lib/Thelia/Model/Base/ProductImageQuery.php create mode 100644 core/lib/Thelia/Model/Map/ProductImageI18nTableMap.php create mode 100644 core/lib/Thelia/Model/Map/ProductImageTableMap.php create mode 100644 core/lib/Thelia/Model/ProductImage.php create mode 100644 core/lib/Thelia/Model/ProductImageI18n.php create mode 100644 core/lib/Thelia/Model/ProductImageI18nQuery.php create mode 100644 core/lib/Thelia/Model/ProductImageQuery.php create mode 100644 core/lib/Thelia/Tests/Action/ImageTest.php create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-1.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-2.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-3.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-4.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-5.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-6.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-7.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-8.png create mode 100644 core/lib/Thelia/Tests/Action/assets/images/sources/test-image-9.png diff --git a/.gitignore b/.gitignore index cd8f8ffa3..16709f59f 100755 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ coverage .settings/ local/cache/* web/assets/* +web/cache/* web/.htaccess phpdoc*.log php-cs diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php new file mode 100644 index 000000000..86003064b --- /dev/null +++ b/core/lib/Thelia/Action/Image.php @@ -0,0 +1,417 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Action; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +use Thelia\Core\Event\ActionEvent; +use Thelia\Core\Event\ImageEvent; +use Thelia\Model\ConfigQuery; +use Thelia\Tools\URL; + +use Imagine\Image\ImagineInterface; +use Imagine\Image\ImageInterface; +use Imagine\Image\Box; +use Imagine\Image\Color; +use Imagine\Image\Point; +use Thelia\Exception\ImageException; +use Thelia\Log\Tlog; +use Thelia\Core\Event\TheliaEvents; + +/** + * + * Image management actions + * + * @package Thelia\Action + * @author Franck Allimant + * + */ +class Image extends BaseAction implements EventSubscriberInterface +{ + // Resize mode constants + const EXACT_RATIO_WITH_BORDERS = 1; + const EXACT_RATIO_WITH_CROP = 2; + const KEEP_IMAGE_RATIO = 3; + + /** + * Process image and write the result in the image cache. + * + * If the image already exists in cache, the cache file is immediately returned, without any processing + * If the original (full resolution) image is required, create either a symbolic link with the + * original image in the cache dir, or copy it in the cache dir. + * + * This method updates the cache_file_path and file_url attributes of the event + * + * @param ImageEvent $event + * @throws \InvalidArgumentException, ImageException + */ + public function processImage(ImageEvent $event) + { + + $subdir = $event->getCacheSubdirectory(); + $source_file = $event->getSourceFilepath(); + + if (null == $subdir || null == $source_file) { + throw new \InvalidArgumentException("Cache sub-directory and source file path cannot be null"); + } + + // echo basename($source_file).": "; + + // Find cached file path + $cacheFilePath = $this->getCacheFilePath($subdir, $source_file, $event); + + if (! file_exists($cacheFilePath)) { + + // If the original image is required, either create a copy of make a symbolic link, + // depending of the current configuration + if ($event->isOriginalImage()) { + + $mode = ConfigQuery::read('original_image_delivery_mode', 'symlink'); + + if ($mode == 'symlink') { + if (false == @symlink($source_file, $cacheFilePath)) { + $error_message = sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir); + Tlog::getInstance()->addError($error_message); + throw new ImageException($error_message); + } + } + else {// mode = 'copy' + if (false == @copy($source_file, $cacheFilePath)) { + $error_message = sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir); + Tlog::getInstance()->addError($error_message); + throw new ImageException($error_message); + } + } + } + else { + + // We have to process the image. + $imagine = $this->createImagineInstance(); + + $image = $imagine->open($source_file); + + if ($image) { + + $background_color = $event->getBackgroundColor(); + + if ($background_color != null) { + $bg_color = new Color($background_color); + } + else + $bg_color = null; + + // Apply resize + $image = $this->applyResize($imagine, $image, $event->getWidth(), $event->getHeight(), $event->getResizeMode(), $bg_color); + + // Rotate if required + $rotation = intval($event->getRotation()); + + if ($rotation != 0) + $image->rotate($rotation, $bg_color); + + // Flip + // Process each effects + foreach ($event->getEffects() as $effect) { + + $effect = trim(strtolower($effect)); + + $params = explode(':', $effect); + + switch ($params[0]) { + + case 'greyscale': + case 'grayscale': + $image->effects()->grayscale(); + break; + + case 'negative': + $image->effects()->negative(); + break; + + case 'horizontal_flip': + case 'hflip': + $image->flipHorizontally(); + break; + + case 'vertical_flip': + case 'vflip': + $image-> flipVertically(); + break; + + case 'gamma': + // Syntax: gamma:value. Exemple: gamma:0.7 + if (isset($params[1])) { + $gamma = floatval($params[1]); + + $image->effects()->gamma($gamma); + } + break; + + case 'colorize': + // Syntax: colorize:couleur. Exemple: colorize:#ff00cc + if (isset($params[1])) { + $the_color = new Color($params[1]); + + $image->effects()->colorize($the_color); + } + break; + } + } + + $quality = $event->getQuality(); + + if (is_null($quality)) $quality = ConfigQuery::read('default_image_quality_percent', 75); + + $image->save( + $cacheFilePath, + array('quality' => $quality) + ); + } + } + } + else { + throw new ImageException(sprintf("Source file %s cannot be opened.", basename($source_file))); + } + + // Compute the image URL + $image_url = $this->getCacheFileURL($subdir, basename($cacheFilePath)); + + // Update the event with file path and file URL + $event->setCacheFilepath($cacheFilePath); + + $event->setFileUrl(URL::absoluteUrl($image_url)); + } + + /** + * Process image resizing, with borders or cropping. If $dest_width and $dest_height + * are both null, no resize is performed. + * + * @param ImagineInterface $imagine the Imagine instance + * @param ImageInterface $image the image to process + * @param int $dest_width the required width + * @param int $dest_height the required height + * @param int $resize_mode the resize mode (crop / bands / keep image ratio)p + * @param string $bg_color the bg_color used for bands + * @return ImageInterface the resized image. + */ + protected function applyResize(ImagineInterface $imagine, ImageInterface $image, $dest_width, $dest_height, $resize_mode, $bg_color) + { + if (! (is_null($dest_width) && is_null($dest_height))) { + + $width_orig = $image->getSize()->getWidth(); + $height_orig = $image->getSize()->getHeight(); + + if (is_null($dest_width)) + $dest_width = $width_orig; + + if (is_null($dest_height)) + $dest_height = $height_orig; + + if (is_null($resize_mode)) + $resize_mode = self::KEEP_IMAGE_RATIO; + + $width_diff = $dest_width / $width_orig; + $height_diff = $dest_height / $height_orig; + + $delta_x = $delta_y = $border_width = $border_height = 0; + + if ($width_diff > 1 AND $height_diff > 1) { + + $next_width = $width_orig; + $next_height = $height_orig; + + $dest_width = ($resize_mode == self::EXACT_RATIO_WITH_BORDERS ? $dest_width : $next_width); + $dest_height = ($resize_mode == self::EXACT_RATIO_WITH_BORDERS ? $dest_height : $next_height); + } + else if ($width_diff > $height_diff) { + // Image height > image width + + $next_height = $dest_height; + $next_width = intval(($width_orig * $next_height) / $height_orig); + + if ($resize_mode == self::EXACT_RATIO_WITH_CROP) { + $next_width = $dest_width; + $next_height = intval($height_orig * $dest_width / $width_orig); + $delta_y = ($next_height - $dest_height) / 2; + } + else if ($resize_mode != self::EXACT_RATIO_WITH_BORDERS) { + $dest_width = $next_width; + } + } + else { + // Image width > image height + $next_width = $dest_width; + $next_height = intval($height_orig * $dest_width / $width_orig); + + if ($resize_mode == self::EXACT_RATIO_WITH_CROP) { + $next_height = $dest_height; + $next_width = intval(($width_orig * $next_height) / $height_orig); + $delta_x = ($next_width - $dest_width) / 2; + } + else if ($resize_mode != self::EXACT_RATIO_WITH_BORDERS) { + $dest_height = $next_height; + } + } + + $image->resize(new Box($next_width, $next_height)); + + // echo "w=$dest_width, h=$dest_height, nw=$next_width, nh=$next_height, dx=$delta_x, dy=$delta_y, bw=$border_width, bh=$border_height\n"; + + if ($resize_mode == self::EXACT_RATIO_WITH_BORDERS) { + + $border_width = intval(($dest_width - $next_width) / 2); + $border_height = intval(($dest_height - $next_height) / 2); + + $canvas = new Box($dest_width, $dest_height); + + return $imagine->create($canvas, $bg_color) + ->paste($image, new Point($border_width, $border_height)); + } + + else if ($resize_mode == self::EXACT_RATIO_WITH_CROP) { + $image->crop( + new Point($delta_x, $delta_y), + new Box($dest_width, $dest_height) + ); + } + } + + return $image; + } + + + /** + * Return the absolute URL to the cached image + * + * @param string $subdir the subdirectory related to cache base + * @param string $filename the safe filename, as returned by getCacheFilePath() + * @return string the absolute URL to the cached image + */ + protected function getCacheFileURL($subdir, $safe_filename) + { + $path = $this->getCachePathFromWebRoot($subdir); + + return URL::absoluteUrl(sprintf("%s/%s", $path, $safe_filename)); + } + + /** + * Return the full path of the cached file + * + * @param string $subdir the subdirectory related to cache base + * @param string $filename the filename + * @return string the cache directory path relative to Web Root + */ + protected function getCacheFilePath($subdir, $filename, ImageEvent $event) + { + $path = $this->getCachePath($subdir); + + $safe_filename = preg_replace("[^:alnum:\-\._]", "-", strtolower(basename($filename))); + + // Keep original safe name if no tranformations are applied + if ($event->isOriginalImage()) + return sprintf("%s/%s", $path, $safe_filename); + else + return sprintf("%s/%s-%s", $path, $event->getSignature(), $safe_filename); + } + + /** + * Return the cache directory path relative to Web Root + * + * @param string $subdir the subdirectory related to cache base + * @return string the cache directory path relative to Web Root + */ + protected function getCachePathFromWebRoot($subdir) + { + $safe_subdir = basename($subdir); + + $cache_dir_from_web_root = ConfigQuery::read('image_cache_dir_from_web_root', 'cache'); + + $path = sprintf("%s/%s", $cache_dir_from_web_root, $safe_subdir); + + return $path; + } + + /** + * Return the absolute cache directory path + * + * @param string $subdir the subdirectory related to cache base + * @throws \RuntimeException if cache directory cannot be created + * @return string the absolute cache directory path + */ + protected function getCachePath($subdir) + { + $cache_base = $this->getCachePathFromWebRoot($subdir); + + $web_root = rtrim(THELIA_WEB_DIR, '/'); + + $path = sprintf("%s/%s", $web_root, $cache_base); + + // Create directory (recursively) if it does not exists. + if (!is_dir($path)) { + if (!@mkdir($path, 0777, true)) { + $error_message = sprintf("Failed to create %s/%s image cache directory", $cache_base); + Tlog::getInstance()->addError($error_message); + + throw new ImageException($error_message); + } + } + + return $path; + } + + /** + * Create a new Imagine object using current driver configuration + * + * @return \Imagine\ImagineInterface + */ + protected function createImagineInstance() + { + $driver = ConfigQuery::read("imagine_driver", "gd"); + + switch ($driver) { + case 'imagik': + $image = new \Imagine\Imagick\Imagine(); + break; + + case 'gmagick': + $image = new \Imagine\Gmagick\Imagine(); + break; + + case 'gd': + default: + $image = new \Imagine\Gd\Imagine(); + } + + return $image; + } + + public static function getSubscribedEvents() + { + return array( + TheliaEvents::IMAGE_PROCESS => array( + "processImage", 128 + ), + ); + } +} diff --git a/core/lib/Thelia/Core/Event/ImageEvent.php b/core/lib/Thelia/Core/Event/ImageEvent.php new file mode 100644 index 000000000..bfca35fb9 --- /dev/null +++ b/core/lib/Thelia/Core/Event/ImageEvent.php @@ -0,0 +1,237 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Event; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Model\Cart; + +class ImageEvent extends ActionEvent +{ + /** + * @var string The complete file name (with path) of the source image + */ + protected $source_filepath = null; + /** + * @var string The target subdirectory in the image cache + */ + protected $cache_subdirectory = null; + + /** + * @var string The absolute URL of the cached image (in the web space) + */ + protected $file_url = null; + + /** + * @var string The absolute path of the cached image file + */ + protected $cache_filepath = null; + + /** + * @var string The image category (i.e. the subdirectory in image cache) + */ + protected $category = null; + + /** + * @var integer the required image width + */ + protected $width = null; + + /** + * @var int the required image height + */ + protected $height = null; + + /** + * @var string the resize mode, either crop, bands, none + */ + protected $resize_mode = null; + + /** + * @var string the background color in RGB format (eg. #ff8000) + */ + protected $background_color = null; + + /** + * @var array a list of effects (grayscale, negative, mirror...), applied in the specified order. + */ + protected $effects = array(); + + /** + * @var int the rotation angle in degrees, none if zero or null + */ + protected $rotation = null; + + /** + * @var int the quality of the result image, from 0 (!) to 100 + */ + protected $quality = null; + + /** + * @return boolean true if the required image is the original image + */ + public function isOriginalImage() { + return + empty($this->width) + && empty($this->height) + && empty($this->resize_mode) + && empty($this->background_color) + && empty($this->effects) + && empty($this->rotation) + ; + } + + /** + * @return string a hash identifiying the processing options + */ + public function getSignature() { + return md5( + $this->width + . $this->height + . $this->resize_mode + . $this->background_color + . implode(',', $this->effects) + . $this->rotation + ); + } + + public function getCategory() + { + return $this->category; + } + + public function setCategory($category) + { + $this->category = $category; + } + + public function getWidth() + { + return $this->width; + } + + public function setWidth($width) + { + $this->width = $width; + } + + public function getHeight() + { + return $this->height; + } + + public function setHeight($height) + { + $this->height = $height; + } + + public function getResizeMode() + { + return $this->resize_mode; + } + + public function setResizeMode($resize_mode) + { + $this->resize_mode = $resize_mode; + } + + public function getBackgroundColor() + { + return $this->background_color; + } + + public function setBackgroundColor($background_color) + { + $this->background_color = $background_color; + } + + public function getEffects() + { + return $this->effects; + } + + public function setEffects(array $effects) + { + $this->effects = $effects; + } + + public function getRotation() + { + return $this->rotation; + } + + public function setRotation($rotation) + { + $this->rotation = $rotation; + } + + public function getFileUrl() + { + return $this->file_url; + } + + public function setFileUrl($file_url) + { + $this->file_url = $file_url; + } + + public function getCacheFilepath() + { + return $this->cache_filepath; + } + + public function setCacheFilepath($cache_filepath) + { + $this->cache_filepath = $cache_filepath; + } + + public function getSourceFilepath() + { + return $this->source_filepath; + } + + public function setSourceFilepath($source_filepath) + { + $this->source_filepath = $source_filepath; + } + + public function getCacheSubdirectory() + { + return $this->cache_subdirectory; + } + + public function setCacheSubdirectory($cache_subdirectory) + { + $this->cache_subdirectory = $cache_subdirectory; + } + + public function getQuality() + { + return $this->quality; + } + + public function setQuality($quality) + { + $this->quality = $quality; + } + +} diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php new file mode 100644 index 000000000..4414e0e4e --- /dev/null +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -0,0 +1,263 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Core\Template\Loop; +use Thelia\Core\Template\Element\BaseLoop; +use Thelia\Core\Template\Loop\Argument\Argument; +use Thelia\Core\Event\ImageEvent; +use Thelia\Model\CategoryImageQuery; +use Thelia\Model\ProductImageQuery; +use Thelia\Core\Event\TheliaEvents; + +/** + * The image loop + * + * @author Franck Allimant + */ +class Image extends BaseLoop +{ + /** + * @var array Possible image sources + */ + protected $possible_sources = array('category', 'product', 'folder', 'content'); + + /** + * Dynamically create the search query, and set the proper filter and order + * + * @return ModelCriteria the propel Query object + */ + protected function getSearchQuery() { + + $search = null; + + foreach($this->possible_sources as $source) { + + $argValue = intval($this->getArgValue($source)); + + if ($argValue > 0) { + + $object = ucfirst($source); + + $queryClass = sprintf("%sImageQuery", $object); + $filterMethod = sprintf("filterBy%s", $object); + $mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object); + + // xxxImageQuery::create() + $method = new \ReflectionMethod($queryClass, 'create'); + $search = $reflectionMethod->invoke(null); // Static ! + + // $query->filterByXXX($id) + $method = new \ReflectionMethod($queryClass, $filterMethod); + $method->invoke($search, $argValue); + + $map = new \ReflectionClass($mapClass); + $title_map = $map->getConstant('TITLE'); + + $orders = $this->getOrder(); + + // Results ordering + foreach ($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn($title_map); + break; + case "alpha-reverse": + $search->addDescendingOrderByColumn($title_map); + break; + case "manual-reverse": + $search->orderByPosition(Criteria::DESC); + break; + case "manual": + $search->orderByPosition(Criteria::ASC); + break; + case "random": + $search->clearOrderByColumns(); + $search->addAscendingOrderByColumn('RAND()'); + break(2); + break; + } + } + + break; + } + } + + if ($search == null) + throw new \InvalidArgumentException(sprintf("Unable to find image source. Valid sources are %s", implode(',', $this->possible_sources))); + + return $search; + } + + /** + * @param unknown $pagination + */ + public function exec($pagination) + { + // Select the proper query to use + $search = $this->getSearchQuery(); + + $id = $this->getId(); + + if (! is_null($id)) { + $search->filterById($id, Criteria::IN); + } + + $exclude = $this->getExclude(); + if (!is_null($exclude)) + $search->filterById($exclude, Criteria::NOT_IN); + + // Create image processing event + $event = new ImageEvent($this->request); + + // Prepare tranformations + // Setup required transformations + $width = $this->getWidth(); + $height = $this->getHeight(); + $resize_mode = $this->getResizeMode(); + $rotation = $this->getRotation(); + $background_color = $this->getBackgroundColor(); + $quality = $this->getQuality(); + $effects = $this->getEffects(); + $effects = $this->getEffects(); + if (! is_null($effects)) { + $effects = explode(',', $effects); + } + + /** + * \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation. + * + * @todo : verify here if we want results for row without translations. + */ + + $search->joinWithI18n( + $this->request->getSession()->getLocale(), + (ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN + ); + + $results = $this->search($search, $pagination); + + $loopResult = new LoopResult(); + + foreach ($results as $result) { + + // Create image processing event + $event = new ImageEvent($this->request); + + // Setup required transformations + if (! is_null($width)) $event->setWidth($width); + if (! is_null($height)) $event->setHeigth($height); + if (! is_null($resize_mode)) $event->setResizeMode($resize_mode); + if (! is_null($rotation)) $event->setRotation($rotation); + if (! is_null($background_color)) $event->setBackgroundColor($background_color); + if (! is_null($quality)) $event->setQuality($quality); + if (! is_null($effects)) $event->setEffects($effects); + + // Dispatch image processing event + $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event); + + $loopResultRow = new LoopResultRow(); + + $loopResultRow + ->set("ID", $result->getId()) + ->set("IMAGE_URL", $event->getFileUrl()) + ->set("FILE_URL", $event-> + ; + + $loopResult->addRow($loopResultRow); + } + + return $loopResult; +/* +#PRODUIT : identifiant du produit associé (valué si le paramètre "produit" a été indiqué) +#PRODTITRE : titre du produit associé (valué si le paramètre "produit" a été indiqué) +#PRODREF : référence du produit associé (valué si le paramètre "produit" a été indiqué) +#RUBRIQUE : identifiant de la rubrique associée (valué si le paramètre "rubrique" a été indiqué) +#RUBTITRE : titre de la rubrique associée (valué si le paramètre "rubrique" a été indiqué) +#DOSSIER : identifiant du dossier associée (valué si le paramètre "dossier" a été indiqué) +#DOSTITRE : titre du dossier associée (valué si le paramètre "dossier" a été indiqué) +#CONTENU : identifiant du contenu associée (valué si le paramètre "contenu" a été indiqué) +#CONTTITRE : titre du contenu associée (valué si le paramètre "contenu" a été indiqué) +#IMAGE : URL de l'image transformée (redimensionnée, inversée, etc. suivant les paramètres d'entrée de la boucle). +#FICHIER : URL de l'image originale +#ID : identifiant de l'image +#TITRE : titre de l'image +#CHAPO : description courte de l'image +#DESCRIPTION : description longue de l'image +#COMPT : compteur débutant à 1. Utile pour l'utilisation de Javascript. + */ + } + + /** + * @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection + */ + protected function getArgDefinitions() + { + $collection = new ArgumentCollection( + + Argument::createIntListTypeArgument('id'), + Argument::createIntListTypeArgument('exclude'), + new Argument( + 'order', + new TypeCollection( + new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) + ), + 'manual' + ), + + Argument::createIntTypeArgument('width'), + Argument::createIntTypeArgument('height'), + Argument::createIntTypeArgument('rotation', 0), + Argument::createAnyTypeArgument('background_color'), + Argument::createIntTypeArgument('quality'), + new Argument( + 'resize_mode', + new TypeCollection( + new Type\EnumListType(array('crop', 'borders', 'none')) + ), + 'none' + ), + Argument::createAnyTypeArgument('effects'), + + Argument::createIntTypeArgument('category'), + Argument::createIntTypeArgument('product'), + Argument::createIntTypeArgument('folder'), + Argument::createIntTypeArgument('content'), + + new Argument( + 'source', + new TypeCollection( + new Type\EnumListType($this->possible_sources) + ) + ), + + Argument::createIntListTypeArgument('lang') + ); + + // Add possible image sources + foreach($possible_sources as $source) { + $collection->addArgument(Argument::createIntTypeArgument($source)) + } + + return $collection; + } +} \ No newline at end of file diff --git a/core/lib/Thelia/Exception/ImageException.php b/core/lib/Thelia/Exception/ImageException.php new file mode 100644 index 000000000..77d2a8ba5 --- /dev/null +++ b/core/lib/Thelia/Exception/ImageException.php @@ -0,0 +1,28 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Exception; + +class ImageException extends \RuntimeException +{ +} diff --git a/core/lib/Thelia/Model/Base/ProductImage.php b/core/lib/Thelia/Model/Base/ProductImage.php new file mode 100644 index 000000000..0b4030ccb --- /dev/null +++ b/core/lib/Thelia/Model/Base/ProductImage.php @@ -0,0 +1,1990 @@ +modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another ProductImage instance. If + * obj is an instance of ProductImage, delegates to + * equals(ProductImage). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return isset($this->virtualColumns[$name]); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return ProductImage The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return ProductImage The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [product_id] column value. + * + * @return int + */ + public function getProductId() + { + + return $this->product_id; + } + + /** + * Get the [file] column value. + * + * @return string + */ + public function getFile() + { + + return $this->file; + } + + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + + /** + * Get the [optionally formatted] temporal [created_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getCreatedAt($format = NULL) + { + if ($format === null) { + return $this->created_at; + } else { + return $this->created_at !== null ? $this->created_at->format($format) : null; + } + } + + /** + * Get the [optionally formatted] temporal [updated_at] column value. + * + * + * @param string $format The date/time format string (either date()-style or strftime()-style). + * If format is NULL, then the raw \DateTime object will be returned. + * + * @return mixed Formatted date/time value as string or \DateTime object (if format is NULL), NULL if column is NULL, and 0 if column value is 0000-00-00 00:00:00 + * + * @throws PropelException - if unable to parse/validate the date/time value. + */ + public function getUpdatedAt($format = NULL) + { + if ($format === null) { + return $this->updated_at; + } else { + return $this->updated_at !== null ? $this->updated_at->format($format) : null; + } + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = ProductImageTableMap::ID; + } + + + return $this; + } // setId() + + /** + * Set the value of [product_id] column. + * + * @param int $v new value + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function setProductId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->product_id !== $v) { + $this->product_id = $v; + $this->modifiedColumns[] = ProductImageTableMap::PRODUCT_ID; + } + + if ($this->aProduct !== null && $this->aProduct->getId() !== $v) { + $this->aProduct = null; + } + + + return $this; + } // setProductId() + + /** + * Set the value of [file] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function setFile($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->file !== $v) { + $this->file = $v; + $this->modifiedColumns[] = ProductImageTableMap::FILE; + } + + + return $this; + } // setFile() + + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = ProductImageTableMap::POSITION; + } + + + return $this; + } // setPosition() + + /** + * Sets the value of [created_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function setCreatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->created_at !== null || $dt !== null) { + if ($dt !== $this->created_at) { + $this->created_at = $dt; + $this->modifiedColumns[] = ProductImageTableMap::CREATED_AT; + } + } // if either are not null + + + return $this; + } // setCreatedAt() + + /** + * Sets the value of [updated_at] column to a normalized version of the date/time value specified. + * + * @param mixed $v string, integer (timestamp), or \DateTime value. + * Empty strings are treated as NULL. + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function setUpdatedAt($v) + { + $dt = PropelDateTime::newInstance($v, null, '\DateTime'); + if ($this->updated_at !== null || $dt !== null) { + if ($dt !== $this->updated_at) { + $this->updated_at = $dt; + $this->modifiedColumns[] = ProductImageTableMap::UPDATED_AT; + } + } // if either are not null + + + return $this; + } // setUpdatedAt() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ProductImageTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProductImageTableMap::translateFieldName('ProductId', TableMap::TYPE_PHPNAME, $indexType)]; + $this->product_id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProductImageTableMap::translateFieldName('File', TableMap::TYPE_PHPNAME, $indexType)]; + $this->file = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProductImageTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductImageTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductImageTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + if ($col === '0000-00-00 00:00:00') { + $col = null; + } + $this->updated_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 6; // 6 = ProductImageTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\ProductImage object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aProduct !== null && $this->product_id !== $this->aProduct->getId()) { + $this->aProduct = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductImageTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildProductImageQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aProduct = null; + $this->collProductImageI18ns = null; + + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see ProductImage::setDeleted() + * @see ProductImage::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildProductImageQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + // timestampable behavior + if (!$this->isColumnModified(ProductImageTableMap::CREATED_AT)) { + $this->setCreatedAt(time()); + } + if (!$this->isColumnModified(ProductImageTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } else { + $ret = $ret && $this->preUpdate($con); + // timestampable behavior + if ($this->isModified() && !$this->isColumnModified(ProductImageTableMap::UPDATED_AT)) { + $this->setUpdatedAt(time()); + } + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + ProductImageTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aProduct !== null) { + if ($this->aProduct->isModified() || $this->aProduct->isNew()) { + $affectedRows += $this->aProduct->save($con); + } + $this->setProduct($this->aProduct); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + if ($this->productImageI18nsScheduledForDeletion !== null) { + if (!$this->productImageI18nsScheduledForDeletion->isEmpty()) { + \Thelia\Model\ProductImageI18nQuery::create() + ->filterByPrimaryKeys($this->productImageI18nsScheduledForDeletion->getPrimaryKeys(false)) + ->delete($con); + $this->productImageI18nsScheduledForDeletion = null; + } + } + + if ($this->collProductImageI18ns !== null) { + foreach ($this->collProductImageI18ns as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + $this->modifiedColumns[] = ProductImageTableMap::ID; + if (null !== $this->id) { + throw new PropelException('Cannot insert a value for auto-increment primary key (' . ProductImageTableMap::ID . ')'); + } + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(ProductImageTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(ProductImageTableMap::PRODUCT_ID)) { + $modifiedColumns[':p' . $index++] = 'PRODUCT_ID'; + } + if ($this->isColumnModified(ProductImageTableMap::FILE)) { + $modifiedColumns[':p' . $index++] = 'FILE'; + } + if ($this->isColumnModified(ProductImageTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } + if ($this->isColumnModified(ProductImageTableMap::CREATED_AT)) { + $modifiedColumns[':p' . $index++] = 'CREATED_AT'; + } + if ($this->isColumnModified(ProductImageTableMap::UPDATED_AT)) { + $modifiedColumns[':p' . $index++] = 'UPDATED_AT'; + } + + $sql = sprintf( + 'INSERT INTO product_image (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'PRODUCT_ID': + $stmt->bindValue($identifier, $this->product_id, PDO::PARAM_INT); + break; + case 'FILE': + $stmt->bindValue($identifier, $this->file, PDO::PARAM_STR); + break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; + case 'CREATED_AT': + $stmt->bindValue($identifier, $this->created_at ? $this->created_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + case 'UPDATED_AT': + $stmt->bindValue($identifier, $this->updated_at ? $this->updated_at->format("Y-m-d H:i:s") : null, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + try { + $pk = $con->lastInsertId(); + } catch (Exception $e) { + throw new PropelException('Unable to get autoincrement id.', 0, $e); + } + $this->setId($pk); + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductImageTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getProductId(); + break; + case 2: + return $this->getFile(); + break; + case 3: + return $this->getPosition(); + break; + case 4: + return $this->getCreatedAt(); + break; + case 5: + return $this->getUpdatedAt(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['ProductImage'][$this->getPrimaryKey()])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['ProductImage'][$this->getPrimaryKey()] = true; + $keys = ProductImageTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getProductId(), + $keys[2] => $this->getFile(), + $keys[3] => $this->getPosition(), + $keys[4] => $this->getCreatedAt(), + $keys[5] => $this->getUpdatedAt(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aProduct) { + $result['Product'] = $this->aProduct->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + if (null !== $this->collProductImageI18ns) { + $result['ProductImageI18ns'] = $this->collProductImageI18ns->toArray(null, true, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductImageTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setProductId($value); + break; + case 2: + $this->setFile($value); + break; + case 3: + $this->setPosition($value); + break; + case 4: + $this->setCreatedAt($value); + break; + case 5: + $this->setUpdatedAt($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = ProductImageTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setProductId($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setFile($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setPosition($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setCreatedAt($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setUpdatedAt($arr[$keys[5]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProductImageTableMap::DATABASE_NAME); + + if ($this->isColumnModified(ProductImageTableMap::ID)) $criteria->add(ProductImageTableMap::ID, $this->id); + if ($this->isColumnModified(ProductImageTableMap::PRODUCT_ID)) $criteria->add(ProductImageTableMap::PRODUCT_ID, $this->product_id); + if ($this->isColumnModified(ProductImageTableMap::FILE)) $criteria->add(ProductImageTableMap::FILE, $this->file); + if ($this->isColumnModified(ProductImageTableMap::POSITION)) $criteria->add(ProductImageTableMap::POSITION, $this->position); + if ($this->isColumnModified(ProductImageTableMap::CREATED_AT)) $criteria->add(ProductImageTableMap::CREATED_AT, $this->created_at); + if ($this->isColumnModified(ProductImageTableMap::UPDATED_AT)) $criteria->add(ProductImageTableMap::UPDATED_AT, $this->updated_at); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ProductImageTableMap::DATABASE_NAME); + $criteria->add(ProductImageTableMap::ID, $this->id); + + return $criteria; + } + + /** + * Returns the primary key for this object (row). + * @return int + */ + public function getPrimaryKey() + { + return $this->getId(); + } + + /** + * Generic method to set the primary key (id column). + * + * @param int $key Primary key. + * @return void + */ + public function setPrimaryKey($key) + { + $this->setId($key); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return null === $this->getId(); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\ProductImage (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setProductId($this->getProductId()); + $copyObj->setFile($this->getFile()); + $copyObj->setPosition($this->getPosition()); + $copyObj->setCreatedAt($this->getCreatedAt()); + $copyObj->setUpdatedAt($this->getUpdatedAt()); + + if ($deepCopy) { + // important: temporarily setNew(false) because this affects the behavior of + // the getter/setter methods for fkey referrer objects. + $copyObj->setNew(false); + + foreach ($this->getProductImageI18ns() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addProductImageI18n($relObj->copy($deepCopy)); + } + } + + } // if ($deepCopy) + + if ($makeNew) { + $copyObj->setNew(true); + $copyObj->setId(NULL); // this is a auto-increment column, so set to default value + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\ProductImage Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildProduct object. + * + * @param ChildProduct $v + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + * @throws PropelException + */ + public function setProduct(ChildProduct $v = null) + { + if ($v === null) { + $this->setProductId(NULL); + } else { + $this->setProductId($v->getId()); + } + + $this->aProduct = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildProduct object, it will not be re-added. + if ($v !== null) { + $v->addProductImage($this); + } + + + return $this; + } + + + /** + * Get the associated ChildProduct object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildProduct The associated ChildProduct object. + * @throws PropelException + */ + public function getProduct(ConnectionInterface $con = null) + { + if ($this->aProduct === null && ($this->product_id !== null)) { + $this->aProduct = ChildProductQuery::create()->findPk($this->product_id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aProduct->addProductImages($this); + */ + } + + return $this->aProduct; + } + + + /** + * Initializes a collection based on the name of a relation. + * Avoids crafting an 'init[$relationName]s' method name + * that wouldn't work when StandardEnglishPluralizer is used. + * + * @param string $relationName The name of the relation to initialize + * @return void + */ + public function initRelation($relationName) + { + if ('ProductImageI18n' == $relationName) { + return $this->initProductImageI18ns(); + } + } + + /** + * Clears out the collProductImageI18ns collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addProductImageI18ns() + */ + public function clearProductImageI18ns() + { + $this->collProductImageI18ns = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collProductImageI18ns collection loaded partially. + */ + public function resetPartialProductImageI18ns($v = true) + { + $this->collProductImageI18nsPartial = $v; + } + + /** + * Initializes the collProductImageI18ns collection. + * + * By default this just sets the collProductImageI18ns collection to an empty array (like clearcollProductImageI18ns()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initProductImageI18ns($overrideExisting = true) + { + if (null !== $this->collProductImageI18ns && !$overrideExisting) { + return; + } + $this->collProductImageI18ns = new ObjectCollection(); + $this->collProductImageI18ns->setModel('\Thelia\Model\ProductImageI18n'); + } + + /** + * Gets an array of ChildProductImageI18n objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildProductImage is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return Collection|ChildProductImageI18n[] List of ChildProductImageI18n objects + * @throws PropelException + */ + public function getProductImageI18ns($criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collProductImageI18nsPartial && !$this->isNew(); + if (null === $this->collProductImageI18ns || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductImageI18ns) { + // return empty collection + $this->initProductImageI18ns(); + } else { + $collProductImageI18ns = ChildProductImageI18nQuery::create(null, $criteria) + ->filterByProductImage($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collProductImageI18nsPartial && count($collProductImageI18ns)) { + $this->initProductImageI18ns(false); + + foreach ($collProductImageI18ns as $obj) { + if (false == $this->collProductImageI18ns->contains($obj)) { + $this->collProductImageI18ns->append($obj); + } + } + + $this->collProductImageI18nsPartial = true; + } + + $collProductImageI18ns->getInternalIterator()->rewind(); + + return $collProductImageI18ns; + } + + if ($partial && $this->collProductImageI18ns) { + foreach ($this->collProductImageI18ns as $obj) { + if ($obj->isNew()) { + $collProductImageI18ns[] = $obj; + } + } + } + + $this->collProductImageI18ns = $collProductImageI18ns; + $this->collProductImageI18nsPartial = false; + } + } + + return $this->collProductImageI18ns; + } + + /** + * Sets a collection of ProductImageI18n objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $productImageI18ns A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return ChildProductImage The current object (for fluent API support) + */ + public function setProductImageI18ns(Collection $productImageI18ns, ConnectionInterface $con = null) + { + $productImageI18nsToDelete = $this->getProductImageI18ns(new Criteria(), $con)->diff($productImageI18ns); + + + //since at least one column in the foreign key is at the same time a PK + //we can not just set a PK to NULL in the lines below. We have to store + //a backup of all values, so we are able to manipulate these items based on the onDelete value later. + $this->productImageI18nsScheduledForDeletion = clone $productImageI18nsToDelete; + + foreach ($productImageI18nsToDelete as $productImageI18nRemoved) { + $productImageI18nRemoved->setProductImage(null); + } + + $this->collProductImageI18ns = null; + foreach ($productImageI18ns as $productImageI18n) { + $this->addProductImageI18n($productImageI18n); + } + + $this->collProductImageI18ns = $productImageI18ns; + $this->collProductImageI18nsPartial = false; + + return $this; + } + + /** + * Returns the number of related ProductImageI18n objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related ProductImageI18n objects. + * @throws PropelException + */ + public function countProductImageI18ns(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collProductImageI18nsPartial && !$this->isNew(); + if (null === $this->collProductImageI18ns || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collProductImageI18ns) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getProductImageI18ns()); + } + + $query = ChildProductImageI18nQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByProductImage($this) + ->count($con); + } + + return count($this->collProductImageI18ns); + } + + /** + * Method called to associate a ChildProductImageI18n object to this object + * through the ChildProductImageI18n foreign key attribute. + * + * @param ChildProductImageI18n $l ChildProductImageI18n + * @return \Thelia\Model\ProductImage The current object (for fluent API support) + */ + public function addProductImageI18n(ChildProductImageI18n $l) + { + if ($l && $locale = $l->getLocale()) { + $this->setLocale($locale); + $this->currentTranslations[$locale] = $l; + } + if ($this->collProductImageI18ns === null) { + $this->initProductImageI18ns(); + $this->collProductImageI18nsPartial = true; + } + + if (!in_array($l, $this->collProductImageI18ns->getArrayCopy(), true)) { // only add it if the **same** object is not already associated + $this->doAddProductImageI18n($l); + } + + return $this; + } + + /** + * @param ProductImageI18n $productImageI18n The productImageI18n object to add. + */ + protected function doAddProductImageI18n($productImageI18n) + { + $this->collProductImageI18ns[]= $productImageI18n; + $productImageI18n->setProductImage($this); + } + + /** + * @param ProductImageI18n $productImageI18n The productImageI18n object to remove. + * @return ChildProductImage The current object (for fluent API support) + */ + public function removeProductImageI18n($productImageI18n) + { + if ($this->getProductImageI18ns()->contains($productImageI18n)) { + $this->collProductImageI18ns->remove($this->collProductImageI18ns->search($productImageI18n)); + if (null === $this->productImageI18nsScheduledForDeletion) { + $this->productImageI18nsScheduledForDeletion = clone $this->collProductImageI18ns; + $this->productImageI18nsScheduledForDeletion->clear(); + } + $this->productImageI18nsScheduledForDeletion[]= clone $productImageI18n; + $productImageI18n->setProductImage(null); + } + + return $this; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->product_id = null; + $this->file = null; + $this->position = null; + $this->created_at = null; + $this->updated_at = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + if ($this->collProductImageI18ns) { + foreach ($this->collProductImageI18ns as $o) { + $o->clearAllReferences($deep); + } + } + } // if ($deep) + + // i18n behavior + $this->currentLocale = 'en_US'; + $this->currentTranslations = null; + + if ($this->collProductImageI18ns instanceof Collection) { + $this->collProductImageI18ns->clearIterator(); + } + $this->collProductImageI18ns = null; + $this->aProduct = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(ProductImageTableMap::DEFAULT_STRING_FORMAT); + } + + // timestampable behavior + + /** + * Mark the current object so that the update date doesn't get updated during next save + * + * @return ChildProductImage The current object (for fluent API support) + */ + public function keepUpdateDateUnchanged() + { + $this->modifiedColumns[] = ProductImageTableMap::UPDATED_AT; + + return $this; + } + + // i18n behavior + + /** + * Sets the locale for translations + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * + * @return ChildProductImage The current object (for fluent API support) + */ + public function setLocale($locale = 'en_US') + { + $this->currentLocale = $locale; + + return $this; + } + + /** + * Gets the locale for translations + * + * @return string $locale Locale to use for the translation, e.g. 'fr_FR' + */ + public function getLocale() + { + return $this->currentLocale; + } + + /** + * Returns the current translation for a given locale + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProductImageI18n */ + public function getTranslation($locale = 'en_US', ConnectionInterface $con = null) + { + if (!isset($this->currentTranslations[$locale])) { + if (null !== $this->collProductImageI18ns) { + foreach ($this->collProductImageI18ns as $translation) { + if ($translation->getLocale() == $locale) { + $this->currentTranslations[$locale] = $translation; + + return $translation; + } + } + } + if ($this->isNew()) { + $translation = new ChildProductImageI18n(); + $translation->setLocale($locale); + } else { + $translation = ChildProductImageI18nQuery::create() + ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) + ->findOneOrCreate($con); + $this->currentTranslations[$locale] = $translation; + } + $this->addProductImageI18n($translation); + } + + return $this->currentTranslations[$locale]; + } + + /** + * Remove the translation for a given locale + * + * @param string $locale Locale to use for the translation, e.g. 'fr_FR' + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProductImage The current object (for fluent API support) + */ + public function removeTranslation($locale = 'en_US', ConnectionInterface $con = null) + { + if (!$this->isNew()) { + ChildProductImageI18nQuery::create() + ->filterByPrimaryKey(array($this->getPrimaryKey(), $locale)) + ->delete($con); + } + if (isset($this->currentTranslations[$locale])) { + unset($this->currentTranslations[$locale]); + } + foreach ($this->collProductImageI18ns as $key => $translation) { + if ($translation->getLocale() == $locale) { + unset($this->collProductImageI18ns[$key]); + break; + } + } + + return $this; + } + + /** + * Returns the current translation + * + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProductImageI18n */ + public function getCurrentTranslation(ConnectionInterface $con = null) + { + return $this->getTranslation($this->getLocale(), $con); + } + + + /** + * Get the [title] column value. + * + * @return string + */ + public function getTitle() + { + return $this->getCurrentTranslation()->getTitle(); + } + + + /** + * Set the value of [title] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setTitle($v) + { $this->getCurrentTranslation()->setTitle($v); + + return $this; + } + + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + return $this->getCurrentTranslation()->getDescription(); + } + + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setDescription($v) + { $this->getCurrentTranslation()->setDescription($v); + + return $this; + } + + + /** + * Get the [chapo] column value. + * + * @return string + */ + public function getChapo() + { + return $this->getCurrentTranslation()->getChapo(); + } + + + /** + * Set the value of [chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setChapo($v) + { $this->getCurrentTranslation()->setChapo($v); + + return $this; + } + + + /** + * Get the [postscriptum] column value. + * + * @return string + */ + public function getPostscriptum() + { + return $this->getCurrentTranslation()->getPostscriptum(); + } + + + /** + * Set the value of [postscriptum] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setPostscriptum($v) + { $this->getCurrentTranslation()->setPostscriptum($v); + + return $this; + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/ProductImageI18n.php b/core/lib/Thelia/Model/Base/ProductImageI18n.php new file mode 100644 index 000000000..634f726a3 --- /dev/null +++ b/core/lib/Thelia/Model/Base/ProductImageI18n.php @@ -0,0 +1,1439 @@ +locale = 'en_US'; + } + + /** + * Initializes internal state of Thelia\Model\Base\ProductImageI18n object. + * @see applyDefaults() + */ + public function __construct() + { + $this->applyDefaultValues(); + } + + /** + * Returns whether the object has been modified. + * + * @return boolean True if the object has been modified. + */ + public function isModified() + { + return !empty($this->modifiedColumns); + } + + /** + * Has specified column been modified? + * + * @param string $col column fully qualified name (TableMap::TYPE_COLNAME), e.g. Book::AUTHOR_ID + * @return boolean True if $col has been modified. + */ + public function isColumnModified($col) + { + return in_array($col, $this->modifiedColumns); + } + + /** + * Get the columns that have been modified in this object. + * @return array A unique list of the modified column names for this object. + */ + public function getModifiedColumns() + { + return array_unique($this->modifiedColumns); + } + + /** + * Returns whether the object has ever been saved. This will + * be false, if the object was retrieved from storage or was created + * and then saved. + * + * @return true, if the object has never been persisted. + */ + public function isNew() + { + return $this->new; + } + + /** + * Setter for the isNew attribute. This method will be called + * by Propel-generated children and objects. + * + * @param boolean $b the state of the object. + */ + public function setNew($b) + { + $this->new = (Boolean) $b; + } + + /** + * Whether this object has been deleted. + * @return boolean The deleted state of this object. + */ + public function isDeleted() + { + return $this->deleted; + } + + /** + * Specify whether this object has been deleted. + * @param boolean $b The deleted state of this object. + * @return void + */ + public function setDeleted($b) + { + $this->deleted = (Boolean) $b; + } + + /** + * Sets the modified state for the object to be false. + * @param string $col If supplied, only the specified column is reset. + * @return void + */ + public function resetModified($col = null) + { + if (null !== $col) { + while (false !== ($offset = array_search($col, $this->modifiedColumns))) { + array_splice($this->modifiedColumns, $offset, 1); + } + } else { + $this->modifiedColumns = array(); + } + } + + /** + * Compares this with another ProductImageI18n instance. If + * obj is an instance of ProductImageI18n, delegates to + * equals(ProductImageI18n). Otherwise, returns false. + * + * @param obj The object to compare to. + * @return Whether equal to the object specified. + */ + public function equals($obj) + { + $thisclazz = get_class($this); + if (!is_object($obj) || !($obj instanceof $thisclazz)) { + return false; + } + + if ($this === $obj) { + return true; + } + + if (null === $this->getPrimaryKey() + || null === $obj->getPrimaryKey()) { + return false; + } + + return $this->getPrimaryKey() === $obj->getPrimaryKey(); + } + + /** + * If the primary key is not null, return the hashcode of the + * primary key. Otherwise, return the hash code of the object. + * + * @return int Hashcode + */ + public function hashCode() + { + if (null !== $this->getPrimaryKey()) { + return crc32(serialize($this->getPrimaryKey())); + } + + return crc32(serialize(clone $this)); + } + + /** + * Get the associative array of the virtual columns in this object + * + * @param string $name The virtual column name + * + * @return array + */ + public function getVirtualColumns() + { + return $this->virtualColumns; + } + + /** + * Checks the existence of a virtual column in this object + * + * @return boolean + */ + public function hasVirtualColumn($name) + { + return isset($this->virtualColumns[$name]); + } + + /** + * Get the value of a virtual column in this object + * + * @return mixed + */ + public function getVirtualColumn($name) + { + if (!$this->hasVirtualColumn($name)) { + throw new PropelException(sprintf('Cannot get value of inexistent virtual column %s.', $name)); + } + + return $this->virtualColumns[$name]; + } + + /** + * Set the value of a virtual column in this object + * + * @param string $name The virtual column name + * @param mixed $value The value to give to the virtual column + * + * @return ProductImageI18n The current object, for fluid interface + */ + public function setVirtualColumn($name, $value) + { + $this->virtualColumns[$name] = $value; + + return $this; + } + + /** + * Logs a message using Propel::log(). + * + * @param string $msg + * @param int $priority One of the Propel::LOG_* logging levels + * @return boolean + */ + protected function log($msg, $priority = Propel::LOG_INFO) + { + return Propel::log(get_class($this) . ': ' . $msg, $priority); + } + + /** + * Populate the current object from a string, using a given parser format + * + * $book = new Book(); + * $book->importFrom('JSON', '{"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, + * or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param string $data The source data to import from + * + * @return ProductImageI18n The current object, for fluid interface + */ + public function importFrom($parser, $data) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $this->fromArray($parser->toArray($data), TableMap::TYPE_PHPNAME); + } + + /** + * Export the current object properties to a string, using a given parser format + * + * $book = BookQuery::create()->findPk(9012); + * echo $book->exportTo('JSON'); + * => {"Id":9012,"Title":"Don Juan","ISBN":"0140422161","Price":12.99,"PublisherId":1234,"AuthorId":5678}'); + * + * + * @param mixed $parser A AbstractParser instance, or a format name ('XML', 'YAML', 'JSON', 'CSV') + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy load(ed) columns. Defaults to TRUE. + * @return string The exported data + */ + public function exportTo($parser, $includeLazyLoadColumns = true) + { + if (!$parser instanceof AbstractParser) { + $parser = AbstractParser::getParser($parser); + } + + return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)); + } + + /** + * Clean up internal collections prior to serializing + * Avoids recursive loops that turn into segmentation faults when serializing + */ + public function __sleep() + { + $this->clearAllReferences(); + + return array_keys(get_object_vars($this)); + } + + /** + * Get the [id] column value. + * + * @return int + */ + public function getId() + { + + return $this->id; + } + + /** + * Get the [locale] column value. + * + * @return string + */ + public function getLocale() + { + + return $this->locale; + } + + /** + * Get the [title] column value. + * + * @return string + */ + public function getTitle() + { + + return $this->title; + } + + /** + * Get the [description] column value. + * + * @return string + */ + public function getDescription() + { + + return $this->description; + } + + /** + * Get the [chapo] column value. + * + * @return string + */ + public function getChapo() + { + + return $this->chapo; + } + + /** + * Get the [postscriptum] column value. + * + * @return string + */ + public function getPostscriptum() + { + + return $this->postscriptum; + } + + /** + * Set the value of [id] column. + * + * @param int $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setId($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->id !== $v) { + $this->id = $v; + $this->modifiedColumns[] = ProductImageI18nTableMap::ID; + } + + if ($this->aProductImage !== null && $this->aProductImage->getId() !== $v) { + $this->aProductImage = null; + } + + + return $this; + } // setId() + + /** + * Set the value of [locale] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setLocale($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->locale !== $v) { + $this->locale = $v; + $this->modifiedColumns[] = ProductImageI18nTableMap::LOCALE; + } + + + return $this; + } // setLocale() + + /** + * Set the value of [title] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setTitle($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->title !== $v) { + $this->title = $v; + $this->modifiedColumns[] = ProductImageI18nTableMap::TITLE; + } + + + return $this; + } // setTitle() + + /** + * Set the value of [description] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setDescription($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->description !== $v) { + $this->description = $v; + $this->modifiedColumns[] = ProductImageI18nTableMap::DESCRIPTION; + } + + + return $this; + } // setDescription() + + /** + * Set the value of [chapo] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setChapo($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->chapo !== $v) { + $this->chapo = $v; + $this->modifiedColumns[] = ProductImageI18nTableMap::CHAPO; + } + + + return $this; + } // setChapo() + + /** + * Set the value of [postscriptum] column. + * + * @param string $v new value + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + */ + public function setPostscriptum($v) + { + if ($v !== null) { + $v = (string) $v; + } + + if ($this->postscriptum !== $v) { + $this->postscriptum = $v; + $this->modifiedColumns[] = ProductImageI18nTableMap::POSTSCRIPTUM; + } + + + return $this; + } // setPostscriptum() + + /** + * Indicates whether the columns in this object are only set to default values. + * + * This method can be used in conjunction with isModified() to indicate whether an object is both + * modified _and_ has some values set which are non-default. + * + * @return boolean Whether the columns in this object are only been set with default values. + */ + public function hasOnlyDefaultValues() + { + if ($this->locale !== 'en_US') { + return false; + } + + // otherwise, everything was equal, so return TRUE + return true; + } // hasOnlyDefaultValues() + + /** + * Hydrates (populates) the object variables with values from the database resultset. + * + * An offset (0-based "start column") is specified so that objects can be hydrated + * with a subset of the columns in the resultset rows. This is needed, for example, + * for results of JOIN queries where the resultset row includes columns from two or + * more tables. + * + * @param array $row The row returned by DataFetcher->fetch(). + * @param int $startcol 0-based offset column which indicates which restultset column to start with. + * @param boolean $rehydrate Whether this object is being re-hydrated from the database. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @return int next starting column + * @throws PropelException - Any caught Exception will be rewrapped as a PropelException. + */ + public function hydrate($row, $startcol = 0, $rehydrate = false, $indexType = TableMap::TYPE_NUM) + { + try { + + + $col = $row[TableMap::TYPE_NUM == $indexType ? 0 + $startcol : ProductImageI18nTableMap::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + $this->id = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : ProductImageI18nTableMap::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)]; + $this->locale = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : ProductImageI18nTableMap::translateFieldName('Title', TableMap::TYPE_PHPNAME, $indexType)]; + $this->title = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : ProductImageI18nTableMap::translateFieldName('Description', TableMap::TYPE_PHPNAME, $indexType)]; + $this->description = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : ProductImageI18nTableMap::translateFieldName('Chapo', TableMap::TYPE_PHPNAME, $indexType)]; + $this->chapo = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : ProductImageI18nTableMap::translateFieldName('Postscriptum', TableMap::TYPE_PHPNAME, $indexType)]; + $this->postscriptum = (null !== $col) ? (string) $col : null; + $this->resetModified(); + + $this->setNew(false); + + if ($rehydrate) { + $this->ensureConsistency(); + } + + return $startcol + 6; // 6 = ProductImageI18nTableMap::NUM_HYDRATE_COLUMNS. + + } catch (Exception $e) { + throw new PropelException("Error populating \Thelia\Model\ProductImageI18n object", 0, $e); + } + } + + /** + * Checks and repairs the internal consistency of the object. + * + * This method is executed after an already-instantiated object is re-hydrated + * from the database. It exists to check any foreign keys to make sure that + * the objects related to the current object are correct based on foreign key. + * + * You can override this method in the stub class, but you should always invoke + * the base method from the overridden method (i.e. parent::ensureConsistency()), + * in case your model changes. + * + * @throws PropelException + */ + public function ensureConsistency() + { + if ($this->aProductImage !== null && $this->id !== $this->aProductImage->getId()) { + $this->aProductImage = null; + } + } // ensureConsistency + + /** + * Reloads this object from datastore based on primary key and (optionally) resets all associated objects. + * + * This will only work if the object has been saved and has a valid primary key set. + * + * @param boolean $deep (optional) Whether to also de-associated any related objects. + * @param ConnectionInterface $con (optional) The ConnectionInterface connection to use. + * @return void + * @throws PropelException - if this object is deleted, unsaved or doesn't have pk match in db + */ + public function reload($deep = false, ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("Cannot reload a deleted object."); + } + + if ($this->isNew()) { + throw new PropelException("Cannot reload an unsaved object."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + + // We don't need to alter the object instance pool; we're just modifying this instance + // already in the pool. + + $dataFetcher = ChildProductImageI18nQuery::create(null, $this->buildPkeyCriteria())->setFormatter(ModelCriteria::FORMAT_STATEMENT)->find($con); + $row = $dataFetcher->fetch(); + $dataFetcher->close(); + if (!$row) { + throw new PropelException('Cannot find matching row in the database to reload object values.'); + } + $this->hydrate($row, 0, true, $dataFetcher->getIndexType()); // rehydrate + + if ($deep) { // also de-associate any related objects? + + $this->aProductImage = null; + } // if (deep) + } + + /** + * Removes this object from datastore and sets delete attribute. + * + * @param ConnectionInterface $con + * @return void + * @throws PropelException + * @see ProductImageI18n::setDeleted() + * @see ProductImageI18n::isDeleted() + */ + public function delete(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("This object has already been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + try { + $deleteQuery = ChildProductImageI18nQuery::create() + ->filterByPrimaryKey($this->getPrimaryKey()); + $ret = $this->preDelete($con); + if ($ret) { + $deleteQuery->delete($con); + $this->postDelete($con); + $con->commit(); + $this->setDeleted(true); + } else { + $con->commit(); + } + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Persists this object to the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All modified related objects will also be persisted in the doSave() + * method. This method wraps all precipitate database operations in a + * single transaction. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see doSave() + */ + public function save(ConnectionInterface $con = null) + { + if ($this->isDeleted()) { + throw new PropelException("You cannot save an object that has been deleted."); + } + + if ($con === null) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + + $con->beginTransaction(); + $isInsert = $this->isNew(); + try { + $ret = $this->preSave($con); + if ($isInsert) { + $ret = $ret && $this->preInsert($con); + } else { + $ret = $ret && $this->preUpdate($con); + } + if ($ret) { + $affectedRows = $this->doSave($con); + if ($isInsert) { + $this->postInsert($con); + } else { + $this->postUpdate($con); + } + $this->postSave($con); + ProductImageI18nTableMap::addInstanceToPool($this); + } else { + $affectedRows = 0; + } + $con->commit(); + + return $affectedRows; + } catch (Exception $e) { + $con->rollBack(); + throw $e; + } + } + + /** + * Performs the work of inserting or updating the row in the database. + * + * If the object is new, it inserts it; otherwise an update is performed. + * All related objects are also updated in this method. + * + * @param ConnectionInterface $con + * @return int The number of rows affected by this insert/update and any referring fk objects' save() operations. + * @throws PropelException + * @see save() + */ + protected function doSave(ConnectionInterface $con) + { + $affectedRows = 0; // initialize var to track total num of affected rows + if (!$this->alreadyInSave) { + $this->alreadyInSave = true; + + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aProductImage !== null) { + if ($this->aProductImage->isModified() || $this->aProductImage->isNew()) { + $affectedRows += $this->aProductImage->save($con); + } + $this->setProductImage($this->aProductImage); + } + + if ($this->isNew() || $this->isModified()) { + // persist changes + if ($this->isNew()) { + $this->doInsert($con); + } else { + $this->doUpdate($con); + } + $affectedRows += 1; + $this->resetModified(); + } + + $this->alreadyInSave = false; + + } + + return $affectedRows; + } // doSave() + + /** + * Insert the row in the database. + * + * @param ConnectionInterface $con + * + * @throws PropelException + * @see doSave() + */ + protected function doInsert(ConnectionInterface $con) + { + $modifiedColumns = array(); + $index = 0; + + + // check the columns in natural order for more readable SQL queries + if ($this->isColumnModified(ProductImageI18nTableMap::ID)) { + $modifiedColumns[':p' . $index++] = 'ID'; + } + if ($this->isColumnModified(ProductImageI18nTableMap::LOCALE)) { + $modifiedColumns[':p' . $index++] = 'LOCALE'; + } + if ($this->isColumnModified(ProductImageI18nTableMap::TITLE)) { + $modifiedColumns[':p' . $index++] = 'TITLE'; + } + if ($this->isColumnModified(ProductImageI18nTableMap::DESCRIPTION)) { + $modifiedColumns[':p' . $index++] = 'DESCRIPTION'; + } + if ($this->isColumnModified(ProductImageI18nTableMap::CHAPO)) { + $modifiedColumns[':p' . $index++] = 'CHAPO'; + } + if ($this->isColumnModified(ProductImageI18nTableMap::POSTSCRIPTUM)) { + $modifiedColumns[':p' . $index++] = 'POSTSCRIPTUM'; + } + + $sql = sprintf( + 'INSERT INTO product_image_i18n (%s) VALUES (%s)', + implode(', ', $modifiedColumns), + implode(', ', array_keys($modifiedColumns)) + ); + + try { + $stmt = $con->prepare($sql); + foreach ($modifiedColumns as $identifier => $columnName) { + switch ($columnName) { + case 'ID': + $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT); + break; + case 'LOCALE': + $stmt->bindValue($identifier, $this->locale, PDO::PARAM_STR); + break; + case 'TITLE': + $stmt->bindValue($identifier, $this->title, PDO::PARAM_STR); + break; + case 'DESCRIPTION': + $stmt->bindValue($identifier, $this->description, PDO::PARAM_STR); + break; + case 'CHAPO': + $stmt->bindValue($identifier, $this->chapo, PDO::PARAM_STR); + break; + case 'POSTSCRIPTUM': + $stmt->bindValue($identifier, $this->postscriptum, PDO::PARAM_STR); + break; + } + } + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute INSERT statement [%s]', $sql), 0, $e); + } + + $this->setNew(false); + } + + /** + * Update the row in the database. + * + * @param ConnectionInterface $con + * + * @return Integer Number of updated rows + * @see doSave() + */ + protected function doUpdate(ConnectionInterface $con) + { + $selectCriteria = $this->buildPkeyCriteria(); + $valuesCriteria = $this->buildCriteria(); + + return $selectCriteria->doUpdate($valuesCriteria, $con); + } + + /** + * Retrieves a field from the object by name passed in as a string. + * + * @param string $name name + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return mixed Value of field. + */ + public function getByName($name, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductImageI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + $field = $this->getByPosition($pos); + + return $field; + } + + /** + * Retrieves a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @return mixed Value of field at $pos + */ + public function getByPosition($pos) + { + switch ($pos) { + case 0: + return $this->getId(); + break; + case 1: + return $this->getLocale(); + break; + case 2: + return $this->getTitle(); + break; + case 3: + return $this->getDescription(); + break; + case 4: + return $this->getChapo(); + break; + case 5: + return $this->getPostscriptum(); + break; + default: + return null; + break; + } // switch() + } + + /** + * Exports the object as an array. + * + * You can specify the key type of the array by passing one of the class + * type constants. + * + * @param string $keyType (optional) One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. + * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. + * + * @return array an associative array containing the field names (as keys) and field values + */ + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) + { + if (isset($alreadyDumpedObjects['ProductImageI18n'][serialize($this->getPrimaryKey())])) { + return '*RECURSION*'; + } + $alreadyDumpedObjects['ProductImageI18n'][serialize($this->getPrimaryKey())] = true; + $keys = ProductImageI18nTableMap::getFieldNames($keyType); + $result = array( + $keys[0] => $this->getId(), + $keys[1] => $this->getLocale(), + $keys[2] => $this->getTitle(), + $keys[3] => $this->getDescription(), + $keys[4] => $this->getChapo(), + $keys[5] => $this->getPostscriptum(), + ); + $virtualColumns = $this->virtualColumns; + foreach($virtualColumns as $key => $virtualColumn) + { + $result[$key] = $virtualColumn; + } + + if ($includeForeignObjects) { + if (null !== $this->aProductImage) { + $result['ProductImage'] = $this->aProductImage->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } + + return $result; + } + + /** + * Sets a field from the object by name passed in as a string. + * + * @param string $name + * @param mixed $value field value + * @param string $type The type of fieldname the $name is of: + * one of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * Defaults to TableMap::TYPE_PHPNAME. + * @return void + */ + public function setByName($name, $value, $type = TableMap::TYPE_PHPNAME) + { + $pos = ProductImageI18nTableMap::translateFieldName($name, $type, TableMap::TYPE_NUM); + + return $this->setByPosition($pos, $value); + } + + /** + * Sets a field from the object by Position as specified in the xml schema. + * Zero-based. + * + * @param int $pos position in xml schema + * @param mixed $value field value + * @return void + */ + public function setByPosition($pos, $value) + { + switch ($pos) { + case 0: + $this->setId($value); + break; + case 1: + $this->setLocale($value); + break; + case 2: + $this->setTitle($value); + break; + case 3: + $this->setDescription($value); + break; + case 4: + $this->setChapo($value); + break; + case 5: + $this->setPostscriptum($value); + break; + } // switch() + } + + /** + * Populates the object using an array. + * + * This is particularly useful when populating an object from one of the + * request arrays (e.g. $_POST). This method goes through the column + * names, checking to see whether a matching key exists in populated + * array. If so the setByName() method is called for that column. + * + * You can specify the key type of the array by additionally passing one + * of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME, + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * The default key type is the column's TableMap::TYPE_PHPNAME. + * + * @param array $arr An array to populate the object from. + * @param string $keyType The type of keys the array uses. + * @return void + */ + public function fromArray($arr, $keyType = TableMap::TYPE_PHPNAME) + { + $keys = ProductImageI18nTableMap::getFieldNames($keyType); + + if (array_key_exists($keys[0], $arr)) $this->setId($arr[$keys[0]]); + if (array_key_exists($keys[1], $arr)) $this->setLocale($arr[$keys[1]]); + if (array_key_exists($keys[2], $arr)) $this->setTitle($arr[$keys[2]]); + if (array_key_exists($keys[3], $arr)) $this->setDescription($arr[$keys[3]]); + if (array_key_exists($keys[4], $arr)) $this->setChapo($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setPostscriptum($arr[$keys[5]]); + } + + /** + * Build a Criteria object containing the values of all modified columns in this object. + * + * @return Criteria The Criteria object containing all modified values. + */ + public function buildCriteria() + { + $criteria = new Criteria(ProductImageI18nTableMap::DATABASE_NAME); + + if ($this->isColumnModified(ProductImageI18nTableMap::ID)) $criteria->add(ProductImageI18nTableMap::ID, $this->id); + if ($this->isColumnModified(ProductImageI18nTableMap::LOCALE)) $criteria->add(ProductImageI18nTableMap::LOCALE, $this->locale); + if ($this->isColumnModified(ProductImageI18nTableMap::TITLE)) $criteria->add(ProductImageI18nTableMap::TITLE, $this->title); + if ($this->isColumnModified(ProductImageI18nTableMap::DESCRIPTION)) $criteria->add(ProductImageI18nTableMap::DESCRIPTION, $this->description); + if ($this->isColumnModified(ProductImageI18nTableMap::CHAPO)) $criteria->add(ProductImageI18nTableMap::CHAPO, $this->chapo); + if ($this->isColumnModified(ProductImageI18nTableMap::POSTSCRIPTUM)) $criteria->add(ProductImageI18nTableMap::POSTSCRIPTUM, $this->postscriptum); + + return $criteria; + } + + /** + * Builds a Criteria object containing the primary key for this object. + * + * Unlike buildCriteria() this method includes the primary key values regardless + * of whether or not they have been modified. + * + * @return Criteria The Criteria object containing value(s) for primary key(s). + */ + public function buildPkeyCriteria() + { + $criteria = new Criteria(ProductImageI18nTableMap::DATABASE_NAME); + $criteria->add(ProductImageI18nTableMap::ID, $this->id); + $criteria->add(ProductImageI18nTableMap::LOCALE, $this->locale); + + return $criteria; + } + + /** + * Returns the composite primary key for this object. + * The array elements will be in same order as specified in XML. + * @return array + */ + public function getPrimaryKey() + { + $pks = array(); + $pks[0] = $this->getId(); + $pks[1] = $this->getLocale(); + + return $pks; + } + + /** + * Set the [composite] primary key. + * + * @param array $keys The elements of the composite key (order must match the order in XML file). + * @return void + */ + public function setPrimaryKey($keys) + { + $this->setId($keys[0]); + $this->setLocale($keys[1]); + } + + /** + * Returns true if the primary key for this object is null. + * @return boolean + */ + public function isPrimaryKeyNull() + { + + return (null === $this->getId()) && (null === $this->getLocale()); + } + + /** + * Sets contents of passed object to values from current object. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param object $copyObj An object of \Thelia\Model\ProductImageI18n (or compatible) type. + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @param boolean $makeNew Whether to reset autoincrement PKs and make the object new. + * @throws PropelException + */ + public function copyInto($copyObj, $deepCopy = false, $makeNew = true) + { + $copyObj->setId($this->getId()); + $copyObj->setLocale($this->getLocale()); + $copyObj->setTitle($this->getTitle()); + $copyObj->setDescription($this->getDescription()); + $copyObj->setChapo($this->getChapo()); + $copyObj->setPostscriptum($this->getPostscriptum()); + if ($makeNew) { + $copyObj->setNew(true); + } + } + + /** + * Makes a copy of this object that will be inserted as a new row in table when saved. + * It creates a new object filling in the simple attributes, but skipping any primary + * keys that are defined for the table. + * + * If desired, this method can also make copies of all associated (fkey referrers) + * objects. + * + * @param boolean $deepCopy Whether to also copy all rows that refer (by fkey) to the current row. + * @return \Thelia\Model\ProductImageI18n Clone of current object. + * @throws PropelException + */ + public function copy($deepCopy = false) + { + // we use get_class(), because this might be a subclass + $clazz = get_class($this); + $copyObj = new $clazz(); + $this->copyInto($copyObj, $deepCopy); + + return $copyObj; + } + + /** + * Declares an association between this object and a ChildProductImage object. + * + * @param ChildProductImage $v + * @return \Thelia\Model\ProductImageI18n The current object (for fluent API support) + * @throws PropelException + */ + public function setProductImage(ChildProductImage $v = null) + { + if ($v === null) { + $this->setId(NULL); + } else { + $this->setId($v->getId()); + } + + $this->aProductImage = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildProductImage object, it will not be re-added. + if ($v !== null) { + $v->addProductImageI18n($this); + } + + + return $this; + } + + + /** + * Get the associated ChildProductImage object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildProductImage The associated ChildProductImage object. + * @throws PropelException + */ + public function getProductImage(ConnectionInterface $con = null) + { + if ($this->aProductImage === null && ($this->id !== null)) { + $this->aProductImage = ChildProductImageQuery::create()->findPk($this->id, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aProductImage->addProductImageI18ns($this); + */ + } + + return $this->aProductImage; + } + + /** + * Clears the current object and sets all attributes to their default values + */ + public function clear() + { + $this->id = null; + $this->locale = null; + $this->title = null; + $this->description = null; + $this->chapo = null; + $this->postscriptum = null; + $this->alreadyInSave = false; + $this->clearAllReferences(); + $this->applyDefaultValues(); + $this->resetModified(); + $this->setNew(true); + $this->setDeleted(false); + } + + /** + * Resets all references to other model objects or collections of model objects. + * + * This method is a user-space workaround for PHP's inability to garbage collect + * objects with circular references (even in PHP 5.3). This is currently necessary + * when using Propel in certain daemon or large-volume/high-memory operations. + * + * @param boolean $deep Whether to also clear the references on all referrer objects. + */ + public function clearAllReferences($deep = false) + { + if ($deep) { + } // if ($deep) + + $this->aProductImage = null; + } + + /** + * Return the string representation of this object + * + * @return string + */ + public function __toString() + { + return (string) $this->exportTo(ProductImageI18nTableMap::DEFAULT_STRING_FORMAT); + } + + /** + * Code to be run before persisting the object + * @param ConnectionInterface $con + * @return boolean + */ + public function preSave(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after persisting the object + * @param ConnectionInterface $con + */ + public function postSave(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before inserting to database + * @param ConnectionInterface $con + * @return boolean + */ + public function preInsert(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after inserting to database + * @param ConnectionInterface $con + */ + public function postInsert(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before updating the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preUpdate(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after updating the object in database + * @param ConnectionInterface $con + */ + public function postUpdate(ConnectionInterface $con = null) + { + + } + + /** + * Code to be run before deleting the object in database + * @param ConnectionInterface $con + * @return boolean + */ + public function preDelete(ConnectionInterface $con = null) + { + return true; + } + + /** + * Code to be run after deleting the object in database + * @param ConnectionInterface $con + */ + public function postDelete(ConnectionInterface $con = null) + { + + } + + + /** + * Derived method to catches calls to undefined methods. + * + * Provides magic import/export method support (fromXML()/toXML(), fromYAML()/toYAML(), etc.). + * Allows to define default __call() behavior if you overwrite __call() + * + * @param string $name + * @param mixed $params + * + * @return array|string + */ + public function __call($name, $params) + { + if (0 === strpos($name, 'get')) { + $virtualColumn = substr($name, 3); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + + $virtualColumn = lcfirst($virtualColumn); + if ($this->hasVirtualColumn($virtualColumn)) { + return $this->getVirtualColumn($virtualColumn); + } + } + + if (0 === strpos($name, 'from')) { + $format = substr($name, 4); + + return $this->importFrom($format, reset($params)); + } + + if (0 === strpos($name, 'to')) { + $format = substr($name, 2); + $includeLazyLoadColumns = isset($params[0]) ? $params[0] : true; + + return $this->exportTo($format, $includeLazyLoadColumns); + } + + throw new BadMethodCallException(sprintf('Call to undefined method: %s.', $name)); + } + +} diff --git a/core/lib/Thelia/Model/Base/ProductImageI18nQuery.php b/core/lib/Thelia/Model/Base/ProductImageI18nQuery.php new file mode 100644 index 000000000..c1f34fbb9 --- /dev/null +++ b/core/lib/Thelia/Model/Base/ProductImageI18nQuery.php @@ -0,0 +1,607 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(array(12, 34), $con); + * + * + * @param array[$id, $locale] $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProductImageI18n|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = ProductImageI18nTableMap::getInstanceFromPool(serialize(array((string) $key[0], (string) $key[1]))))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildProductImageI18n A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, LOCALE, TITLE, DESCRIPTION, CHAPO, POSTSCRIPTUM FROM product_image_i18n WHERE ID = :p0 AND LOCALE = :p1'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key[0], PDO::PARAM_INT); + $stmt->bindValue(':p1', $key[1], PDO::PARAM_STR); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildProductImageI18n(); + $obj->hydrate($row); + ProductImageI18nTableMap::addInstanceToPool($obj, serialize(array((string) $key[0], (string) $key[1]))); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildProductImageI18n|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(array(12, 56), array(832, 123), array(123, 456)), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + $this->addUsingAlias(ProductImageI18nTableMap::ID, $key[0], Criteria::EQUAL); + $this->addUsingAlias(ProductImageI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); + + return $this; + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + if (empty($keys)) { + return $this->add(null, '1<>1', Criteria::CUSTOM); + } + foreach ($keys as $key) { + $cton0 = $this->getNewCriterion(ProductImageI18nTableMap::ID, $key[0], Criteria::EQUAL); + $cton1 = $this->getNewCriterion(ProductImageI18nTableMap::LOCALE, $key[1], Criteria::EQUAL); + $cton0->addAnd($cton1); + $this->addOr($cton0); + } + + return $this; + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @see filterByProductImage() + * + * @param mixed $id The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(ProductImageI18nTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(ProductImageI18nTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductImageI18nTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the locale column + * + * Example usage: + * + * $query->filterByLocale('fooValue'); // WHERE locale = 'fooValue' + * $query->filterByLocale('%fooValue%'); // WHERE locale LIKE '%fooValue%' + * + * + * @param string $locale The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByLocale($locale = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($locale)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $locale)) { + $locale = str_replace('*', '%', $locale); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductImageI18nTableMap::LOCALE, $locale, $comparison); + } + + /** + * Filter the query on the title column + * + * Example usage: + * + * $query->filterByTitle('fooValue'); // WHERE title = 'fooValue' + * $query->filterByTitle('%fooValue%'); // WHERE title LIKE '%fooValue%' + * + * + * @param string $title The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByTitle($title = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($title)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $title)) { + $title = str_replace('*', '%', $title); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductImageI18nTableMap::TITLE, $title, $comparison); + } + + /** + * Filter the query on the description column + * + * Example usage: + * + * $query->filterByDescription('fooValue'); // WHERE description = 'fooValue' + * $query->filterByDescription('%fooValue%'); // WHERE description LIKE '%fooValue%' + * + * + * @param string $description The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByDescription($description = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($description)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $description)) { + $description = str_replace('*', '%', $description); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductImageI18nTableMap::DESCRIPTION, $description, $comparison); + } + + /** + * Filter the query on the chapo column + * + * Example usage: + * + * $query->filterByChapo('fooValue'); // WHERE chapo = 'fooValue' + * $query->filterByChapo('%fooValue%'); // WHERE chapo LIKE '%fooValue%' + * + * + * @param string $chapo The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByChapo($chapo = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($chapo)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $chapo)) { + $chapo = str_replace('*', '%', $chapo); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductImageI18nTableMap::CHAPO, $chapo, $comparison); + } + + /** + * Filter the query on the postscriptum column + * + * Example usage: + * + * $query->filterByPostscriptum('fooValue'); // WHERE postscriptum = 'fooValue' + * $query->filterByPostscriptum('%fooValue%'); // WHERE postscriptum LIKE '%fooValue%' + * + * + * @param string $postscriptum The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByPostscriptum($postscriptum = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($postscriptum)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $postscriptum)) { + $postscriptum = str_replace('*', '%', $postscriptum); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductImageI18nTableMap::POSTSCRIPTUM, $postscriptum, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\ProductImage object + * + * @param \Thelia\Model\ProductImage|ObjectCollection $productImage The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function filterByProductImage($productImage, $comparison = null) + { + if ($productImage instanceof \Thelia\Model\ProductImage) { + return $this + ->addUsingAlias(ProductImageI18nTableMap::ID, $productImage->getId(), $comparison); + } elseif ($productImage instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(ProductImageI18nTableMap::ID, $productImage->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByProductImage() only accepts arguments of type \Thelia\Model\ProductImage or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the ProductImage relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function joinProductImage($relationAlias = null, $joinType = 'LEFT JOIN') + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('ProductImage'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'ProductImage'); + } + + return $this; + } + + /** + * Use the ProductImage relation ProductImage object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\ProductImageQuery A secondary query class using the current class as primary query + */ + public function useProductImageQuery($relationAlias = null, $joinType = 'LEFT JOIN') + { + return $this + ->joinProductImage($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ProductImage', '\Thelia\Model\ProductImageQuery'); + } + + /** + * Exclude object from result + * + * @param ChildProductImageI18n $productImageI18n Object to remove from the list of results + * + * @return ChildProductImageI18nQuery The current query, for fluid interface + */ + public function prune($productImageI18n = null) + { + if ($productImageI18n) { + $this->addCond('pruneCond0', $this->getAliasedColName(ProductImageI18nTableMap::ID), $productImageI18n->getId(), Criteria::NOT_EQUAL); + $this->addCond('pruneCond1', $this->getAliasedColName(ProductImageI18nTableMap::LOCALE), $productImageI18n->getLocale(), Criteria::NOT_EQUAL); + $this->combine(array('pruneCond0', 'pruneCond1'), Criteria::LOGICAL_OR); + } + + return $this; + } + + /** + * Deletes all rows from the product_image_i18n table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + ProductImageI18nTableMap::clearInstancePool(); + ProductImageI18nTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildProductImageI18n or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildProductImageI18n object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(ProductImageI18nTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + ProductImageI18nTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + ProductImageI18nTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + +} // ProductImageI18nQuery diff --git a/core/lib/Thelia/Model/Base/ProductImageQuery.php b/core/lib/Thelia/Model/Base/ProductImageQuery.php new file mode 100644 index 000000000..94cb1b361 --- /dev/null +++ b/core/lib/Thelia/Model/Base/ProductImageQuery.php @@ -0,0 +1,846 @@ +setModelAlias($modelAlias); + } + if ($criteria instanceof Criteria) { + $query->mergeWith($criteria); + } + + return $query; + } + + /** + * Find object by primary key. + * Propel uses the instance pool to skip the database if the object exists. + * Go fast if the query is untouched. + * + * + * $obj = $c->findPk(12, $con); + * + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ChildProductImage|array|mixed the result, formatted by the current formatter + */ + public function findPk($key, $con = null) + { + if ($key === null) { + return null; + } + if ((null !== ($obj = ProductImageTableMap::getInstanceFromPool((string) $key))) && !$this->formatter) { + // the object is already in the instance pool + return $obj; + } + if ($con === null) { + $con = Propel::getServiceContainer()->getReadConnection(ProductImageTableMap::DATABASE_NAME); + } + $this->basePreSelect($con); + if ($this->formatter || $this->modelAlias || $this->with || $this->select + || $this->selectColumns || $this->asColumns || $this->selectModifiers + || $this->map || $this->having || $this->joins) { + return $this->findPkComplex($key, $con); + } else { + return $this->findPkSimple($key, $con); + } + } + + /** + * Find object by primary key using raw SQL to go fast. + * Bypass doSelect() and the object formatter by using generated code. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildProductImage A model object, or null if the key is not found + */ + protected function findPkSimple($key, $con) + { + $sql = 'SELECT ID, PRODUCT_ID, FILE, POSITION, CREATED_AT, UPDATED_AT FROM product_image WHERE ID = :p0'; + try { + $stmt = $con->prepare($sql); + $stmt->bindValue(':p0', $key, PDO::PARAM_INT); + $stmt->execute(); + } catch (Exception $e) { + Propel::log($e->getMessage(), Propel::LOG_ERR); + throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), 0, $e); + } + $obj = null; + if ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + $obj = new ChildProductImage(); + $obj->hydrate($row); + ProductImageTableMap::addInstanceToPool($obj, (string) $key); + } + $stmt->closeCursor(); + + return $obj; + } + + /** + * Find object by primary key. + * + * @param mixed $key Primary key to use for the query + * @param ConnectionInterface $con A connection object + * + * @return ChildProductImage|array|mixed the result, formatted by the current formatter + */ + protected function findPkComplex($key, $con) + { + // As the query uses a PK condition, no limit(1) is necessary. + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKey($key) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->formatOne($dataFetcher); + } + + /** + * Find objects by primary key + * + * $objs = $c->findPks(array(12, 56, 832), $con); + * + * @param array $keys Primary keys to use for the query + * @param ConnectionInterface $con an optional connection object + * + * @return ObjectCollection|array|mixed the list of results, formatted by the current formatter + */ + public function findPks($keys, $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getReadConnection($this->getDbName()); + } + $this->basePreSelect($con); + $criteria = $this->isKeepQuery() ? clone $this : $this; + $dataFetcher = $criteria + ->filterByPrimaryKeys($keys) + ->doSelect($con); + + return $criteria->getFormatter()->init($criteria)->format($dataFetcher); + } + + /** + * Filter the query by primary key + * + * @param mixed $key Primary key to use for the query + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByPrimaryKey($key) + { + + return $this->addUsingAlias(ProductImageTableMap::ID, $key, Criteria::EQUAL); + } + + /** + * Filter the query by a list of primary keys + * + * @param array $keys The list of primary key to use for the query + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByPrimaryKeys($keys) + { + + return $this->addUsingAlias(ProductImageTableMap::ID, $keys, Criteria::IN); + } + + /** + * Filter the query on the id column + * + * Example usage: + * + * $query->filterById(1234); // WHERE id = 1234 + * $query->filterById(array(12, 34)); // WHERE id IN (12, 34) + * $query->filterById(array('min' => 12)); // WHERE id > 12 + * + * + * @param mixed $id The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterById($id = null, $comparison = null) + { + if (is_array($id)) { + $useMinMax = false; + if (isset($id['min'])) { + $this->addUsingAlias(ProductImageTableMap::ID, $id['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($id['max'])) { + $this->addUsingAlias(ProductImageTableMap::ID, $id['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductImageTableMap::ID, $id, $comparison); + } + + /** + * Filter the query on the product_id column + * + * Example usage: + * + * $query->filterByProductId(1234); // WHERE product_id = 1234 + * $query->filterByProductId(array(12, 34)); // WHERE product_id IN (12, 34) + * $query->filterByProductId(array('min' => 12)); // WHERE product_id > 12 + * + * + * @see filterByProduct() + * + * @param mixed $productId The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByProductId($productId = null, $comparison = null) + { + if (is_array($productId)) { + $useMinMax = false; + if (isset($productId['min'])) { + $this->addUsingAlias(ProductImageTableMap::PRODUCT_ID, $productId['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($productId['max'])) { + $this->addUsingAlias(ProductImageTableMap::PRODUCT_ID, $productId['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductImageTableMap::PRODUCT_ID, $productId, $comparison); + } + + /** + * Filter the query on the file column + * + * Example usage: + * + * $query->filterByFile('fooValue'); // WHERE file = 'fooValue' + * $query->filterByFile('%fooValue%'); // WHERE file LIKE '%fooValue%' + * + * + * @param string $file The value to use as filter. + * Accepts wildcards (* and % trigger a LIKE) + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByFile($file = null, $comparison = null) + { + if (null === $comparison) { + if (is_array($file)) { + $comparison = Criteria::IN; + } elseif (preg_match('/[\%\*]/', $file)) { + $file = str_replace('*', '%', $file); + $comparison = Criteria::LIKE; + } + } + + return $this->addUsingAlias(ProductImageTableMap::FILE, $file, $comparison); + } + + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(ProductImageTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(ProductImageTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductImageTableMap::POSITION, $position, $comparison); + } + + /** + * Filter the query on the created_at column + * + * Example usage: + * + * $query->filterByCreatedAt('2011-03-14'); // WHERE created_at = '2011-03-14' + * $query->filterByCreatedAt('now'); // WHERE created_at = '2011-03-14' + * $query->filterByCreatedAt(array('max' => 'yesterday')); // WHERE created_at > '2011-03-13' + * + * + * @param mixed $createdAt The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByCreatedAt($createdAt = null, $comparison = null) + { + if (is_array($createdAt)) { + $useMinMax = false; + if (isset($createdAt['min'])) { + $this->addUsingAlias(ProductImageTableMap::CREATED_AT, $createdAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($createdAt['max'])) { + $this->addUsingAlias(ProductImageTableMap::CREATED_AT, $createdAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductImageTableMap::CREATED_AT, $createdAt, $comparison); + } + + /** + * Filter the query on the updated_at column + * + * Example usage: + * + * $query->filterByUpdatedAt('2011-03-14'); // WHERE updated_at = '2011-03-14' + * $query->filterByUpdatedAt('now'); // WHERE updated_at = '2011-03-14' + * $query->filterByUpdatedAt(array('max' => 'yesterday')); // WHERE updated_at > '2011-03-13' + * + * + * @param mixed $updatedAt The value to use as filter. + * Values can be integers (unix timestamps), DateTime objects, or strings. + * Empty strings are treated as NULL. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByUpdatedAt($updatedAt = null, $comparison = null) + { + if (is_array($updatedAt)) { + $useMinMax = false; + if (isset($updatedAt['min'])) { + $this->addUsingAlias(ProductImageTableMap::UPDATED_AT, $updatedAt['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($updatedAt['max'])) { + $this->addUsingAlias(ProductImageTableMap::UPDATED_AT, $updatedAt['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(ProductImageTableMap::UPDATED_AT, $updatedAt, $comparison); + } + + /** + * Filter the query by a related \Thelia\Model\Product object + * + * @param \Thelia\Model\Product|ObjectCollection $product The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByProduct($product, $comparison = null) + { + if ($product instanceof \Thelia\Model\Product) { + return $this + ->addUsingAlias(ProductImageTableMap::PRODUCT_ID, $product->getId(), $comparison); + } elseif ($product instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(ProductImageTableMap::PRODUCT_ID, $product->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByProduct() only accepts arguments of type \Thelia\Model\Product or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Product relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function joinProduct($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Product'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Product'); + } + + return $this; + } + + /** + * Use the Product relation Product object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\ProductQuery A secondary query class using the current class as primary query + */ + public function useProductQuery($relationAlias = null, $joinType = Criteria::INNER_JOIN) + { + return $this + ->joinProduct($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Product', '\Thelia\Model\ProductQuery'); + } + + /** + * Filter the query by a related \Thelia\Model\ProductImageI18n object + * + * @param \Thelia\Model\ProductImageI18n|ObjectCollection $productImageI18n the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function filterByProductImageI18n($productImageI18n, $comparison = null) + { + if ($productImageI18n instanceof \Thelia\Model\ProductImageI18n) { + return $this + ->addUsingAlias(ProductImageTableMap::ID, $productImageI18n->getId(), $comparison); + } elseif ($productImageI18n instanceof ObjectCollection) { + return $this + ->useProductImageI18nQuery() + ->filterByPrimaryKeys($productImageI18n->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByProductImageI18n() only accepts arguments of type \Thelia\Model\ProductImageI18n or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the ProductImageI18n relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function joinProductImageI18n($relationAlias = null, $joinType = 'LEFT JOIN') + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('ProductImageI18n'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'ProductImageI18n'); + } + + return $this; + } + + /** + * Use the ProductImageI18n relation ProductImageI18n object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Thelia\Model\ProductImageI18nQuery A secondary query class using the current class as primary query + */ + public function useProductImageI18nQuery($relationAlias = null, $joinType = 'LEFT JOIN') + { + return $this + ->joinProductImageI18n($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ProductImageI18n', '\Thelia\Model\ProductImageI18nQuery'); + } + + /** + * Exclude object from result + * + * @param ChildProductImage $productImage Object to remove from the list of results + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function prune($productImage = null) + { + if ($productImage) { + $this->addUsingAlias(ProductImageTableMap::ID, $productImage->getId(), Criteria::NOT_EQUAL); + } + + return $this; + } + + /** + * Deletes all rows from the product_image table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public function doDeleteAll(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageTableMap::DATABASE_NAME); + } + $affectedRows = 0; // initialize var to track total num of affected rows + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + $affectedRows += parent::doDeleteAll($con); + // Because this db requires some delete cascade/set null emulation, we have to + // clear the cached instance *after* the emulation has happened (since + // instances get re-added by the select statement contained therein). + ProductImageTableMap::clearInstancePool(); + ProductImageTableMap::clearRelatedInstancePool(); + + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $affectedRows; + } + + /** + * Performs a DELETE on the database, given a ChildProductImage or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ChildProductImage object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public function delete(ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageTableMap::DATABASE_NAME); + } + + $criteria = $this; + + // Set the correct dbName + $criteria->setDbName(ProductImageTableMap::DATABASE_NAME); + + $affectedRows = 0; // initialize var to track total num of affected rows + + try { + // use transaction because $criteria could contain info + // for more than one table or we could emulating ON DELETE CASCADE, etc. + $con->beginTransaction(); + + + ProductImageTableMap::removeInstanceFromPool($criteria); + + $affectedRows += ModelCriteria::delete($con); + ProductImageTableMap::clearRelatedInstancePool(); + $con->commit(); + + return $affectedRows; + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + } + + // timestampable behavior + + /** + * Filter by the latest updated + * + * @param int $nbDays Maximum age of the latest update in days + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function recentlyUpdated($nbDays = 7) + { + return $this->addUsingAlias(ProductImageTableMap::UPDATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Filter by the latest created + * + * @param int $nbDays Maximum age of in days + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function recentlyCreated($nbDays = 7) + { + return $this->addUsingAlias(ProductImageTableMap::CREATED_AT, time() - $nbDays * 24 * 60 * 60, Criteria::GREATER_EQUAL); + } + + /** + * Order by update date desc + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function lastUpdatedFirst() + { + return $this->addDescendingOrderByColumn(ProductImageTableMap::UPDATED_AT); + } + + /** + * Order by update date asc + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function firstUpdatedFirst() + { + return $this->addAscendingOrderByColumn(ProductImageTableMap::UPDATED_AT); + } + + /** + * Order by create date desc + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function lastCreatedFirst() + { + return $this->addDescendingOrderByColumn(ProductImageTableMap::CREATED_AT); + } + + /** + * Order by create date asc + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function firstCreatedFirst() + { + return $this->addAscendingOrderByColumn(ProductImageTableMap::CREATED_AT); + } + + // i18n behavior + + /** + * Adds a JOIN clause to the query using the i18n relation + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function joinI18n($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + $relationName = $relationAlias ? $relationAlias : 'ProductImageI18n'; + + return $this + ->joinProductImageI18n($relationAlias, $joinType) + ->addJoinCondition($relationName, $relationName . '.Locale = ?', $locale); + } + + /** + * Adds a JOIN clause to the query and hydrates the related I18n object. + * Shortcut for $c->joinI18n($locale)->with() + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildProductImageQuery The current query, for fluid interface + */ + public function joinWithI18n($locale = 'en_US', $joinType = Criteria::LEFT_JOIN) + { + $this + ->joinI18n($locale, null, $joinType) + ->with('ProductImageI18n'); + $this->with['ProductImageI18n']->setIsWithOneToMany(false); + + return $this; + } + + /** + * Use the I18n relation query object + * + * @see useQuery() + * + * @param string $locale Locale to use for the join condition, e.g. 'fr_FR' + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join'. Defaults to left join. + * + * @return ChildProductImageI18nQuery A secondary query class using the current class as primary query + */ + public function useI18nQuery($locale = 'en_US', $relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + return $this + ->joinI18n($locale, $relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'ProductImageI18n', '\Thelia\Model\ProductImageI18nQuery'); + } + +} // ProductImageQuery diff --git a/core/lib/Thelia/Model/Map/ProductImageI18nTableMap.php b/core/lib/Thelia/Model/Map/ProductImageI18nTableMap.php new file mode 100644 index 000000000..39ad567f9 --- /dev/null +++ b/core/lib/Thelia/Model/Map/ProductImageI18nTableMap.php @@ -0,0 +1,497 @@ + array('Id', 'Locale', 'Title', 'Description', 'Chapo', 'Postscriptum', ), + self::TYPE_STUDLYPHPNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), + self::TYPE_COLNAME => array(ProductImageI18nTableMap::ID, ProductImageI18nTableMap::LOCALE, ProductImageI18nTableMap::TITLE, ProductImageI18nTableMap::DESCRIPTION, ProductImageI18nTableMap::CHAPO, ProductImageI18nTableMap::POSTSCRIPTUM, ), + self::TYPE_RAW_COLNAME => array('ID', 'LOCALE', 'TITLE', 'DESCRIPTION', 'CHAPO', 'POSTSCRIPTUM', ), + self::TYPE_FIELDNAME => array('id', 'locale', 'title', 'description', 'chapo', 'postscriptum', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'Locale' => 1, 'Title' => 2, 'Description' => 3, 'Chapo' => 4, 'Postscriptum' => 5, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), + self::TYPE_COLNAME => array(ProductImageI18nTableMap::ID => 0, ProductImageI18nTableMap::LOCALE => 1, ProductImageI18nTableMap::TITLE => 2, ProductImageI18nTableMap::DESCRIPTION => 3, ProductImageI18nTableMap::CHAPO => 4, ProductImageI18nTableMap::POSTSCRIPTUM => 5, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'LOCALE' => 1, 'TITLE' => 2, 'DESCRIPTION' => 3, 'CHAPO' => 4, 'POSTSCRIPTUM' => 5, ), + self::TYPE_FIELDNAME => array('id' => 0, 'locale' => 1, 'title' => 2, 'description' => 3, 'chapo' => 4, 'postscriptum' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('product_image_i18n'); + $this->setPhpName('ProductImageI18n'); + $this->setClassName('\\Thelia\\Model\\ProductImageI18n'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(false); + // columns + $this->addForeignPrimaryKey('ID', 'Id', 'INTEGER' , 'product_image', 'ID', true, null, null); + $this->addPrimaryKey('LOCALE', 'Locale', 'VARCHAR', true, 5, 'en_US'); + $this->addColumn('TITLE', 'Title', 'VARCHAR', false, 255, null); + $this->addColumn('DESCRIPTION', 'Description', 'CLOB', false, null, null); + $this->addColumn('CHAPO', 'Chapo', 'LONGVARCHAR', false, null, null); + $this->addColumn('POSTSCRIPTUM', 'Postscriptum', 'LONGVARCHAR', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('ProductImage', '\\Thelia\\Model\\ProductImage', RelationMap::MANY_TO_ONE, array('id' => 'id', ), 'CASCADE', null); + } // buildRelations() + + /** + * Adds an object to the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases you may need to explicitly add objects + * to the cache in order to ensure that the same objects are always returned by find*() + * and findPk*() calls. + * + * @param \Thelia\Model\ProductImageI18n $obj A \Thelia\Model\ProductImageI18n object. + * @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally). + */ + public static function addInstanceToPool($obj, $key = null) + { + if (Propel::isInstancePoolingEnabled()) { + if (null === $key) { + $key = serialize(array((string) $obj->getId(), (string) $obj->getLocale())); + } // if key === null + self::$instances[$key] = $obj; + } + } + + /** + * Removes an object from the instance pool. + * + * Propel keeps cached copies of objects in an instance pool when they are retrieved + * from the database. In some cases -- especially when you override doDelete + * methods in your stub classes -- you may need to explicitly remove objects + * from the cache in order to prevent returning objects that no longer exist. + * + * @param mixed $value A \Thelia\Model\ProductImageI18n object or a primary key value. + */ + public static function removeInstanceFromPool($value) + { + if (Propel::isInstancePoolingEnabled() && null !== $value) { + if (is_object($value) && $value instanceof \Thelia\Model\ProductImageI18n) { + $key = serialize(array((string) $value->getId(), (string) $value->getLocale())); + + } elseif (is_array($value) && count($value) === 2) { + // assume we've been passed a primary key"; + $key = serialize(array((string) $value[0], (string) $value[1])); + } elseif ($value instanceof Criteria) { + self::$instances = []; + + return; + } else { + $e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or \Thelia\Model\ProductImageI18n object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value, true))); + throw $e; + } + + unset(self::$instances[$key]); + } + } + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null && $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return serialize(array((string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)], (string) $row[TableMap::TYPE_NUM == $indexType ? 1 + $offset : static::translateFieldName('Locale', TableMap::TYPE_PHPNAME, $indexType)])); + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return $pks; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? ProductImageI18nTableMap::CLASS_DEFAULT : ProductImageI18nTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (ProductImageI18n object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = ProductImageI18nTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = ProductImageI18nTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + ProductImageI18nTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = ProductImageI18nTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + ProductImageI18nTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = ProductImageI18nTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = ProductImageI18nTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + ProductImageI18nTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(ProductImageI18nTableMap::ID); + $criteria->addSelectColumn(ProductImageI18nTableMap::LOCALE); + $criteria->addSelectColumn(ProductImageI18nTableMap::TITLE); + $criteria->addSelectColumn(ProductImageI18nTableMap::DESCRIPTION); + $criteria->addSelectColumn(ProductImageI18nTableMap::CHAPO); + $criteria->addSelectColumn(ProductImageI18nTableMap::POSTSCRIPTUM); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.LOCALE'); + $criteria->addSelectColumn($alias . '.TITLE'); + $criteria->addSelectColumn($alias . '.DESCRIPTION'); + $criteria->addSelectColumn($alias . '.CHAPO'); + $criteria->addSelectColumn($alias . '.POSTSCRIPTUM'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(ProductImageI18nTableMap::DATABASE_NAME)->getTable(ProductImageI18nTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(ProductImageI18nTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(ProductImageI18nTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new ProductImageI18nTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a ProductImageI18n or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ProductImageI18n object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\ProductImageI18n) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(ProductImageI18nTableMap::DATABASE_NAME); + // primary key is composite; we therefore, expect + // the primary key passed to be an array of pkey values + if (count($values) == count($values, COUNT_RECURSIVE)) { + // array is not multi-dimensional + $values = array($values); + } + foreach ($values as $value) { + $criterion = $criteria->getNewCriterion(ProductImageI18nTableMap::ID, $value[0]); + $criterion->addAnd($criteria->getNewCriterion(ProductImageI18nTableMap::LOCALE, $value[1])); + $criteria->addOr($criterion); + } + } + + $query = ProductImageI18nQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { ProductImageI18nTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { ProductImageI18nTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the product_image_i18n table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return ProductImageI18nQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a ProductImageI18n or Criteria object. + * + * @param mixed $criteria Criteria or ProductImageI18n object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageI18nTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from ProductImageI18n object + } + + + // Set the correct dbName + $query = ProductImageI18nQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // ProductImageI18nTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +ProductImageI18nTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/Map/ProductImageTableMap.php b/core/lib/Thelia/Model/Map/ProductImageTableMap.php new file mode 100644 index 000000000..36aabed3e --- /dev/null +++ b/core/lib/Thelia/Model/Map/ProductImageTableMap.php @@ -0,0 +1,475 @@ + array('Id', 'ProductId', 'File', 'Position', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'productId', 'file', 'position', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(ProductImageTableMap::ID, ProductImageTableMap::PRODUCT_ID, ProductImageTableMap::FILE, ProductImageTableMap::POSITION, ProductImageTableMap::CREATED_AT, ProductImageTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'PRODUCT_ID', 'FILE', 'POSITION', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'product_id', 'file', 'position', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * holds an array of keys for quick access to the fieldnames array + * + * first dimension keys are the type constants + * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 + */ + protected static $fieldKeys = array ( + self::TYPE_PHPNAME => array('Id' => 0, 'ProductId' => 1, 'File' => 2, 'Position' => 3, 'CreatedAt' => 4, 'UpdatedAt' => 5, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'productId' => 1, 'file' => 2, 'position' => 3, 'createdAt' => 4, 'updatedAt' => 5, ), + self::TYPE_COLNAME => array(ProductImageTableMap::ID => 0, ProductImageTableMap::PRODUCT_ID => 1, ProductImageTableMap::FILE => 2, ProductImageTableMap::POSITION => 3, ProductImageTableMap::CREATED_AT => 4, ProductImageTableMap::UPDATED_AT => 5, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'PRODUCT_ID' => 1, 'FILE' => 2, 'POSITION' => 3, 'CREATED_AT' => 4, 'UPDATED_AT' => 5, ), + self::TYPE_FIELDNAME => array('id' => 0, 'product_id' => 1, 'file' => 2, 'position' => 3, 'created_at' => 4, 'updated_at' => 5, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, ) + ); + + /** + * Initialize the table attributes and columns + * Relations are not initialized by this method since they are lazy loaded + * + * @return void + * @throws PropelException + */ + public function initialize() + { + // attributes + $this->setName('product_image'); + $this->setPhpName('ProductImage'); + $this->setClassName('\\Thelia\\Model\\ProductImage'); + $this->setPackage('Thelia.Model'); + $this->setUseIdGenerator(true); + // columns + $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); + $this->addForeignKey('PRODUCT_ID', 'ProductId', 'INTEGER', 'product', 'ID', true, null, null); + $this->addColumn('FILE', 'File', 'VARCHAR', true, 255, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); + $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); + $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); + } // initialize() + + /** + * Build the RelationMap objects for this table relationships + */ + public function buildRelations() + { + $this->addRelation('Product', '\\Thelia\\Model\\Product', RelationMap::MANY_TO_ONE, array('product_id' => 'id', ), 'CASCADE', 'RESTRICT'); + $this->addRelation('ProductImageI18n', '\\Thelia\\Model\\ProductImageI18n', RelationMap::ONE_TO_MANY, array('id' => 'id', ), 'CASCADE', null, 'ProductImageI18ns'); + } // buildRelations() + + /** + * + * Gets the list of behaviors registered for this table + * + * @return array Associative array (name => parameters) of behaviors + */ + public function getBehaviors() + { + return array( + 'timestampable' => array('create_column' => 'created_at', 'update_column' => 'updated_at', ), + 'i18n' => array('i18n_table' => '%TABLE%_i18n', 'i18n_phpname' => '%PHPNAME%I18n', 'i18n_columns' => 'title, description, chapo, postscriptum', 'locale_column' => 'locale', 'locale_length' => '5', 'default_locale' => '', 'locale_alias' => '', ), + ); + } // getBehaviors() + /** + * Method to invalidate the instance pool of all tables related to product_image * by a foreign key with ON DELETE CASCADE + */ + public static function clearRelatedInstancePool() + { + // Invalidate objects in ".$this->getClassNameFromBuilder($joinedTableTableMapBuilder)." instance pool, + // since one or more of them may be deleted by ON DELETE CASCADE/SETNULL rule. + ProductImageI18nTableMap::clearInstancePool(); + } + + /** + * Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table. + * + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, a serialize()d version of the primary key will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + */ + public static function getPrimaryKeyHashFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + // If the PK cannot be derived from the row, return NULL. + if ($row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)] === null) { + return null; + } + + return (string) $row[TableMap::TYPE_NUM == $indexType ? 0 + $offset : static::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType)]; + } + + /** + * Retrieves the primary key from the DB resultset row + * For tables with a single-column primary key, that simple pkey value will be returned. For tables with + * a multi-column primary key, an array of the primary key columns will be returned. + * + * @param array $row resultset row. + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM + * + * @return mixed The primary key of the row + */ + public static function getPrimaryKeyFromRow($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + + return (int) $row[ + $indexType == TableMap::TYPE_NUM + ? 0 + $offset + : self::translateFieldName('Id', TableMap::TYPE_PHPNAME, $indexType) + ]; + } + + /** + * The class that the tableMap will make instances of. + * + * If $withPrefix is true, the returned path + * uses a dot-path notation which is translated into a path + * relative to a location on the PHP include_path. + * (e.g. path.to.MyClass -> 'path/to/MyClass.php') + * + * @param boolean $withPrefix Whether or not to return the path with the class name + * @return string path.to.ClassName + */ + public static function getOMClass($withPrefix = true) + { + return $withPrefix ? ProductImageTableMap::CLASS_DEFAULT : ProductImageTableMap::OM_CLASS; + } + + /** + * Populates an object of the default type or an object that inherit from the default. + * + * @param array $row row returned by DataFetcher->fetch(). + * @param int $offset The 0-based offset for reading from the resultset row. + * @param string $indexType The index type of $row. Mostly DataFetcher->getIndexType(). + One of the class type constants TableMap::TYPE_PHPNAME, TableMap::TYPE_STUDLYPHPNAME + * TableMap::TYPE_COLNAME, TableMap::TYPE_FIELDNAME, TableMap::TYPE_NUM. + * + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + * @return array (ProductImage object, last column rank) + */ + public static function populateObject($row, $offset = 0, $indexType = TableMap::TYPE_NUM) + { + $key = ProductImageTableMap::getPrimaryKeyHashFromRow($row, $offset, $indexType); + if (null !== ($obj = ProductImageTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, $offset, true); // rehydrate + $col = $offset + ProductImageTableMap::NUM_HYDRATE_COLUMNS; + } else { + $cls = ProductImageTableMap::OM_CLASS; + $obj = new $cls(); + $col = $obj->hydrate($row, $offset, false, $indexType); + ProductImageTableMap::addInstanceToPool($obj, $key); + } + + return array($obj, $col); + } + + /** + * The returned array will contain objects of the default type or + * objects that inherit from the default. + * + * @param DataFetcherInterface $dataFetcher + * @return array + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function populateObjects(DataFetcherInterface $dataFetcher) + { + $results = array(); + + // set the class once to avoid overhead in the loop + $cls = static::getOMClass(false); + // populate the object(s) + while ($row = $dataFetcher->fetch()) { + $key = ProductImageTableMap::getPrimaryKeyHashFromRow($row, 0, $dataFetcher->getIndexType()); + if (null !== ($obj = ProductImageTableMap::getInstanceFromPool($key))) { + // We no longer rehydrate the object, since this can cause data loss. + // See http://www.propelorm.org/ticket/509 + // $obj->hydrate($row, 0, true); // rehydrate + $results[] = $obj; + } else { + $obj = new $cls(); + $obj->hydrate($row); + $results[] = $obj; + ProductImageTableMap::addInstanceToPool($obj, $key); + } // if key exists + } + + return $results; + } + /** + * Add all the columns needed to create a new object. + * + * Note: any columns that were marked with lazyLoad="true" in the + * XML schema will not be added to the select list and only loaded + * on demand. + * + * @param Criteria $criteria object containing the columns to add. + * @param string $alias optional table alias + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function addSelectColumns(Criteria $criteria, $alias = null) + { + if (null === $alias) { + $criteria->addSelectColumn(ProductImageTableMap::ID); + $criteria->addSelectColumn(ProductImageTableMap::PRODUCT_ID); + $criteria->addSelectColumn(ProductImageTableMap::FILE); + $criteria->addSelectColumn(ProductImageTableMap::POSITION); + $criteria->addSelectColumn(ProductImageTableMap::CREATED_AT); + $criteria->addSelectColumn(ProductImageTableMap::UPDATED_AT); + } else { + $criteria->addSelectColumn($alias . '.ID'); + $criteria->addSelectColumn($alias . '.PRODUCT_ID'); + $criteria->addSelectColumn($alias . '.FILE'); + $criteria->addSelectColumn($alias . '.POSITION'); + $criteria->addSelectColumn($alias . '.CREATED_AT'); + $criteria->addSelectColumn($alias . '.UPDATED_AT'); + } + } + + /** + * Returns the TableMap related to this object. + * This method is not needed for general use but a specific application could have a need. + * @return TableMap + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function getTableMap() + { + return Propel::getServiceContainer()->getDatabaseMap(ProductImageTableMap::DATABASE_NAME)->getTable(ProductImageTableMap::TABLE_NAME); + } + + /** + * Add a TableMap instance to the database for this tableMap class. + */ + public static function buildTableMap() + { + $dbMap = Propel::getServiceContainer()->getDatabaseMap(ProductImageTableMap::DATABASE_NAME); + if (!$dbMap->hasTable(ProductImageTableMap::TABLE_NAME)) { + $dbMap->addTableObject(new ProductImageTableMap()); + } + } + + /** + * Performs a DELETE on the database, given a ProductImage or Criteria object OR a primary key value. + * + * @param mixed $values Criteria or ProductImage object or primary key or array of primary keys + * which is used to create the DELETE statement + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows + * if supported by native driver or if emulated using Propel. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doDelete($values, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageTableMap::DATABASE_NAME); + } + + if ($values instanceof Criteria) { + // rename for clarity + $criteria = $values; + } elseif ($values instanceof \Thelia\Model\ProductImage) { // it's a model object + // create criteria based on pk values + $criteria = $values->buildPkeyCriteria(); + } else { // it's a primary key, or an array of pks + $criteria = new Criteria(ProductImageTableMap::DATABASE_NAME); + $criteria->add(ProductImageTableMap::ID, (array) $values, Criteria::IN); + } + + $query = ProductImageQuery::create()->mergeWith($criteria); + + if ($values instanceof Criteria) { ProductImageTableMap::clearInstancePool(); + } elseif (!is_object($values)) { // it's a primary key, or an array of pks + foreach ((array) $values as $singleval) { ProductImageTableMap::removeInstanceFromPool($singleval); + } + } + + return $query->delete($con); + } + + /** + * Deletes all rows from the product_image table. + * + * @param ConnectionInterface $con the connection to use + * @return int The number of affected rows (if supported by underlying database driver). + */ + public static function doDeleteAll(ConnectionInterface $con = null) + { + return ProductImageQuery::create()->doDeleteAll($con); + } + + /** + * Performs an INSERT on the database, given a ProductImage or Criteria object. + * + * @param mixed $criteria Criteria or ProductImage object containing data that is used to create the INSERT statement. + * @param ConnectionInterface $con the ConnectionInterface connection to use + * @return mixed The new primary key. + * @throws PropelException Any exceptions caught during processing will be + * rethrown wrapped into a PropelException. + */ + public static function doInsert($criteria, ConnectionInterface $con = null) + { + if (null === $con) { + $con = Propel::getServiceContainer()->getWriteConnection(ProductImageTableMap::DATABASE_NAME); + } + + if ($criteria instanceof Criteria) { + $criteria = clone $criteria; // rename for clarity + } else { + $criteria = $criteria->buildCriteria(); // build Criteria from ProductImage object + } + + if ($criteria->containsKey(ProductImageTableMap::ID) && $criteria->keyContainsValue(ProductImageTableMap::ID) ) { + throw new PropelException('Cannot insert a value for auto-increment primary key ('.ProductImageTableMap::ID.')'); + } + + + // Set the correct dbName + $query = ProductImageQuery::create()->mergeWith($criteria); + + try { + // use transaction because $criteria could contain info + // for more than one table (I guess, conceivably) + $con->beginTransaction(); + $pk = $query->doInsert($con); + $con->commit(); + } catch (PropelException $e) { + $con->rollBack(); + throw $e; + } + + return $pk; + } + +} // ProductImageTableMap +// This is the static code needed to register the TableMap for this table with the main Propel class. +// +ProductImageTableMap::buildTableMap(); diff --git a/core/lib/Thelia/Model/ProductImage.php b/core/lib/Thelia/Model/ProductImage.php new file mode 100644 index 000000000..9fe5b78e0 --- /dev/null +++ b/core/lib/Thelia/Model/ProductImage.php @@ -0,0 +1,10 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Tests\Action\ImageTest; + +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; +use Thelia\Core\HttpFoundation\Request; +use Thelia\Core\HttpFoundation\Session\Session; + +use Thelia\Action\Image; +use Thelia\Core\Event\ImageEvent; +use Thelia\Model\ConfigQuery; + +/** + * Class ImageTest + * + * @package Thelia\Tests\Action\ImageTest + */ +class ImageTest extends \PHPUnit_Framework_TestCase +{ + protected $request; + + protected $session; + + public function getContainer() + { + $container = new \Symfony\Component\DependencyInjection\ContainerBuilder(); + + $dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface"); + + $container->set("event_dispatcher", $dispatcher); + + return $container; + } + + public function setUp() + { + $this->session = new Session(new MockArraySessionStorage()); + $this->request = new Request(); + + $this->request->setSession($this->session); + + // mock cache configuration. + $config = ConfigQuery::create()->filterByName('image_cache_dir_from_web_root')->findOne(); + + if ($config != null) { + $this->cache_dir_from_web_root = $config->getValue(); + + $config->setValue(__DIR__."/assets/images/cache"); + + $config->setValue($this->cache_dir_from_web_root)->save(); + } + } + + public static function setUpBeforeClass() { + $dir = THELIA_WEB_DIR."/cache/tests"; + if ($dh = opendir($dir)) { + while ($file = readdir($dh)) { + if ($file == '.' || $file == '..') continue; + + unlink(sprintf("%s/%s", $dir, $file)); + } + } + } + + public function tearDown() { + // restore cache configuration. + $config = ConfigQuery::create()->filterByName('image_cache_dir_from_web_root')->findOne(); + + if ($config != null) { + $config->setValue($this->cache_dir_from_web_root)->save(); + } + } + + /** + * + * Imageevent is empty, mandatory parameters not specified. + * + * @expectedException \InvalidArgumentException + */ + public function testProcessEmptyImageEvent() + { + $event = new ImageEvent($this->request); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + /** + * + * Tru to process a non-existent file + * + * @expectedException \InvalidArgumentException + */ + public function testProcessNonExistentImage() + { + $event = new ImageEvent($this->request); + + $image = new Image($this->getContainer()); + + $event->setCacheFilepath("blablabla.png"); + $event->setCacheSubdirectory("tests"); + + $image->processImage($event); + } + + /** + * No operation done on source file -> copie ! + */ + public function testProcessImageWithoutAnyTransformationsCopy() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-1.png"); + $event->setCacheSubdirectory("tests"); + + $image = new Image($this->getContainer()); + + // mock cache configuration. + $config = ConfigQuery::create()->filterByName('original_image_delivery_mode')->findOne(); + + if ($config != null) { + $oldval = $config->getValue(); + $config->setValue('copy')->save(); + } + + $image->processImage($event); + + if ($config != null) $config->setValue($oldval)->save(); + + $this->assertFileExists(THELIA_WEB_DIR."/cache/tests/test-image-1.png"); + } + + /** + * No operation done on source file -> copie ! + */ + public function testProcessImageWithoutAnyTransformationsSymlink() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-9.png"); + $event->setCacheSubdirectory("tests"); + + $image = new Image($this->getContainer()); + + // mock cache configuration. + $config = ConfigQuery::create()->filterByName('original_image_delivery_mode')->findOne(); + + if ($config != null) { + $oldval = $config->getValue(); + $config->setValue('symlink')->save(); + } + + $image->processImage($event); + + if ($config != null) $config->setValue($oldval)->save(); + + $this->assertFileExists(THELIA_WEB_DIR."/cache/tests/test-image-9.png"); + } + + /** + * Resize image with bands width > height + */ + public function testProcessImageResizeHorizWithBands() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-2.png"); + $event->setCacheSubdirectory("tests"); + + $event->setBackgroundColor('#ff0000'); + $event->setWidth(100); + $event->setHeight(100); + $event->setResizeMode(Image::EXACT_RATIO_WITH_BORDERS); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + /** + * Resize image with bands height > width + */ + public function testProcessImageResizeVertWithBands() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-3.png"); + $event->setCacheSubdirectory("tests"); + + $event->setBackgroundColor('#ff0000'); + $event->setWidth(100); + $event->setHeight(100); + $event->setResizeMode(Image::EXACT_RATIO_WITH_BORDERS); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + + /** + * Apply all transformations + */ + public function testProcessImageWithTransformations() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-4.png"); + $event->setCacheSubdirectory("tests"); + + $event->setEffects(array("grayscale", "vertical_flip", "horizontal_flip", 'colorize:#00ff00', 'gamma: 0.2')); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + /** + * Resize image with crop width > height + */ + public function testProcessImageResizeHorizWithCrop() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-5.png"); + $event->setCacheSubdirectory("tests"); + + $event->setBackgroundColor('#ff0000'); + $event->setWidth(180); + $event->setHeight(100); + $event->setResizeMode(Image::EXACT_RATIO_WITH_CROP); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + /** + * Resize image with crop height > width + */ + public function testProcessImageResizeVertWithCrop() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-6.png"); + $event->setCacheSubdirectory("tests"); + + $event->setBackgroundColor('#ff0000'); + $event->setWidth(100); + $event->setHeight(150); + $event->setResizeMode(Image::EXACT_RATIO_WITH_CROP); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + /** + * Resize image keeping image ration + */ + public function testProcessImageResizeHorizKeepRatio() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-7.png"); + $event->setCacheSubdirectory("tests"); + + $event->setWidth(100); + $event->setHeight(100); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + + /** + * Resize image with crop height > width + */ + public function testProcessImageResizeVertKeepRatio() + { + $event = new ImageEvent($this->request); + + $event->setSourceFilepath(__DIR__."/assets/images/sources/test-image-8.png"); + $event->setCacheSubdirectory("tests"); + + $event->setWidth(100); + $event->setHeight(100); + + $image = new Image($this->getContainer()); + + $image->processImage($event); + } + +} \ No newline at end of file diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-1.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-1.png new file mode 100644 index 0000000000000000000000000000000000000000..84a6899a6b6433307f74a3f1e729dac610c22ed2 GIT binary patch literal 13736 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 literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-2.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-2.png new file mode 100644 index 0000000000000000000000000000000000000000..84a6899a6b6433307f74a3f1e729dac610c22ed2 GIT binary patch literal 13736 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 literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-3.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-3.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca361372b2061831e008e03e2e24365c9751515 GIT binary patch literal 11126 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 literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-4.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-4.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca361372b2061831e008e03e2e24365c9751515 GIT binary patch literal 11126 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 literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-5.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-5.png new file mode 100644 index 0000000000000000000000000000000000000000..23c14c7d067e92acbdb9aabf9ea096a5fcd24315 GIT binary patch literal 11052 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 UpFYO}GX4sXkyMnZ5i<(<9}JAKoB#j- literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-6.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-6.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca361372b2061831e008e03e2e24365c9751515 GIT binary patch literal 11126 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 literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-7.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-7.png new file mode 100644 index 0000000000000000000000000000000000000000..23c14c7d067e92acbdb9aabf9ea096a5fcd24315 GIT binary patch literal 11052 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 UpFYO}GX4sXkyMnZ5i<(<9}JAKoB#j- literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-8.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-8.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca361372b2061831e008e03e2e24365c9751515 GIT binary patch literal 11126 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 literal 0 HcmV?d00001 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-9.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-9.png new file mode 100644 index 0000000000000000000000000000000000000000..6ca361372b2061831e008e03e2e24365c9751515 GIT binary patch literal 11126 zcmV-+D~Z&JP)$C+-j*?}FH zbErE0QDoJ<#Uh*JkUb;e6&~iXo9rsqSLdF4&UX?ZBKi8L;^4l9;A^D5M(S&%KJi2M ziF^-H6vL57Boc|o6Uk&Eo68YG2mwL}A@ZIB)N9p`@@v%#`bWb4IVtz9Ac&nE9n+_# zDj^k(MweGsWAXT{8`lj610wqU`=LnKVzzX5xs66+V*x_Mqd>st^X>ZglZk{N2pS&( zAc$DJ8v=lcK;38YEg%F5fOK9>Y>^NkKtTQg`?`oM62fs%Nv1-f(2wrk&1AA2ZEXNR z2w7TLdG-1YA_9QR<-C34hRI}V6h_{yt+n-cp>S9fMfu(oM2Z*@L;?U3SOA2AiIxWf zNDzq1=t1UGK;ejl06~JFyq5j|0FVH1m5_S#b}5t2+`MtUueX;F5>F(SmX=#=whQOZ zg(Hy{FJHcT{pQmA#Se$+@aX8}%U6d-M_K{|1W|gx(*NnDLIHtH zCP|2t2T;HrQEQ#DNbT(IPEL$VFcCub_Yd;<{M_tpcXwBJcUL$P-rd{F=kq$9?nCs^ ztJiN<*VaT)EYUmEy-7DHD-k3bA0}$)0Ro`;nIgVGElL7}AP`a%G!^cZ_dZ1I?Cg|( z3Vs63OI`@7`TrT@~py0)P@mss{;B_+@du74MIfXk|^^ zPfFa6BG%HGX^E9Zul&={X$XHo{|iTfBd5z{vs$I!BvVO_=SvrGl}9uhySuOui^q%l zSb03uvO-167Qa0fWC4rnn-CgVNj(t+09n^TLAS}v5h;~TseJlhdPM`2J`(1(IgSg3 z!}2B=i9}sahxB7Ao!;E^*laed)lvsck!bYp!a^(-qx3QLgc<2TMk^N{e90m$+@S&= zA_9^Aqs|J-{#e*Q5m6F0<+=n_>R&o@1)1vZ>RMS@ZMEAS4#$hvuL*&{fdN9u`uq3G z%PWaQ;?n$l9WbR*sr&aI#9}e6J&6EfQ9YHhn-Cc-rrbNVei5P6B2Zn3*#`<@C!HM1 zYPK>+&CSl-TfD!pcwZ9Pp~1n{>{zL(Kx zY_ZwQW;4(8SiDaF2nIvZXjIxE;t!7l0hn$&oA7+@An@# zTJ2+_qjq}>B8J0}?VX*c&!30Gp-c1g)q@oX1bjZ9tRbM}w)Fn0O;1Nh$H?$-m8X8cu_1Z98tw%l9LHV1 za-|lSKwiJh(uI=&inXWSZ+iNAd*^0nX_yEh27}?^h4Xg1eRXZU%JU|ZN#FJkZORq| z0YEY)XJ=-*ySr-IMT=)BF)~gbsdOqeFfgDkdph0V;6OYcPo+}ToOfq;ub`n&<>wND z*zRhZnw+Scg<$m+V?&-8=Lvd!S?||mH01>$pBJh*@BaS2LWdBVEkYz@a&o-B%~bK) zprV<00_<=o6s|y(m`x_L`FMURo6SZd5!P8zd^@MZA=4E#Aw)A)sPJ|lLr-;dw6CtM z6-;6FI5<4?c)ae;&T1%^R5~3^B(&}o2qAsFJ@pGz(Paag)jWBmW~Wc(a=9P=_{U!F zRyLaz1VIplR4To+ymI&6g2AAlnLbsOI!`2tC@ShhSuBWzw6(Q;h<+;4pC2{i(ACv- z{o2(>Up=}1@FB->7PA=%Nu|=FDA=sl%aIIu(>m z@+#XQ!U>sEB{q6rZ?DVc@_4-d{e5ZkvfEpFy1R!42dnq{lF1ZHgv(Am>h$`0nRqA= z05q4TMUR{iQiKqT**tw}N)^MYah-^a0YyaecdN!d}EoVI}s~Er?RROiDWT= zqY7jYQ50>qmgE=MVR$Lq z0}z6MC%^jgg3#O3GdDYv%jY$|qlgBhp^l}gbK-B(B|Z0=_wRNv&G_cIvcW7 zfaU6nzpqoK6ssI%gR`Kh;NVlFWI3gPBB4a;% z?`y#Gu~;k?i>0w&)MmBH@wAU}a7_T}Pv^nNl!%Qnc=rzuc6WC z(a5Bz%&Sm;qQso3^dJNPQjBtyWNMJIxYOZSRAs`@NkYB7J(ZB^a=S%Q+}+y?1cJGI zPIV}JVeZ`H_4fAmT)T3)ac-JgUWzFx(t`s~@p0_^(~B2X znPy0I5yFHsUf zMD-qzz%Fjdw*fj1h!rfw;7f84`{Vo&Yn5Fc>jUoW-{go?)mpqsdP0dCp9DW_{r07B%=5pDx-st zjyh8cnsxN|^>uf5@9pgonm;H8u2ZR0I1)CSyBd$w)Z|1mnPN-ZlEp5L!_j|TDfN9V;Q0)F@?gbTsE7_ zH9@A9S60K}F!NYseii@`J3BghdwM=Kr1C#n-fE2nDI>O-yp-Oa%yf`61 z_$JAebcDj;wY7JFU?7o90;0`scXzapj*i+}T0Tvrj*bGQu_;MWnM|feQF>~mmRDC_ zym(0fT3TAVIy;eIC>&W?UEA37T)s44SH^vFk5D)qjznnBn0{exTzU+Hly__E#fw+% zZEa`Io@sNrBq}|h&-?fHpFVrOc>m$IzHz4^d1wthyk4(FffhJ*WHKRWebPwFb7ghS z*3xq8*3FLgb~)mp)9Lzpdq2B%lK^?6s&D<+M?8_(*z_n~F%vxn0MO*H8h}(V7@Qaz z(M)k`ZEYPL9y&Zcl50Reh2!<>H<@C^7g6z31l!x&>#hfp56(X-=V`GiAlNqGO$Hxzk z4j(>#tWrjaMB?G2N6AEDdUERHVib=j79Tu#^6VMQDPpk)Qvs~jmX_-35NKvk3rVvDo(Rt|*8zGt+&2AIF|T#7HEvvAMai=_z=;OuiveaoML& z&lwt>daaI(ilXT8Zmq4ahrIh!Hef#FkQWbR? zbh;u@r7kL}2eDl9z|y4Sw)VEqZ{2E!uc~A9QBn{EDVK)hIG)!LAfhNH5(z0yM#uBj zq~vqJY1}q-Z^aZBIrGqYctD57^J4BG>ib>_RfaK!}GdRQqBQPfMTUY#ouLU#*E%e2Z$;{f zNexCq0EUN#&YwMFXmXuVrHDf$5_$Uk`TqVvdwcuMYgcQmNe5Q*s#jw9u8T~J6BtC9 z!ZjqM#b!M{H#ayiK$?GOBPELB>iYWYH*ZBjID6*wNR zhNXb&^mKYpG?`2jW256^V}=tcSu4wVe)ZLpKrrZbyU(9H>!>}o4CPEtNexrNqDs*O zX72#)@*29s5YM%{+WY!?2L}cko}X9)Qi33?tggLXTGHwDS1w5wn8Mlj@Roxe$Q>SB z&-47JLC!QwrUHRLE|)J?@FZ3Ix?Ha2eVbf9pGYJ!=}bD4kw_J@*`(L&ZB}co9@Po? zeJ6Pcf)EG<{QCz-fj}e@$>;NeAYjpz;Q%;})A78?Z0=}pce^{=+u9ml$r-Bg28C)>FypG9_sAqI7un{I7lUv$>o(*x#gg;4=N6w+{K!9 z_Y|uN0Nif(>DigKlS-)k2uN*gZoYc`CYefsmc^u9;z)aul#$AD+|=a6%=EOb`J3a3 zB9+hQpFVs3esfc8S(TuJWqMm8kkU3TPM7Q2mCMae24IlNWV50uLRt5O@EljS_mE1Z z79Tu3JUWsaxD|`Cq`L=&2uIaQ)Q~k~@im)GS1(^_U>x)qr0(8ZI0^*hZ_IHV02EXS z0E(j9-Ff5MwK^`7NF?qpES5GRB5IZiv4j-Us=3l&I}HZI^{ZFAy4+1dig63#i39+& zx3{~TPM6Dth}mq`>2kVUPM6amief66s^c2jYk>&EpfmoF8VDXF2E61`9~{?hVFmHmiV71@A2^Rsc&nhKGheyLGF@Zl?yRs5=706N&d5o6STDMS6L)IbB`uPFX#nSljCJ zc)g4lLZ}u1NHv&8*&Qa~aQNQhV&XWkoKEMh8`sSy6RX*gHhnfco!2%;QN0hqC5$voToxj?8QCN>2Tb-apTy*Hh%y9m-p_8Md}&l zU8m?&U%qsyj$tNM$yA%mCBc-<<(8ILg252|ZmZp1eUhhdd#5l#jc%)g>J~lJq$;I6 zE*uWuU067F8FqEKXJ=;Q4lPg|yCa)sJ3Bi~*XY?y_Vt@LN0Jd#*P&4ZOkts{Xt|*T zqs|~44&Pf?j2~ydO^lD(?RKh_i`&M?Tw~$CCD_pC$yT_o@s|;G%_X&oYjFhq) z)pdj;QPv_ajQRqCI-O4P_(z6^FJHV+?8kykB^9+Zh9i-?_ZBKhR!fV`-fCxLirOoJ zjdKIFkusZ1*RNge?dh&}^~KBCs3xPawb*2RWO#VK09Lu@RWKdyF5a)8v)T(22C;PR zSUQ_&E>gK%&TKLTgP|>-@9^lT)&kW`I#bTbw_2@qTyu0}Wd7m>wV74|T{slFcfYL8 zVlrRZQ{{7c?J2Jx?)RnBnOCo0dAEFp@=ySRXf~UtrY6TnM{9}V6&hEw6eVyaXBZtB zAq2j9@&siY0%e}BsPF;8;mDT@i??syu$Ba73b{&j10ky9p;1u@2B~B+_2avDBax`1 z)!yIVZ@1flkYFg}^ZA}Xe-Q`-uU)xZ-GzY~3ae^;r}630kzoMx=&L6R8&zOsP;S&h z2#JIvckeCSzIj6x#VS11l4*578aawa)qC-6BoaAu`ZV2ezrVk4c4qqJt5>UQ>m6-v z6BFad;{+5}$$*9Voc2N<86HN&ubw=U!dcV^UZ%HaI2?ZX_^TV&uF@oRGMOaBu7FT9 z*`Y3%zFIxC2D))zB>?|e2nxRaQ z5dZ%Em-iMnHa4l;Pxa9DW>rG=_V%u>uKBjNHOZ#!ot@t9ss=Tg&1Q$gfs8Mw_!+@q z$h);w`3$2YBNs1Rkk+7Tx1|&Q_V)I+cXp_KkCAta+0tTbX$n$vvomJ1d13LvAAbJ_ zyL)@mF9ktZxPSk_!$%g2rOIhfgpl5z?y^I75#KJaq|?V(&qbZ3a8I(>sFM8)tb7Sy z=i!ht|gMk<+1_4f9B@%iV~M~C`)dyOU&FjA$&>|)XA zlV{J4^(~uK3`Nf?ErUq*4beU{+XJ_~5=qMJ8 zaXfFeT6=rCySut-HB3fEhBrMPL1I2jzyieeckemi&YwGboMa6n!6#3iBGWO6O=^eY zwD#h&9UC2KYzC!TruO#_9zK4QNTxUdlgWgL>2#V9aJih9E?%g$1;CSM&(`0)uaw6^ z$i&2WHGOB_Z)|?`9e;zi&%^^hlE2G&iEk2f49HBx^6{^Z2Crd`|9-QC~c zx4Y-BmF^kn?>{v)Su8)(h!~EIjaAy~d@o6|=0dVMyVt-f4volbZ4%H{t4e!0#4*x2ZW^XKa(Bu7VvFI~J)EV2bhYwPWs zH<~&)i$Q8=Xwc{Lt*x(@!u0ah>tHDOA*nVz&tJWKslTt65F8&HyZ8Yx(T+4Bq_xF% zvxEq3_@T~-{qpX;Kp^1m>>L>Aw_2=-7*8bLZ)}9a;ohE}8`rOWATgH7WVUy9h6V>4 zrA@qBTdnq1hok9T+trq5I-Pm>>XpaqrHK)}!7w>KJ~cV<>34!VIi#c`kw}Ik;Y1?A zah%O+b2=TLW-q~yhLk9Zl82yLVu)BMVk>z|^N7Y`;c%FPil3yj@=Cp3)o-9utBzxS zPc+^tnVZ5~LKH=-#iFV+VXTD32M>e6AkTBGzDEGyIW8{h?ZF_$aU8GH@s#tyb3Dg$sdPFT zi4er9r~9c!#!=H#DQS`$+5u5@4JdpFOXt_oW#6jGBRUg8`9NV76jYYO(&^1u(ejjM zhsixpBax`b>-BiO1kq}>^jFJ`u{FlPOt>m04pURz2|K-q6xmet&q9`659D2OoEuT*i1gFz^ z;q2M|{{EVn77e{!sxzUa^|YF$W4|mQL8|2oA!SEOva1J}CJltiqhwb!sJ~~$xmb4> z7Wek{j7Hg z*!uzjIQZ~+zd+4YL#pElT^Cwt1_-6fh?(_KkPA8hLll;(WVD~0CI`w@N&ukb3<=xh zQcFGT;hwd)l|Xy}9Xm_Wb$F z*RT6}dxr-H+*OaNlj2UAE0-%q2k3doOkBRyGLl~aK%rtwx+PBOTaD^ZtEvRq9Tw!} z41}(YE1UyGv2^VDG1ay4czk2i)ombDZNhjDfAadARkJQuWFQU;X$LvHX zD=a|}oKDB-xw+$?x;$E|m@tM#PJ%Jb3obsW#@NdVqD5B`0U1BJXeE?bwzB1|%tVH! zCYVOeSM67<#&Eta>Od7>3fN#`syK<9k(^2dc@% zMB4;yFid6jR6d{I+w*UFJ-fSmh}hZLDUG|Rp#cX?X(E*=jVucZDvww}mVupG!Tef- zf(muxsOT?d1*vENiZ!Cru#urmHSmJw$kc;}kG8hAd5#+$86F%QbUGY$#+tAk9j5V7 zP&s!<_p<~IjU%^GrJE5KIbdpY0MgJIdYnot5kibcgVk!YTCH`5Yqk357!M-)}YxDHKWSh=f;3;4O)7lf)hovjmYCTZyHMSh`8)dD1#ejE;sH zN%bO?NG2n(7|)VeNPq*dS*>{?Z*E+{j&lC+JKXpk-1!miERbA8+d7i0C~G%#-++N{ za3kL#=FX3~`f~X^R;*|Nj%y(Cg#Jh3%m0L%ze{p4qMFu;6|G2f7dP=UaQbh7W8zOX z>r#art&0zT8Q*=6hyp2T?N++QF=mwvrP0pK{sMRL9}=VUq>+00>Qy8Xl{YxaASy^1 z5K$CePUqb0?1w6(SN~aj{Le}1sIaz6Go~ru5LBJsK+XGtYnr?HA7J2HC#t7*_xzDa z#AGrRo2g|H(P%UR2Lwqfoz7)*AC#DzjR=4I^SJ(7G?%Uo6Ych(R?3QOaR!%!-~F@P z)qlmE|NAG0R6d^@9vZrQX+EFNa~${J(W6Kt`pqxyNW0mUWg^lab_hTI+qipA?Yfmt$CBRVbi~vKtwY4pMepW`n5G7S9$;f*S_Nq7_CO)&HmF!U4L{I7^_eqDU} zZ%HnqZG}l-CHBQf|BV0UZ#2=K@@{QeEEc(`W-gZ#5#<4`{{8)2F4td6$*TCrKPSHV zFJ<>E35<*Xh@1Z$v`ZE7)1k{{{b@?-OWFb?x1Sg-|FY z4LSz^p63NYK$)dQba!@Mt|E81fYj1|C%FW(&9l}vcl+1sfr${Jv+&>it{~=c=ug4uPpXX%8M4GS9z1Q1jb37uS8l*k z-V=_I;1cttDcc%aN4c@T*svRz`YRf>B66f==k7@$MF>fzlGOfNZQo%`>|$_LyV3;+ zjQ%7sG_2hU41Al|1~t5Eso&#a^JU7vzmJ3jLm`u z$ErGOd|R!{W%)9>NZaWKThH!!T>h?_2Wa5zi=40=O%SJ&CI zXSTO@UcG+3>-Q7H!GVFX>PCEHe7kI}32y;&M}v_vw=)leem1!T=Hk$BnVO!OvfJ$z zi&<_jH+^bqWOz89i0gRXZnsxkS}W$tk#L|h6QiTSZa&SUt0e>41!-*hiNX{rCr2i)gBTpppvaACCS>Bvdkc|h)ah{a_x0JVRstj% zje56y&tJX_1cTSEUa2iL0k!I68+~AKiIf&nNt_pNQZqRXLF(<&QX~>Rb9(mF)D(@# z^r=%XUcOpeU+?H>pBNvnNvuk(gvKMayTDwF7G84)u{37>6QiL$Uf)1}|MaO-D#77- z{`|SKE|=^5hNo7HlwvDricI0bGdy_4=yLjDI2tx}hCxaY@_l_h+BXi+-`^LDSJnBH zmY`-wsB!&&6Cue&A}Bi!x~?_qLTZg(sq?8$CyG^hf}q-oXiEnhtD%;~rT<2>s!|Ji z;=Q+;B2&P@!9m&1r+)vw*<`Aw{US2HB0ChOp{q~)>R*slP{WCl9#Z#Ja85M^sh;lc z)wN2UPy2d%t2Gp$9C(d`>BX<%+HVn+9;7bEjsAs3ZG7t0cV=!b6bdaY-gh`0bF;I3 zy*-2wK@c81eB|5Sw%M$uZLTYW1**}7*f7Y%<=+q&{$5#Igb>m)P$%_VjZC$+wtjKv z&gjT+I2;ZJ14T72#N&znzP`_H->!8o9+HwR@55K0m=~Y?Yw?GFlVF}PK7jd;oBIXQ zPzO`3zin3QrTO^_=g-TU+h8#KnQwoyUX@GK5r+>{;YY8;2fu`yzo%_I$*DrlNpAXY zGlo4{3UH?uzcbjqqZq$xO5Fd*A?zYQ?jVoyaYk)?C6*| zRcP%UkH^E&$mwFbVk8=k$6_C(s*tijRky9F@>TC@CZW;!4Q(^rxBh2C7|vrgI@^+m z9SDgi)~S=RM7}^v=t^@jN`*@^#YOr>+YI;Tej8fHNOKNdsdA`bF*d-B)9lz?0TEIj zHQEpFxyFC{H%ZGt^BhcF4Z5a2QDX0~Fsu*C2pUvWRhnYR@!Z@maM%A$_1Q9wM@kCr zE170kBW_TJ1=W1Fbgx9#sYVT1gSI*D>aW7^pC`>f7^L(DBh4kaJ3HuVQN3QTtEqfV zwKqYVO-f<)C3_T1Ss)fPmcsBQ1i3K&?I z5H#S>*egwK&^6DE|795YPUB-d)gx88fT)I+o`x1;uq%oKHFPr)t!Rx(vN#TO7NWBf z#~8S#pz|VhoFgrRi_@% literal 0 HcmV?d00001 From 7bd14d5aabcf7c0578ca43abb2125ff3baf17d3e Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 11:52:02 +0200 Subject: [PATCH 06/11] Re-added database.yml.sample --- local/config/database.yml.sample | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 local/config/database.yml.sample diff --git a/local/config/database.yml.sample b/local/config/database.yml.sample new file mode 100644 index 000000000..e1afbf005 --- /dev/null +++ b/local/config/database.yml.sample @@ -0,0 +1,6 @@ +database: + connection: + driver: %DRIVER% + user: %USERNAME% + password: %PASSWORD% + dsn: %DSN% \ No newline at end of file From 56034e1184a30f4882beb20b411e81d532bfed79 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 12:12:54 +0200 Subject: [PATCH 07/11] Fixed image test --- core/lib/Thelia/Tests/Action/ImageTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/lib/Thelia/Tests/Action/ImageTest.php b/core/lib/Thelia/Tests/Action/ImageTest.php index ce5e72a9c..2b7510449 100644 --- a/core/lib/Thelia/Tests/Action/ImageTest.php +++ b/core/lib/Thelia/Tests/Action/ImageTest.php @@ -76,12 +76,14 @@ class ImageTest extends \PHPUnit_Framework_TestCase public static function setUpBeforeClass() { $dir = THELIA_WEB_DIR."/cache/tests"; - if ($dh = opendir($dir)) { + if ($dh = @opendir($dir)) { while ($file = readdir($dh)) { if ($file == '.' || $file == '..') continue; unlink(sprintf("%s/%s", $dir, $file)); } + + closedir($dir); } } From 5762711146a8aa2200d56595d03045d44c74320e Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 12:27:30 +0200 Subject: [PATCH 08/11] Added original file data --- core/lib/Thelia/Action/Image.php | 29 ++++++---- core/lib/Thelia/Core/Event/ImageEvent.php | 54 ++++++++++++------ core/lib/Thelia/Tests/Action/ImageTest.php | 2 +- .../assets/images/sources/test-image-2.png | Bin 13736 -> 6010 bytes .../assets/images/sources/test-image-3.png | Bin 11126 -> 6568 bytes .../assets/images/sources/test-image-4.png | Bin 11126 -> 9154 bytes .../assets/images/sources/test-image-5.png | Bin 11052 -> 17175 bytes .../assets/images/sources/test-image-6.png | Bin 11126 -> 14973 bytes .../assets/images/sources/test-image-7.png | Bin 11052 -> 5651 bytes .../assets/images/sources/test-image-8.png | Bin 11126 -> 5811 bytes 10 files changed, 57 insertions(+), 28 deletions(-) diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 86003064b..353f9d9c3 100644 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -81,30 +81,33 @@ class Image extends BaseAction implements EventSubscriberInterface // Find cached file path $cacheFilePath = $this->getCacheFilePath($subdir, $source_file, $event); + $originalImagePathInCache = $this->getCacheFilePath($subdir, $source_file, $event, true); + if (! file_exists($cacheFilePath)) { - // If the original image is required, either create a copy of make a symbolic link, - // depending of the current configuration - if ($event->isOriginalImage()) { + // Create a chached version of the original image in the web space, if not exists + if (! file_exists($originalImagePathInCache)) { $mode = ConfigQuery::read('original_image_delivery_mode', 'symlink'); if ($mode == 'symlink') { - if (false == @symlink($source_file, $cacheFilePath)) { + if (false == @symlink($source_file, $originalImagePathInCache)) { $error_message = sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir); Tlog::getInstance()->addError($error_message); throw new ImageException($error_message); } } else {// mode = 'copy' - if (false == @copy($source_file, $cacheFilePath)) { + if (false == @copy($source_file, $originalImagePathInCache)) { $error_message = sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir); Tlog::getInstance()->addError($error_message); throw new ImageException($error_message); } } } - else { + + // Process image only if we have some transformations to do. + if (! $event->isOriginalImage()) { // We have to process the image. $imagine = $this->createImagineInstance(); @@ -195,12 +198,17 @@ class Image extends BaseAction implements EventSubscriberInterface } // Compute the image URL - $image_url = $this->getCacheFileURL($subdir, basename($cacheFilePath)); + $processed_image_url = $this->getCacheFileURL($subdir, basename($cacheFilePath)); + + // compute the full resulution image path in cache + $original_image_url = $this->getCacheFileURL($subdir, basename($originalImagePathInCache)); // Update the event with file path and file URL $event->setCacheFilepath($cacheFilePath); + $event->setCacheOriginalFilepath($originalImagePathInCache); - $event->setFileUrl(URL::absoluteUrl($image_url)); + $event->setFileUrl(URL::absoluteUrl($processed_image_url)); + $event->setOriginalFileUrl(URL::absoluteUrl($original_image_url)); } /** @@ -320,16 +328,17 @@ class Image extends BaseAction implements EventSubscriberInterface * * @param string $subdir the subdirectory related to cache base * @param string $filename the filename + * @param boolean $forceOriginalImage if true, the origiunal image path in the cache dir is returned. * @return string the cache directory path relative to Web Root */ - protected function getCacheFilePath($subdir, $filename, ImageEvent $event) + protected function getCacheFilePath($subdir, $filename, ImageEvent $event, $forceOriginalImage = false) { $path = $this->getCachePath($subdir); $safe_filename = preg_replace("[^:alnum:\-\._]", "-", strtolower(basename($filename))); // Keep original safe name if no tranformations are applied - if ($event->isOriginalImage()) + if ($forceOriginalImage || $event->isOriginalImage()) return sprintf("%s/%s", $path, $safe_filename); else return sprintf("%s/%s-%s", $path, $event->getSignature(), $safe_filename); diff --git a/core/lib/Thelia/Core/Event/ImageEvent.php b/core/lib/Thelia/Core/Event/ImageEvent.php index bfca35fb9..f6421eb9f 100644 --- a/core/lib/Thelia/Core/Event/ImageEvent.php +++ b/core/lib/Thelia/Core/Event/ImageEvent.php @@ -46,6 +46,16 @@ class ImageEvent extends ActionEvent */ protected $cache_filepath = null; + /** + * @var string The absolute URL of the cached version of the original image (in the web space) + */ + protected $original_file_url = null; + + /** + * @var string The absolute path of the cached version of the original image file + */ + protected $cache_original_filepath = null; + /** * @var string The image category (i.e. the subdirectory in image cache) */ @@ -89,29 +99,20 @@ class ImageEvent extends ActionEvent /** * @return boolean true if the required image is the original image */ - public function isOriginalImage() { - return - empty($this->width) - && empty($this->height) - && empty($this->resize_mode) - && empty($this->background_color) - && empty($this->effects) - && empty($this->rotation) - ; + public function isOriginalImage() + { + return empty($this->width) && empty($this->height) && empty($this->resize_mode) && empty($this->background_color) + && empty($this->effects) && empty($this->rotation); } /** * @return string a hash identifiying the processing options */ - public function getSignature() { + public function getSignature() + { return md5( - $this->width - . $this->height - . $this->resize_mode - . $this->background_color - . implode(',', $this->effects) - . $this->rotation - ); + $this->width . $this->height . $this->resize_mode . $this->background_color . implode(',', $this->effects) + . $this->rotation); } public function getCategory() @@ -234,4 +235,23 @@ class ImageEvent extends ActionEvent $this->quality = $quality; } + public function getOriginalFileUrl() + { + return $this->original_file_url; + } + + public function setOriginalFileUrl($original_file_url) + { + $this->original_file_url = $original_file_url; + } + + public function getCacheOriginalFilepath() + { + return $this->cache_original_filepath; + } + + public function setCacheOriginalFilepath($cache_original_filepath) + { + $this->cache_original_filepath = $cache_original_filepath; + } } diff --git a/core/lib/Thelia/Tests/Action/ImageTest.php b/core/lib/Thelia/Tests/Action/ImageTest.php index 2b7510449..fa25672d7 100644 --- a/core/lib/Thelia/Tests/Action/ImageTest.php +++ b/core/lib/Thelia/Tests/Action/ImageTest.php @@ -83,7 +83,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase unlink(sprintf("%s/%s", $dir, $file)); } - closedir($dir); + closedir($dh); } } diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-2.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-2.png index 84a6899a6b6433307f74a3f1e729dac610c22ed2..f6b7f9a53a381f9dcd98b98fceff0db7b1f47ac9 100644 GIT binary patch literal 6010 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 literal 13736 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 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-3.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-3.png index 6ca361372b2061831e008e03e2e24365c9751515..51d05ea159470c5864dc55a82dae670f2778b9bb 100644 GIT binary patch literal 6568 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 a67v7G!Y5RS{6O;n0000$C+-j*?}FH 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 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-4.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-4.png index 6ca361372b2061831e008e03e2e24365c9751515..c6d5d3834a168b84c1986deb1dcac96463ec593e 100644 GIT binary patch literal 9154 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 M07*qoM6N<$f^U$4tN;K2 literal 11126 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 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-5.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-5.png index 23c14c7d067e92acbdb9aabf9ea096a5fcd24315..a933abd266c5a436f71625ac6eef03ec38702d4c 100644 GIT binary patch literal 17175 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 UpFYO}GX4sXkyMnZ5i<(<9}JAKoB#j- diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-6.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-6.png index 6ca361372b2061831e008e03e2e24365c9751515..e7d6b950b3f4c54463a0d7fa017c5757960fa441 100644 GIT binary patch literal 14973 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%0A*JWEbMK9z6OkD1u9UH37O#+S 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 diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-7.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-7.png index 23c14c7d067e92acbdb9aabf9ea096a5fcd24315..f46514478ef2fe41f1d678038275cb64c9c9efa5 100644 GIT binary patch literal 5651 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 literal 11052 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 UpFYO}GX4sXkyMnZ5i<(<9}JAKoB#j- diff --git a/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-8.png b/core/lib/Thelia/Tests/Action/assets/images/sources/test-image-8.png index 6ca361372b2061831e008e03e2e24365c9751515..8631b4e7862ed32f5b32abb64e1f7b4e2e976414 100644 GIT binary patch literal 5811 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 From d61eeef0d6279cac3c3a1d58b35e7a8450276607 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 20:47:05 +0200 Subject: [PATCH 09/11] Finalized images action and loop --- .gitignore | 2 + core/lib/Thelia/Action/Image.php | 130 ++++++++--- core/lib/Thelia/Command/Install.php | 3 +- core/lib/Thelia/Config/Resources/action.xml | 5 + core/lib/Thelia/Config/Resources/config.xml | 1 + core/lib/Thelia/Core/Event/ImageEvent.php | 8 +- core/lib/Thelia/Core/Template/Loop/Image.php | 214 +++++++++++++----- .../Smarty/Assets/SmartyAssetsManager.php | 2 +- core/lib/Thelia/Exception/ImageException.php | 8 + core/lib/Thelia/Model/Base/Currency.php | 86 +++++-- core/lib/Thelia/Model/Base/CurrencyQuery.php | 47 +++- core/lib/Thelia/Model/Base/Lang.php | 86 +++++-- core/lib/Thelia/Model/Base/LangQuery.php | 47 +++- .../lib/Thelia/Model/Map/CurrencyTableMap.php | 36 +-- core/lib/Thelia/Model/Map/LangTableMap.php | 36 +-- core/lib/Thelia/Tests/Action/ImageTest.php | 53 ++++- core/lib/Thelia/Tools/URL.php | 18 +- install/INSTALL-TODO.txt | 5 +- install/faker.php | 79 ++++++- install/insert.sql | 2 +- install/thelia.sql | 2 + local/config/schema.xml | 4 +- local/media/.gitkeep | 0 templates/default/images.html | 104 +++++++++ 24 files changed, 812 insertions(+), 166 deletions(-) create mode 100644 local/media/.gitkeep create mode 100644 templates/default/images.html diff --git a/.gitignore b/.gitignore index 16709f59f..cad92f7a8 100755 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ coverage .project .settings/ local/cache/* +local/media/documents/* +local/media/images/* web/assets/* web/cache/* web/.htaccess diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index 353f9d9c3..dcf4390c5 100644 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -36,12 +36,37 @@ use Imagine\Image\Box; use Imagine\Image\Color; use Imagine\Image\Point; use Thelia\Exception\ImageException; -use Thelia\Log\Tlog; use Thelia\Core\Event\TheliaEvents; /** * - * Image management actions + * Image management actions. This class handles image processing an caching. + * + * Basically, images are stored outside the web space (by default in local/media/images), + * and cached in the web space (by default in web/local/images). + * + * In the images caches directory, a subdirectory for images categories (eg. product, category, folder, etc.) is + * automatically created, and the cached image is created here. Plugin may use their own subdirectory as required. + * + * The cached image name contains a hash of the processing options, and the original (normalized) name of the image. + * + * A copy (or symbolic link, by default) of the original image is always created in the cache, so that the full + * resolution image is always available. + * + * Various image processing options are available : + * + * - resizing, with border, crop, or by keeping image aspect ratio + * - rotation, in degrees, positive or negative + * - background color, applyed to empty background when creating borders or rotating + * - effects. The effects are applied in the specified order. The following effects are available: + * - gamma:value : change the image Gamma to the specified value. Example: gamma:0.7 + * - grayscale or greyscale: switch image to grayscale + * - colorize:color : apply a color mask to the image. Exemple: colorize:#ff2244 + * - negative : transform the image in its negative equivalent + * - vflip or vertical_flip : vertical flip + * - hflip or horizontal_flip : horizontal flip + * + * If a problem occurs, an ImageException may be thrown. * * @package Thelia\Action * @author Franck Allimant @@ -54,6 +79,42 @@ class Image extends BaseAction implements EventSubscriberInterface const EXACT_RATIO_WITH_CROP = 2; const KEEP_IMAGE_RATIO = 3; + /** + * Clear the image cache. Is a subdirectory is specified, only this directory is cleared. + * If no directory is specified, the whole cache is cleared. + * Only files are deleted, directories will remain. + * + * @param ImageEvent $event + */ + public function clearCache(ImageEvent $event) { + + $path = $this->getCachePath($event->getCacheSubdirectory(), false); + + $this->clearDirectory($path); + } + + /** + * Recursively clears the specified directory. + * + * @param string $path the directory path + */ + protected function clearDirectory($path) { + + $iterator = new \DirectoryIterator($path); + + foreach ($iterator as $fileinfo) { + + if ($fileinfo->isDot()) continue; + + if ($fileinfo->isFile() || $fileinfo->isLink()) { + @unlink($fileinfo->getPathname()); + } + else if ($fileinfo->isDir()) { + $this->clearDirectory($fileinfo->getPathname()); + } + } + } + /** * Process image and write the result in the image cache. * @@ -85,23 +146,24 @@ class Image extends BaseAction implements EventSubscriberInterface if (! file_exists($cacheFilePath)) { + if (! file_exists($source_file)) { + throw new ImageException(sprintf("Source image file %s does not exists.", $source_file)); + } + // Create a chached version of the original image in the web space, if not exists if (! file_exists($originalImagePathInCache)) { + $mode = ConfigQuery::read('original_image_delivery_mode', 'symlink'); if ($mode == 'symlink') { - if (false == @symlink($source_file, $originalImagePathInCache)) { - $error_message = sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir); - Tlog::getInstance()->addError($error_message); - throw new ImageException($error_message); + if (false == symlink($source_file, $originalImagePathInCache)) { + throw new ImageException(sprintf("Failed to create symbolic link for %s in %s image cache directory", basename($source_file), $subdir)); } } else {// mode = 'copy' if (false == @copy($source_file, $originalImagePathInCache)) { - $error_message = sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir); - Tlog::getInstance()->addError($error_message); - throw new ImageException($error_message); + throw new ImageException(sprintf("Failed to copy %s in %s image cache directory", basename($source_file), $subdir)); } } } @@ -191,11 +253,11 @@ class Image extends BaseAction implements EventSubscriberInterface array('quality' => $quality) ); } + else { + throw new ImageException(sprintf("Source file %s cannot be opened.", basename($source_file))); + } } } - else { - throw new ImageException(sprintf("Source file %s cannot be opened.", basename($source_file))); - } // Compute the image URL $processed_image_url = $this->getCacheFileURL($subdir, basename($cacheFilePath)); @@ -207,8 +269,8 @@ class Image extends BaseAction implements EventSubscriberInterface $event->setCacheFilepath($cacheFilePath); $event->setCacheOriginalFilepath($originalImagePathInCache); - $event->setFileUrl(URL::absoluteUrl($processed_image_url)); - $event->setOriginalFileUrl(URL::absoluteUrl($original_image_url)); + $event->setFileUrl(URL::absoluteUrl($processed_image_url, null, URL::PATH_TO_FILE)); + $event->setOriginalFileUrl(URL::absoluteUrl($original_image_url, null, URL::PATH_TO_FILE)); } /** @@ -320,7 +382,7 @@ class Image extends BaseAction implements EventSubscriberInterface { $path = $this->getCachePathFromWebRoot($subdir); - return URL::absoluteUrl(sprintf("%s/%s", $path, $safe_filename)); + return URL::absoluteUrl(sprintf("%s/%s", $path, $safe_filename), null, URL::PATH_TO_FILE); } /** @@ -341,22 +403,28 @@ class Image extends BaseAction implements EventSubscriberInterface if ($forceOriginalImage || $event->isOriginalImage()) return sprintf("%s/%s", $path, $safe_filename); else - return sprintf("%s/%s-%s", $path, $event->getSignature(), $safe_filename); + return sprintf("%s/%s-%s", $path, $event->getOptionsHash(), $safe_filename); } /** * Return the cache directory path relative to Web Root * - * @param string $subdir the subdirectory related to cache base + * @param string $subdir the subdirectory related to cache base, or null to get the cache directory only. * @return string the cache directory path relative to Web Root */ - protected function getCachePathFromWebRoot($subdir) + protected function getCachePathFromWebRoot($subdir = null) { - $safe_subdir = basename($subdir); - $cache_dir_from_web_root = ConfigQuery::read('image_cache_dir_from_web_root', 'cache'); - $path = sprintf("%s/%s", $cache_dir_from_web_root, $safe_subdir); + if ($subdir != null) { + $safe_subdir = basename($subdir); + + $path = sprintf("%s/%s", $cache_dir_from_web_root, $safe_subdir); + } + else + $path = $cache_dir_from_web_root; + + // Check if path is valid, e.g. in the cache dir return $path; } @@ -364,11 +432,11 @@ class Image extends BaseAction implements EventSubscriberInterface /** * Return the absolute cache directory path * - * @param string $subdir the subdirectory related to cache base + * @param string $subdir the subdirectory related to cache base, or null to get the cache base directory. * @throws \RuntimeException if cache directory cannot be created * @return string the absolute cache directory path */ - protected function getCachePath($subdir) + protected function getCachePath($subdir = null, $create_if_not_exists = true) { $cache_base = $this->getCachePathFromWebRoot($subdir); @@ -377,15 +445,19 @@ class Image extends BaseAction implements EventSubscriberInterface $path = sprintf("%s/%s", $web_root, $cache_base); // Create directory (recursively) if it does not exists. - if (!is_dir($path)) { + if ($create_if_not_exists && !is_dir($path)) { if (!@mkdir($path, 0777, true)) { - $error_message = sprintf("Failed to create %s/%s image cache directory", $cache_base); - Tlog::getInstance()->addError($error_message); - - throw new ImageException($error_message); + throw new ImageException(sprintf("Failed to create %s/%s image cache directory", $cache_base)); } } + // Check if path is valid, e.g. in the cache dir + $cache_base = realpath(sprintf("%s/%s", $web_root, $this->getCachePathFromWebRoot())); + + if (strpos(realpath($path), $cache_base) !== 0) { + throw new \InvalidArgumentException(sprintf("Invalid cache path %s, with subdirectory %s", $path, $subdir)); + } + return $path; } @@ -396,7 +468,7 @@ class Image extends BaseAction implements EventSubscriberInterface */ protected function createImagineInstance() { - $driver = ConfigQuery::read("imagine_driver", "gd"); + $driver = ConfigQuery::read("imagine_graphic_driver", "gd"); switch ($driver) { case 'imagik': diff --git a/core/lib/Thelia/Command/Install.php b/core/lib/Thelia/Command/Install.php index c151c44b7..edf459086 100755 --- a/core/lib/Thelia/Command/Install.php +++ b/core/lib/Thelia/Command/Install.php @@ -189,7 +189,8 @@ class Install extends ContainerAwareCommand file_put_contents($configFile, $configContent); - $fs->remove($sampleConfigFile); + // FA - no, as no further install will be possible + // $fs->remove($sampleConfigFile); $fs->remove($this->getContainer()->getParameter("kernel.cache_dir")); diff --git a/core/lib/Thelia/Config/Resources/action.xml b/core/lib/Thelia/Config/Resources/action.xml index 988c86ce9..f773b4cd7 100755 --- a/core/lib/Thelia/Config/Resources/action.xml +++ b/core/lib/Thelia/Config/Resources/action.xml @@ -27,6 +27,11 @@ + + + + + diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 98017f979..8181c60fc 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -25,6 +25,7 @@ + diff --git a/core/lib/Thelia/Core/Event/ImageEvent.php b/core/lib/Thelia/Core/Event/ImageEvent.php index f6421eb9f..a105d9f6f 100644 --- a/core/lib/Thelia/Core/Event/ImageEvent.php +++ b/core/lib/Thelia/Core/Event/ImageEvent.php @@ -97,18 +97,18 @@ class ImageEvent extends ActionEvent protected $quality = null; /** - * @return boolean true if the required image is the original image + * @return boolean true if the required image is the original image (resize_mode and background_color are not significant) */ public function isOriginalImage() { - return empty($this->width) && empty($this->height) && empty($this->resize_mode) && empty($this->background_color) - && empty($this->effects) && empty($this->rotation); + return empty($this->width) && empty($this->height) /* && empty($this->resize_mode) && empty($this->background_color) not significant */ + && empty($this->effects) && empty($this->rotation) && empty($this->quality); } /** * @return string a hash identifiying the processing options */ - public function getSignature() + public function getOptionsHash() { return md5( $this->width . $this->height . $this->resize_mode . $this->background_color . implode(',', $this->effects) diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index 4414e0e4e..e7a7ddca4 100644 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -28,6 +28,15 @@ use Thelia\Core\Event\ImageEvent; use Thelia\Model\CategoryImageQuery; use Thelia\Model\ProductImageQuery; use Thelia\Core\Event\TheliaEvents; +use Thelia\Core\Template\Loop\Argument\ArgumentCollection; +use Thelia\Type\TypeCollection; +use Thelia\Type\EnumListType; +use Propel\Runtime\ActiveQuery\Criteria; +use Thelia\Model\ConfigQuery; +use Thelia\Core\Template\Element\LoopResultRow; +use Thelia\Core\Template\Element\LoopResult; +use Thelia\Type\EnumType; +use Thelia\Log\Tlog; /** * The image loop @@ -44,61 +53,101 @@ class Image extends BaseLoop /** * Dynamically create the search query, and set the proper filter and order * + * @param string $source a valid source identifier (@see $possible_sources) + * @param int $object_id the source object ID * @return ModelCriteria the propel Query object */ - protected function getSearchQuery() { + protected function createSearchQuery($source, $object_id) { + + $object = ucfirst($source); + + $queryClass = sprintf("\Thelia\Model\%sImageQuery", $object); + $filterMethod = sprintf("filterBy%sId", $object); + $mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object); + + // xxxImageQuery::create() + $method = new \ReflectionMethod($queryClass, 'create'); + $search = $method->invoke(null); // Static ! + + // $query->filterByXXX(id) + $method = new \ReflectionMethod($queryClass, $filterMethod); + $method->invoke($search, $object_id); + + $map = new \ReflectionClass($mapClass); + $title_map = $map->getConstant('TITLE'); + + $orders = $this->getOrder(); + + // Results ordering + foreach ($orders as $order) { + switch ($order) { + case "alpha": + $search->addAscendingOrderByColumn($title_map); + break; + case "alpha-reverse": + $search->addDescendingOrderByColumn($title_map); + break; + case "manual-reverse": + $search->orderByPosition(Criteria::DESC); + break; + case "manual": + $search->orderByPosition(Criteria::ASC); + break; + case "random": + $search->clearOrderByColumns(); + $search->addAscendingOrderByColumn('RAND()'); + break(2); + break; + } + } + + return $search; + } + + /** + * Dynamically create the search query, and set the proper filter and order + * + * @param string $object_type (returned) the a valid source identifier (@see $possible_sources) + * @param string $object_id (returned) the ID of the source object + * @return ModelCriteria the propel Query object + */ + protected function getSearchQuery(&$object_type, &$object_id) { $search = null; - foreach($this->possible_sources as $source) { + // Check form source="product" source_id="123" style arguments + $source = $this->getSource(); - $argValue = intval($this->getArgValue($source)); + if (! is_null($source)) { - if ($argValue > 0) { + $source_id = $this->getSourceId(); - $object = ucfirst($source); + // echo "source = ".$this->getSource().", id=".$id."
"; - $queryClass = sprintf("%sImageQuery", $object); - $filterMethod = sprintf("filterBy%s", $object); - $mapClass = sprintf("\Thelia\Model\Map\%sI18nTableMap", $object); + if (is_null($source_id)) { + throw new \InvalidArgumentException("'source_id' argument cannot be null if 'source' argument is specified."); + } - // xxxImageQuery::create() - $method = new \ReflectionMethod($queryClass, 'create'); - $search = $reflectionMethod->invoke(null); // Static ! + $search = $this->createSearchQuery($source, $source_id); - // $query->filterByXXX($id) - $method = new \ReflectionMethod($queryClass, $filterMethod); - $method->invoke($search, $argValue); + $object_type = $source; + $object_id = $source_id; + } + else { + // Check for product="id" folder="id", etc. style arguments + foreach($this->possible_sources as $source) { - $map = new \ReflectionClass($mapClass); - $title_map = $map->getConstant('TITLE'); + $argValue = intval($this->getArgValue($source)); - $orders = $this->getOrder(); + if ($argValue > 0) { - // Results ordering - foreach ($orders as $order) { - switch ($order) { - case "alpha": - $search->addAscendingOrderByColumn($title_map); - break; - case "alpha-reverse": - $search->addDescendingOrderByColumn($title_map); - break; - case "manual-reverse": - $search->orderByPosition(Criteria::DESC); - break; - case "manual": - $search->orderByPosition(Criteria::ASC); - break; - case "random": - $search->clearOrderByColumns(); - $search->addAscendingOrderByColumn('RAND()'); - break(2); - break; - } + $search = $this->createSearchQuery($source, $argValue); + + $object_type = $source; + $object_id = $argValue; + + break; } - - break; } } @@ -111,10 +160,12 @@ class Image extends BaseLoop /** * @param unknown $pagination */ - public function exec($pagination) + public function exec(&$pagination) { - // Select the proper query to use - $search = $this->getSearchQuery(); + // Select the proper query to use, and get the object type + $object_type = $object_id = null; + + $search = $this->getSearchQuery($object_type, $object_id); $id = $this->getId(); @@ -130,10 +181,8 @@ class Image extends BaseLoop $event = new ImageEvent($this->request); // Prepare tranformations - // Setup required transformations $width = $this->getWidth(); $height = $this->getHeight(); - $resize_mode = $this->getResizeMode(); $rotation = $this->getRotation(); $background_color = $this->getBackgroundColor(); $quality = $this->getQuality(); @@ -143,6 +192,21 @@ class Image extends BaseLoop $effects = explode(',', $effects); } + switch($this->getResizeMode()) { + case 'crop' : + $resize_mode = \Thelia\Action\Image::EXACT_RATIO_WITH_CROP; + break; + + case 'borders' : + $resize_mode = \Thelia\Action\Image::EXACT_RATIO_WITH_BORDERS; + break; + + case 'none' : + default: + $resize_mode = \Thelia\Action\Image::KEEP_IMAGE_RATIO; + + } + /** * \Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation. * @@ -165,25 +229,51 @@ class Image extends BaseLoop // Setup required transformations if (! is_null($width)) $event->setWidth($width); - if (! is_null($height)) $event->setHeigth($height); - if (! is_null($resize_mode)) $event->setResizeMode($resize_mode); + if (! is_null($height)) $event->setHeight($height); + $event->setResizeMode($resize_mode); if (! is_null($rotation)) $event->setRotation($rotation); if (! is_null($background_color)) $event->setBackgroundColor($background_color); if (! is_null($quality)) $event->setQuality($quality); if (! is_null($effects)) $event->setEffects($effects); - // Dispatch image processing event - $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event); + // Put source image file path + $source_filepath = sprintf("%s%s/%s/%s", + THELIA_ROOT, + ConfigQuery::read('documents_library_path', 'local/media/images'), + $object_type, + $result->getFile() + ); - $loopResultRow = new LoopResultRow(); + $event->setSourceFilepath($source_filepath); + $event->setCacheSubdirectory($object_type); - $loopResultRow - ->set("ID", $result->getId()) - ->set("IMAGE_URL", $event->getFileUrl()) - ->set("FILE_URL", $event-> - ; + try { + // Dispatch image processing event + $this->dispatcher->dispatch(TheliaEvents::IMAGE_PROCESS, $event); - $loopResult->addRow($loopResultRow); + $loopResultRow = new LoopResultRow(); + + $loopResultRow + ->set("ID", $result->getId()) + ->set("IMAGE_URL", $event->getFileUrl()) + ->set("ORIGINAL_IMAGE_URL", $event->getOriginalFileUrl()) + ->set("IMAGE_PATH", $event->getCacheFilepath()) + ->set("ORIGINAL_IMAGE_PATH", $source_filepath) + ->set("TITLE", $result->getTitle()) + ->set("CHAPO", $result->getChapo()) + ->set("DESCRIPTION", $result->getDescription()) + ->set("POSTSCRIPTUM", $result->getPostscriptum()) + ->set("POSITION", $result->getPosition()) + ->set("OBJECT_TYPE", $object_type) + ->set("OBJECT_ID", $object_id) + ; + + $loopResult->addRow($loopResultRow); + } + catch (\Exception $ex) { + // Ignore the result and log an error + Tlog::getInstance()->addError("Failed to process image in image loop: ", $this->args); + } } return $loopResult; @@ -200,6 +290,7 @@ class Image extends BaseLoop #IMAGE : URL de l'image transformée (redimensionnée, inversée, etc. suivant les paramètres d'entrée de la boucle). #FICHIER : URL de l'image originale #ID : identifiant de l'image + #TITRE : titre de l'image #CHAPO : description courte de l'image #DESCRIPTION : description longue de l'image @@ -219,7 +310,7 @@ class Image extends BaseLoop new Argument( 'order', new TypeCollection( - new Type\EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) + new EnumListType(array('alpha', 'alpha-reverse', 'manual', 'manual-reverse', 'random')) ), 'manual' ), @@ -232,7 +323,7 @@ class Image extends BaseLoop new Argument( 'resize_mode', new TypeCollection( - new Type\EnumListType(array('crop', 'borders', 'none')) + new EnumType(array('crop', 'borders', 'none')) ), 'none' ), @@ -246,16 +337,17 @@ class Image extends BaseLoop new Argument( 'source', new TypeCollection( - new Type\EnumListType($this->possible_sources) + new EnumType($this->possible_sources) ) ), + Argument::createIntTypeArgument('source_id'), Argument::createIntListTypeArgument('lang') ); // Add possible image sources - foreach($possible_sources as $source) { - $collection->addArgument(Argument::createIntTypeArgument($source)) + foreach($this->possible_sources as $source) { + $collection->addArgument(Argument::createIntTypeArgument($source)); } return $collection; diff --git a/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php b/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php index e3365be85..a07eba565 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php +++ b/core/lib/Thelia/Core/Template/Smarty/Assets/SmartyAssetsManager.php @@ -70,7 +70,7 @@ class SmartyAssetsManager $url = $this->assetic_manager->asseticize( $asset_dir.'/'.$asset_file, $this->web_root."/".$this->path_relative_to_web_root, - URL::absoluteUrl($this->path_relative_to_web_root, array(), true /* path only */), + URL::absoluteUrl($this->path_relative_to_web_root, null, URL::PATH_TO_FILE /* path only */), $assetType, $filters, $debug diff --git a/core/lib/Thelia/Exception/ImageException.php b/core/lib/Thelia/Exception/ImageException.php index 77d2a8ba5..60774dabf 100644 --- a/core/lib/Thelia/Exception/ImageException.php +++ b/core/lib/Thelia/Exception/ImageException.php @@ -23,6 +23,14 @@ namespace Thelia\Exception; +use Thelia\Log\Tlog; + class ImageException extends \RuntimeException { + public function __construct($message, $code = null, $previous = null) { + + Tlog::getInstance()->addError($message); + + parent::__construct($message, $code, $previous); + } } diff --git a/core/lib/Thelia/Model/Base/Currency.php b/core/lib/Thelia/Model/Base/Currency.php index 5ab40a742..77718992f 100644 --- a/core/lib/Thelia/Model/Base/Currency.php +++ b/core/lib/Thelia/Model/Base/Currency.php @@ -87,6 +87,12 @@ abstract class Currency implements ActiveRecordInterface */ protected $rate; + /** + * The value for the position field. + * @var int + */ + protected $position; + /** * The value for the by_default field. * @var int @@ -473,6 +479,17 @@ abstract class Currency implements ActiveRecordInterface return $this->rate; } + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + /** * Get the [by_default] column value. * @@ -608,6 +625,27 @@ abstract class Currency implements ActiveRecordInterface return $this; } // setRate() + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\Currency The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = CurrencyTableMap::POSITION; + } + + + return $this; + } // setPosition() + /** * Set the value of [by_default] column. * @@ -720,16 +758,19 @@ abstract class Currency implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 3 + $startcol : CurrencyTableMap::translateFieldName('Rate', TableMap::TYPE_PHPNAME, $indexType)]; $this->rate = (null !== $col) ? (double) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : CurrencyTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : CurrencyTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : CurrencyTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; $this->by_default = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : CurrencyTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CurrencyTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : CurrencyTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : CurrencyTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -742,7 +783,7 @@ abstract class Currency implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 7; // 7 = CurrencyTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 8; // 8 = CurrencyTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Currency object", 0, $e); @@ -1052,6 +1093,9 @@ abstract class Currency implements ActiveRecordInterface if ($this->isColumnModified(CurrencyTableMap::RATE)) { $modifiedColumns[':p' . $index++] = 'RATE'; } + if ($this->isColumnModified(CurrencyTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } if ($this->isColumnModified(CurrencyTableMap::BY_DEFAULT)) { $modifiedColumns[':p' . $index++] = 'BY_DEFAULT'; } @@ -1084,6 +1128,9 @@ abstract class Currency implements ActiveRecordInterface case 'RATE': $stmt->bindValue($identifier, $this->rate, PDO::PARAM_STR); break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; case 'BY_DEFAULT': $stmt->bindValue($identifier, $this->by_default, PDO::PARAM_INT); break; @@ -1168,12 +1215,15 @@ abstract class Currency implements ActiveRecordInterface return $this->getRate(); break; case 4: - return $this->getByDefault(); + return $this->getPosition(); break; case 5: - return $this->getCreatedAt(); + return $this->getByDefault(); break; case 6: + return $this->getCreatedAt(); + break; + case 7: return $this->getUpdatedAt(); break; default: @@ -1209,9 +1259,10 @@ abstract class Currency implements ActiveRecordInterface $keys[1] => $this->getCode(), $keys[2] => $this->getSymbol(), $keys[3] => $this->getRate(), - $keys[4] => $this->getByDefault(), - $keys[5] => $this->getCreatedAt(), - $keys[6] => $this->getUpdatedAt(), + $keys[4] => $this->getPosition(), + $keys[5] => $this->getByDefault(), + $keys[6] => $this->getCreatedAt(), + $keys[7] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1279,12 +1330,15 @@ abstract class Currency implements ActiveRecordInterface $this->setRate($value); break; case 4: - $this->setByDefault($value); + $this->setPosition($value); break; case 5: - $this->setCreatedAt($value); + $this->setByDefault($value); break; case 6: + $this->setCreatedAt($value); + break; + case 7: $this->setUpdatedAt($value); break; } // switch() @@ -1315,9 +1369,10 @@ abstract class Currency implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) $this->setCode($arr[$keys[1]]); if (array_key_exists($keys[2], $arr)) $this->setSymbol($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setRate($arr[$keys[3]]); - if (array_key_exists($keys[4], $arr)) $this->setByDefault($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setCreatedAt($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setUpdatedAt($arr[$keys[6]]); + if (array_key_exists($keys[4], $arr)) $this->setPosition($arr[$keys[4]]); + if (array_key_exists($keys[5], $arr)) $this->setByDefault($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); } /** @@ -1333,6 +1388,7 @@ abstract class Currency implements ActiveRecordInterface if ($this->isColumnModified(CurrencyTableMap::CODE)) $criteria->add(CurrencyTableMap::CODE, $this->code); if ($this->isColumnModified(CurrencyTableMap::SYMBOL)) $criteria->add(CurrencyTableMap::SYMBOL, $this->symbol); if ($this->isColumnModified(CurrencyTableMap::RATE)) $criteria->add(CurrencyTableMap::RATE, $this->rate); + if ($this->isColumnModified(CurrencyTableMap::POSITION)) $criteria->add(CurrencyTableMap::POSITION, $this->position); if ($this->isColumnModified(CurrencyTableMap::BY_DEFAULT)) $criteria->add(CurrencyTableMap::BY_DEFAULT, $this->by_default); if ($this->isColumnModified(CurrencyTableMap::CREATED_AT)) $criteria->add(CurrencyTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(CurrencyTableMap::UPDATED_AT)) $criteria->add(CurrencyTableMap::UPDATED_AT, $this->updated_at); @@ -1402,6 +1458,7 @@ abstract class Currency implements ActiveRecordInterface $copyObj->setCode($this->getCode()); $copyObj->setSymbol($this->getSymbol()); $copyObj->setRate($this->getRate()); + $copyObj->setPosition($this->getPosition()); $copyObj->setByDefault($this->getByDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -2578,6 +2635,7 @@ abstract class Currency implements ActiveRecordInterface $this->code = null; $this->symbol = null; $this->rate = null; + $this->position = null; $this->by_default = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/CurrencyQuery.php b/core/lib/Thelia/Model/Base/CurrencyQuery.php index 140b70463..eb4b1b2f7 100644 --- a/core/lib/Thelia/Model/Base/CurrencyQuery.php +++ b/core/lib/Thelia/Model/Base/CurrencyQuery.php @@ -26,6 +26,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method ChildCurrencyQuery orderByCode($order = Criteria::ASC) Order by the code column * @method ChildCurrencyQuery orderBySymbol($order = Criteria::ASC) Order by the symbol column * @method ChildCurrencyQuery orderByRate($order = Criteria::ASC) Order by the rate column + * @method ChildCurrencyQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildCurrencyQuery orderByByDefault($order = Criteria::ASC) Order by the by_default column * @method ChildCurrencyQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildCurrencyQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -34,6 +35,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method ChildCurrencyQuery groupByCode() Group by the code column * @method ChildCurrencyQuery groupBySymbol() Group by the symbol column * @method ChildCurrencyQuery groupByRate() Group by the rate column + * @method ChildCurrencyQuery groupByPosition() Group by the position column * @method ChildCurrencyQuery groupByByDefault() Group by the by_default column * @method ChildCurrencyQuery groupByCreatedAt() Group by the created_at column * @method ChildCurrencyQuery groupByUpdatedAt() Group by the updated_at column @@ -65,6 +67,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method ChildCurrency findOneByCode(string $code) Return the first ChildCurrency filtered by the code column * @method ChildCurrency findOneBySymbol(string $symbol) Return the first ChildCurrency filtered by the symbol column * @method ChildCurrency findOneByRate(double $rate) Return the first ChildCurrency filtered by the rate column + * @method ChildCurrency findOneByPosition(int $position) Return the first ChildCurrency filtered by the position column * @method ChildCurrency findOneByByDefault(int $by_default) Return the first ChildCurrency filtered by the by_default column * @method ChildCurrency findOneByCreatedAt(string $created_at) Return the first ChildCurrency filtered by the created_at column * @method ChildCurrency findOneByUpdatedAt(string $updated_at) Return the first ChildCurrency filtered by the updated_at column @@ -73,6 +76,7 @@ use Thelia\Model\Map\CurrencyTableMap; * @method array findByCode(string $code) Return ChildCurrency objects filtered by the code column * @method array findBySymbol(string $symbol) Return ChildCurrency objects filtered by the symbol column * @method array findByRate(double $rate) Return ChildCurrency objects filtered by the rate column + * @method array findByPosition(int $position) Return ChildCurrency objects filtered by the position column * @method array findByByDefault(int $by_default) Return ChildCurrency objects filtered by the by_default column * @method array findByCreatedAt(string $created_at) Return ChildCurrency objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildCurrency objects filtered by the updated_at column @@ -164,7 +168,7 @@ abstract class CurrencyQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, CODE, SYMBOL, RATE, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM currency WHERE ID = :p0'; + $sql = 'SELECT ID, CODE, SYMBOL, RATE, POSITION, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM currency WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -393,6 +397,47 @@ abstract class CurrencyQuery extends ModelCriteria return $this->addUsingAlias(CurrencyTableMap::RATE, $rate, $comparison); } + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildCurrencyQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(CurrencyTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(CurrencyTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(CurrencyTableMap::POSITION, $position, $comparison); + } + /** * Filter the query on the by_default column * diff --git a/core/lib/Thelia/Model/Base/Lang.php b/core/lib/Thelia/Model/Base/Lang.php index 694f86bc5..3379594ef 100644 --- a/core/lib/Thelia/Model/Base/Lang.php +++ b/core/lib/Thelia/Model/Base/Lang.php @@ -84,6 +84,12 @@ abstract class Lang implements ActiveRecordInterface */ protected $url; + /** + * The value for the position field. + * @var int + */ + protected $position; + /** * The value for the by_default field. * @var int @@ -419,6 +425,17 @@ abstract class Lang implements ActiveRecordInterface return $this->url; } + /** + * Get the [position] column value. + * + * @return int + */ + public function getPosition() + { + + return $this->position; + } + /** * Get the [by_default] column value. * @@ -575,6 +592,27 @@ abstract class Lang implements ActiveRecordInterface return $this; } // setUrl() + /** + * Set the value of [position] column. + * + * @param int $v new value + * @return \Thelia\Model\Lang The current object (for fluent API support) + */ + public function setPosition($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->position !== $v) { + $this->position = $v; + $this->modifiedColumns[] = LangTableMap::POSITION; + } + + + return $this; + } // setPosition() + /** * Set the value of [by_default] column. * @@ -690,16 +728,19 @@ abstract class Lang implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : LangTableMap::translateFieldName('Url', TableMap::TYPE_PHPNAME, $indexType)]; $this->url = (null !== $col) ? (string) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : LangTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : LangTableMap::translateFieldName('Position', TableMap::TYPE_PHPNAME, $indexType)]; + $this->position = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : LangTableMap::translateFieldName('ByDefault', TableMap::TYPE_PHPNAME, $indexType)]; $this->by_default = (null !== $col) ? (int) $col : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : LangTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : LangTableMap::translateFieldName('CreatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } $this->created_at = (null !== $col) ? PropelDateTime::newInstance($col, null, '\DateTime') : null; - $col = $row[TableMap::TYPE_NUM == $indexType ? 7 + $startcol : LangTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; + $col = $row[TableMap::TYPE_NUM == $indexType ? 8 + $startcol : LangTableMap::translateFieldName('UpdatedAt', TableMap::TYPE_PHPNAME, $indexType)]; if ($col === '0000-00-00 00:00:00') { $col = null; } @@ -712,7 +753,7 @@ abstract class Lang implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 8; // 8 = LangTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 9; // 9 = LangTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException("Error populating \Thelia\Model\Lang object", 0, $e); @@ -947,6 +988,9 @@ abstract class Lang implements ActiveRecordInterface if ($this->isColumnModified(LangTableMap::URL)) { $modifiedColumns[':p' . $index++] = 'URL'; } + if ($this->isColumnModified(LangTableMap::POSITION)) { + $modifiedColumns[':p' . $index++] = 'POSITION'; + } if ($this->isColumnModified(LangTableMap::BY_DEFAULT)) { $modifiedColumns[':p' . $index++] = 'BY_DEFAULT'; } @@ -982,6 +1026,9 @@ abstract class Lang implements ActiveRecordInterface case 'URL': $stmt->bindValue($identifier, $this->url, PDO::PARAM_STR); break; + case 'POSITION': + $stmt->bindValue($identifier, $this->position, PDO::PARAM_INT); + break; case 'BY_DEFAULT': $stmt->bindValue($identifier, $this->by_default, PDO::PARAM_INT); break; @@ -1069,12 +1116,15 @@ abstract class Lang implements ActiveRecordInterface return $this->getUrl(); break; case 5: - return $this->getByDefault(); + return $this->getPosition(); break; case 6: - return $this->getCreatedAt(); + return $this->getByDefault(); break; case 7: + return $this->getCreatedAt(); + break; + case 8: return $this->getUpdatedAt(); break; default: @@ -1110,9 +1160,10 @@ abstract class Lang implements ActiveRecordInterface $keys[2] => $this->getCode(), $keys[3] => $this->getLocale(), $keys[4] => $this->getUrl(), - $keys[5] => $this->getByDefault(), - $keys[6] => $this->getCreatedAt(), - $keys[7] => $this->getUpdatedAt(), + $keys[5] => $this->getPosition(), + $keys[6] => $this->getByDefault(), + $keys[7] => $this->getCreatedAt(), + $keys[8] => $this->getUpdatedAt(), ); $virtualColumns = $this->virtualColumns; foreach($virtualColumns as $key => $virtualColumn) @@ -1169,12 +1220,15 @@ abstract class Lang implements ActiveRecordInterface $this->setUrl($value); break; case 5: - $this->setByDefault($value); + $this->setPosition($value); break; case 6: - $this->setCreatedAt($value); + $this->setByDefault($value); break; case 7: + $this->setCreatedAt($value); + break; + case 8: $this->setUpdatedAt($value); break; } // switch() @@ -1206,9 +1260,10 @@ abstract class Lang implements ActiveRecordInterface if (array_key_exists($keys[2], $arr)) $this->setCode($arr[$keys[2]]); if (array_key_exists($keys[3], $arr)) $this->setLocale($arr[$keys[3]]); if (array_key_exists($keys[4], $arr)) $this->setUrl($arr[$keys[4]]); - if (array_key_exists($keys[5], $arr)) $this->setByDefault($arr[$keys[5]]); - if (array_key_exists($keys[6], $arr)) $this->setCreatedAt($arr[$keys[6]]); - if (array_key_exists($keys[7], $arr)) $this->setUpdatedAt($arr[$keys[7]]); + if (array_key_exists($keys[5], $arr)) $this->setPosition($arr[$keys[5]]); + if (array_key_exists($keys[6], $arr)) $this->setByDefault($arr[$keys[6]]); + if (array_key_exists($keys[7], $arr)) $this->setCreatedAt($arr[$keys[7]]); + if (array_key_exists($keys[8], $arr)) $this->setUpdatedAt($arr[$keys[8]]); } /** @@ -1225,6 +1280,7 @@ abstract class Lang implements ActiveRecordInterface if ($this->isColumnModified(LangTableMap::CODE)) $criteria->add(LangTableMap::CODE, $this->code); if ($this->isColumnModified(LangTableMap::LOCALE)) $criteria->add(LangTableMap::LOCALE, $this->locale); if ($this->isColumnModified(LangTableMap::URL)) $criteria->add(LangTableMap::URL, $this->url); + if ($this->isColumnModified(LangTableMap::POSITION)) $criteria->add(LangTableMap::POSITION, $this->position); if ($this->isColumnModified(LangTableMap::BY_DEFAULT)) $criteria->add(LangTableMap::BY_DEFAULT, $this->by_default); if ($this->isColumnModified(LangTableMap::CREATED_AT)) $criteria->add(LangTableMap::CREATED_AT, $this->created_at); if ($this->isColumnModified(LangTableMap::UPDATED_AT)) $criteria->add(LangTableMap::UPDATED_AT, $this->updated_at); @@ -1295,6 +1351,7 @@ abstract class Lang implements ActiveRecordInterface $copyObj->setCode($this->getCode()); $copyObj->setLocale($this->getLocale()); $copyObj->setUrl($this->getUrl()); + $copyObj->setPosition($this->getPosition()); $copyObj->setByDefault($this->getByDefault()); $copyObj->setCreatedAt($this->getCreatedAt()); $copyObj->setUpdatedAt($this->getUpdatedAt()); @@ -1336,6 +1393,7 @@ abstract class Lang implements ActiveRecordInterface $this->code = null; $this->locale = null; $this->url = null; + $this->position = null; $this->by_default = null; $this->created_at = null; $this->updated_at = null; diff --git a/core/lib/Thelia/Model/Base/LangQuery.php b/core/lib/Thelia/Model/Base/LangQuery.php index 1a99ff28a..a5100c5f8 100644 --- a/core/lib/Thelia/Model/Base/LangQuery.php +++ b/core/lib/Thelia/Model/Base/LangQuery.php @@ -23,6 +23,7 @@ use Thelia\Model\Map\LangTableMap; * @method ChildLangQuery orderByCode($order = Criteria::ASC) Order by the code column * @method ChildLangQuery orderByLocale($order = Criteria::ASC) Order by the locale column * @method ChildLangQuery orderByUrl($order = Criteria::ASC) Order by the url column + * @method ChildLangQuery orderByPosition($order = Criteria::ASC) Order by the position column * @method ChildLangQuery orderByByDefault($order = Criteria::ASC) Order by the by_default column * @method ChildLangQuery orderByCreatedAt($order = Criteria::ASC) Order by the created_at column * @method ChildLangQuery orderByUpdatedAt($order = Criteria::ASC) Order by the updated_at column @@ -32,6 +33,7 @@ use Thelia\Model\Map\LangTableMap; * @method ChildLangQuery groupByCode() Group by the code column * @method ChildLangQuery groupByLocale() Group by the locale column * @method ChildLangQuery groupByUrl() Group by the url column + * @method ChildLangQuery groupByPosition() Group by the position column * @method ChildLangQuery groupByByDefault() Group by the by_default column * @method ChildLangQuery groupByCreatedAt() Group by the created_at column * @method ChildLangQuery groupByUpdatedAt() Group by the updated_at column @@ -48,6 +50,7 @@ use Thelia\Model\Map\LangTableMap; * @method ChildLang findOneByCode(string $code) Return the first ChildLang filtered by the code column * @method ChildLang findOneByLocale(string $locale) Return the first ChildLang filtered by the locale column * @method ChildLang findOneByUrl(string $url) Return the first ChildLang filtered by the url column + * @method ChildLang findOneByPosition(int $position) Return the first ChildLang filtered by the position column * @method ChildLang findOneByByDefault(int $by_default) Return the first ChildLang filtered by the by_default column * @method ChildLang findOneByCreatedAt(string $created_at) Return the first ChildLang filtered by the created_at column * @method ChildLang findOneByUpdatedAt(string $updated_at) Return the first ChildLang filtered by the updated_at column @@ -57,6 +60,7 @@ use Thelia\Model\Map\LangTableMap; * @method array findByCode(string $code) Return ChildLang objects filtered by the code column * @method array findByLocale(string $locale) Return ChildLang objects filtered by the locale column * @method array findByUrl(string $url) Return ChildLang objects filtered by the url column + * @method array findByPosition(int $position) Return ChildLang objects filtered by the position column * @method array findByByDefault(int $by_default) Return ChildLang objects filtered by the by_default column * @method array findByCreatedAt(string $created_at) Return ChildLang objects filtered by the created_at column * @method array findByUpdatedAt(string $updated_at) Return ChildLang objects filtered by the updated_at column @@ -148,7 +152,7 @@ abstract class LangQuery extends ModelCriteria */ protected function findPkSimple($key, $con) { - $sql = 'SELECT ID, TITLE, CODE, LOCALE, URL, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM lang WHERE ID = :p0'; + $sql = 'SELECT ID, TITLE, CODE, LOCALE, URL, POSITION, BY_DEFAULT, CREATED_AT, UPDATED_AT FROM lang WHERE ID = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -394,6 +398,47 @@ abstract class LangQuery extends ModelCriteria return $this->addUsingAlias(LangTableMap::URL, $url, $comparison); } + /** + * Filter the query on the position column + * + * Example usage: + * + * $query->filterByPosition(1234); // WHERE position = 1234 + * $query->filterByPosition(array(12, 34)); // WHERE position IN (12, 34) + * $query->filterByPosition(array('min' => 12)); // WHERE position > 12 + * + * + * @param mixed $position The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildLangQuery The current query, for fluid interface + */ + public function filterByPosition($position = null, $comparison = null) + { + if (is_array($position)) { + $useMinMax = false; + if (isset($position['min'])) { + $this->addUsingAlias(LangTableMap::POSITION, $position['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($position['max'])) { + $this->addUsingAlias(LangTableMap::POSITION, $position['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(LangTableMap::POSITION, $position, $comparison); + } + /** * Filter the query on the by_default column * diff --git a/core/lib/Thelia/Model/Map/CurrencyTableMap.php b/core/lib/Thelia/Model/Map/CurrencyTableMap.php index b1251801a..b37a6b30a 100644 --- a/core/lib/Thelia/Model/Map/CurrencyTableMap.php +++ b/core/lib/Thelia/Model/Map/CurrencyTableMap.php @@ -57,7 +57,7 @@ class CurrencyTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 7; + const NUM_COLUMNS = 8; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class CurrencyTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 7; + const NUM_HYDRATE_COLUMNS = 8; /** * the column name for the ID field @@ -89,6 +89,11 @@ class CurrencyTableMap extends TableMap */ const RATE = 'currency.RATE'; + /** + * the column name for the POSITION field + */ + const POSITION = 'currency.POSITION'; + /** * the column name for the BY_DEFAULT field */ @@ -125,12 +130,12 @@ class CurrencyTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Code', 'Symbol', 'Rate', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'code', 'symbol', 'rate', 'byDefault', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(CurrencyTableMap::ID, CurrencyTableMap::CODE, CurrencyTableMap::SYMBOL, CurrencyTableMap::RATE, CurrencyTableMap::BY_DEFAULT, CurrencyTableMap::CREATED_AT, CurrencyTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'CODE', 'SYMBOL', 'RATE', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'code', 'symbol', 'rate', 'by_default', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + self::TYPE_PHPNAME => array('Id', 'Code', 'Symbol', 'Rate', 'Position', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'code', 'symbol', 'rate', 'position', 'byDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(CurrencyTableMap::ID, CurrencyTableMap::CODE, CurrencyTableMap::SYMBOL, CurrencyTableMap::RATE, CurrencyTableMap::POSITION, CurrencyTableMap::BY_DEFAULT, CurrencyTableMap::CREATED_AT, CurrencyTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'CODE', 'SYMBOL', 'RATE', 'POSITION', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'code', 'symbol', 'rate', 'position', 'by_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); /** @@ -140,12 +145,12 @@ class CurrencyTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Code' => 1, 'Symbol' => 2, 'Rate' => 3, 'ByDefault' => 4, 'CreatedAt' => 5, 'UpdatedAt' => 6, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'byDefault' => 4, 'createdAt' => 5, 'updatedAt' => 6, ), - self::TYPE_COLNAME => array(CurrencyTableMap::ID => 0, CurrencyTableMap::CODE => 1, CurrencyTableMap::SYMBOL => 2, CurrencyTableMap::RATE => 3, CurrencyTableMap::BY_DEFAULT => 4, CurrencyTableMap::CREATED_AT => 5, CurrencyTableMap::UPDATED_AT => 6, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'CODE' => 1, 'SYMBOL' => 2, 'RATE' => 3, 'BY_DEFAULT' => 4, 'CREATED_AT' => 5, 'UPDATED_AT' => 6, ), - self::TYPE_FIELDNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'by_default' => 4, 'created_at' => 5, 'updated_at' => 6, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Code' => 1, 'Symbol' => 2, 'Rate' => 3, 'Position' => 4, 'ByDefault' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'position' => 4, 'byDefault' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), + self::TYPE_COLNAME => array(CurrencyTableMap::ID => 0, CurrencyTableMap::CODE => 1, CurrencyTableMap::SYMBOL => 2, CurrencyTableMap::RATE => 3, CurrencyTableMap::POSITION => 4, CurrencyTableMap::BY_DEFAULT => 5, CurrencyTableMap::CREATED_AT => 6, CurrencyTableMap::UPDATED_AT => 7, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'CODE' => 1, 'SYMBOL' => 2, 'RATE' => 3, 'POSITION' => 4, 'BY_DEFAULT' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), + self::TYPE_FIELDNAME => array('id' => 0, 'code' => 1, 'symbol' => 2, 'rate' => 3, 'position' => 4, 'by_default' => 5, 'created_at' => 6, 'updated_at' => 7, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) ); /** @@ -168,6 +173,7 @@ class CurrencyTableMap extends TableMap $this->addColumn('CODE', 'Code', 'VARCHAR', false, 45, null); $this->addColumn('SYMBOL', 'Symbol', 'VARCHAR', false, 45, null); $this->addColumn('RATE', 'Rate', 'FLOAT', false, null, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('BY_DEFAULT', 'ByDefault', 'TINYINT', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -351,6 +357,7 @@ class CurrencyTableMap extends TableMap $criteria->addSelectColumn(CurrencyTableMap::CODE); $criteria->addSelectColumn(CurrencyTableMap::SYMBOL); $criteria->addSelectColumn(CurrencyTableMap::RATE); + $criteria->addSelectColumn(CurrencyTableMap::POSITION); $criteria->addSelectColumn(CurrencyTableMap::BY_DEFAULT); $criteria->addSelectColumn(CurrencyTableMap::CREATED_AT); $criteria->addSelectColumn(CurrencyTableMap::UPDATED_AT); @@ -359,6 +366,7 @@ class CurrencyTableMap extends TableMap $criteria->addSelectColumn($alias . '.CODE'); $criteria->addSelectColumn($alias . '.SYMBOL'); $criteria->addSelectColumn($alias . '.RATE'); + $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.BY_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Model/Map/LangTableMap.php b/core/lib/Thelia/Model/Map/LangTableMap.php index 86e3ebe16..9eb864388 100644 --- a/core/lib/Thelia/Model/Map/LangTableMap.php +++ b/core/lib/Thelia/Model/Map/LangTableMap.php @@ -57,7 +57,7 @@ class LangTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 8; + const NUM_COLUMNS = 9; /** * The number of lazy-loaded columns @@ -67,7 +67,7 @@ class LangTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 8; + const NUM_HYDRATE_COLUMNS = 9; /** * the column name for the ID field @@ -94,6 +94,11 @@ class LangTableMap extends TableMap */ const URL = 'lang.URL'; + /** + * the column name for the POSITION field + */ + const POSITION = 'lang.POSITION'; + /** * the column name for the BY_DEFAULT field */ @@ -121,12 +126,12 @@ class LangTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Title', 'Code', 'Locale', 'Url', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), - self::TYPE_STUDLYPHPNAME => array('id', 'title', 'code', 'locale', 'url', 'byDefault', 'createdAt', 'updatedAt', ), - self::TYPE_COLNAME => array(LangTableMap::ID, LangTableMap::TITLE, LangTableMap::CODE, LangTableMap::LOCALE, LangTableMap::URL, LangTableMap::BY_DEFAULT, LangTableMap::CREATED_AT, LangTableMap::UPDATED_AT, ), - self::TYPE_RAW_COLNAME => array('ID', 'TITLE', 'CODE', 'LOCALE', 'URL', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), - self::TYPE_FIELDNAME => array('id', 'title', 'code', 'locale', 'url', 'by_default', 'created_at', 'updated_at', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id', 'Title', 'Code', 'Locale', 'Url', 'Position', 'ByDefault', 'CreatedAt', 'UpdatedAt', ), + self::TYPE_STUDLYPHPNAME => array('id', 'title', 'code', 'locale', 'url', 'position', 'byDefault', 'createdAt', 'updatedAt', ), + self::TYPE_COLNAME => array(LangTableMap::ID, LangTableMap::TITLE, LangTableMap::CODE, LangTableMap::LOCALE, LangTableMap::URL, LangTableMap::POSITION, LangTableMap::BY_DEFAULT, LangTableMap::CREATED_AT, LangTableMap::UPDATED_AT, ), + self::TYPE_RAW_COLNAME => array('ID', 'TITLE', 'CODE', 'LOCALE', 'URL', 'POSITION', 'BY_DEFAULT', 'CREATED_AT', 'UPDATED_AT', ), + self::TYPE_FIELDNAME => array('id', 'title', 'code', 'locale', 'url', 'position', 'by_default', 'created_at', 'updated_at', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -136,12 +141,12 @@ class LangTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Title' => 1, 'Code' => 2, 'Locale' => 3, 'Url' => 4, 'ByDefault' => 5, 'CreatedAt' => 6, 'UpdatedAt' => 7, ), - self::TYPE_STUDLYPHPNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'byDefault' => 5, 'createdAt' => 6, 'updatedAt' => 7, ), - self::TYPE_COLNAME => array(LangTableMap::ID => 0, LangTableMap::TITLE => 1, LangTableMap::CODE => 2, LangTableMap::LOCALE => 3, LangTableMap::URL => 4, LangTableMap::BY_DEFAULT => 5, LangTableMap::CREATED_AT => 6, LangTableMap::UPDATED_AT => 7, ), - self::TYPE_RAW_COLNAME => array('ID' => 0, 'TITLE' => 1, 'CODE' => 2, 'LOCALE' => 3, 'URL' => 4, 'BY_DEFAULT' => 5, 'CREATED_AT' => 6, 'UPDATED_AT' => 7, ), - self::TYPE_FIELDNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'by_default' => 5, 'created_at' => 6, 'updated_at' => 7, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Title' => 1, 'Code' => 2, 'Locale' => 3, 'Url' => 4, 'Position' => 5, 'ByDefault' => 6, 'CreatedAt' => 7, 'UpdatedAt' => 8, ), + self::TYPE_STUDLYPHPNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'position' => 5, 'byDefault' => 6, 'createdAt' => 7, 'updatedAt' => 8, ), + self::TYPE_COLNAME => array(LangTableMap::ID => 0, LangTableMap::TITLE => 1, LangTableMap::CODE => 2, LangTableMap::LOCALE => 3, LangTableMap::URL => 4, LangTableMap::POSITION => 5, LangTableMap::BY_DEFAULT => 6, LangTableMap::CREATED_AT => 7, LangTableMap::UPDATED_AT => 8, ), + self::TYPE_RAW_COLNAME => array('ID' => 0, 'TITLE' => 1, 'CODE' => 2, 'LOCALE' => 3, 'URL' => 4, 'POSITION' => 5, 'BY_DEFAULT' => 6, 'CREATED_AT' => 7, 'UPDATED_AT' => 8, ), + self::TYPE_FIELDNAME => array('id' => 0, 'title' => 1, 'code' => 2, 'locale' => 3, 'url' => 4, 'position' => 5, 'by_default' => 6, 'created_at' => 7, 'updated_at' => 8, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, 7, 8, ) ); /** @@ -165,6 +170,7 @@ class LangTableMap extends TableMap $this->addColumn('CODE', 'Code', 'VARCHAR', false, 10, null); $this->addColumn('LOCALE', 'Locale', 'VARCHAR', false, 45, null); $this->addColumn('URL', 'Url', 'VARCHAR', false, 255, null); + $this->addColumn('POSITION', 'Position', 'INTEGER', false, null, null); $this->addColumn('BY_DEFAULT', 'ByDefault', 'TINYINT', false, null, null); $this->addColumn('CREATED_AT', 'CreatedAt', 'TIMESTAMP', false, null, null); $this->addColumn('UPDATED_AT', 'UpdatedAt', 'TIMESTAMP', false, null, null); @@ -333,6 +339,7 @@ class LangTableMap extends TableMap $criteria->addSelectColumn(LangTableMap::CODE); $criteria->addSelectColumn(LangTableMap::LOCALE); $criteria->addSelectColumn(LangTableMap::URL); + $criteria->addSelectColumn(LangTableMap::POSITION); $criteria->addSelectColumn(LangTableMap::BY_DEFAULT); $criteria->addSelectColumn(LangTableMap::CREATED_AT); $criteria->addSelectColumn(LangTableMap::UPDATED_AT); @@ -342,6 +349,7 @@ class LangTableMap extends TableMap $criteria->addSelectColumn($alias . '.CODE'); $criteria->addSelectColumn($alias . '.LOCALE'); $criteria->addSelectColumn($alias . '.URL'); + $criteria->addSelectColumn($alias . '.POSITION'); $criteria->addSelectColumn($alias . '.BY_DEFAULT'); $criteria->addSelectColumn($alias . '.CREATED_AT'); $criteria->addSelectColumn($alias . '.UPDATED_AT'); diff --git a/core/lib/Thelia/Tests/Action/ImageTest.php b/core/lib/Thelia/Tests/Action/ImageTest.php index fa25672d7..195613c0b 100644 --- a/core/lib/Thelia/Tests/Action/ImageTest.php +++ b/core/lib/Thelia/Tests/Action/ImageTest.php @@ -113,7 +113,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase /** * - * Tru to process a non-existent file + * Try to process a non-existent file * * @expectedException \InvalidArgumentException */ @@ -129,6 +129,24 @@ class ImageTest extends \PHPUnit_Framework_TestCase $image->processImage($event); } + /** + * + * Try to process a file outside of the cache + * + * @expectedException \InvalidArgumentException + */ + public function testProcessImageOutsideValidPath() + { + $event = new ImageEvent($this->request); + + $image = new Image($this->getContainer()); + + $event->setCacheFilepath("blablabla.png"); + $event->setCacheSubdirectory("../../../"); + + $image->processImage($event); + } + /** * No operation done on source file -> copie ! */ @@ -317,4 +335,37 @@ class ImageTest extends \PHPUnit_Framework_TestCase $image->processImage($event); } + public function testClearTestsCache() { + $event = new ImageEvent($this->request); + + $event->setCacheSubdirectory('tests'); + + $image = new Image($this->getContainer()); + + $image->clearCache($event); + } + + public function testClearWholeCache() { + $event = new ImageEvent($this->request); + + $image = new Image($this->getContainer()); + + $image->clearCache($event); + } + + /** + * Try to clear directory ouside of the cache + * + * @expectedException \InvalidArgumentException + */ + public function testClearUnallowedPathCache() { + $event = new ImageEvent($this->request); + + $event->setCacheSubdirectory('../../../..'); + + $image = new Image($this->getContainer()); + + $image->clearCache($event); + } + } \ No newline at end of file diff --git a/core/lib/Thelia/Tools/URL.php b/core/lib/Thelia/Tools/URL.php index accd4fd8b..5a88fa922 100644 --- a/core/lib/Thelia/Tools/URL.php +++ b/core/lib/Thelia/Tools/URL.php @@ -27,6 +27,9 @@ use Thelia\Model\ConfigQuery; class URL { + const PATH_TO_FILE = true; + const WITH_INDEX_PAGE = false; + public static function getIndexPage() { return ConfigQuery::read('base_url', '/') . "index_dev.php"; // FIXME ! @@ -39,25 +42,28 @@ class URL * * @param string $path the relative path * @param array $parameters An array of parameters - * @param boolean $path_only if true, getIndexPage() will not be added + * @param boolean $path_only if true (PATH_TO_FILE), getIndexPage() will not be added * * @return string The generated URL */ - public static function absoluteUrl($path, array $parameters = array(), $path_only = false) + public static function absoluteUrl($path, array $parameters = null, $path_only = self::WITH_INDEX_PAGE) { // Already absolute ? if (substr($path, 0, 4) != 'http') { - $root = $path_only ? ConfigQuery::read('base_url', '/') : self::getIndexPage(); + $root = $path_only == self::PATH_TO_FILE ? ConfigQuery::read('base_url', '/') : self::getIndexPage(); - $base = $root . '/' . ltrim($path, '/'); + $base = rtrim($root, '/') . '/' . ltrim($path, '/'); } else $base = $path; + $queryString = ''; - foreach ($parameters as $name => $value) { - $queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value)); + if (! is_null($parameters)) { + foreach ($parameters as $name => $value) { + $queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value)); + } } $sepChar = strstr($base, '?') === false ? '?' : '&'; diff --git a/install/INSTALL-TODO.txt b/install/INSTALL-TODO.txt index ba319c228..8ea68554e 100644 --- a/install/INSTALL-TODO.txt +++ b/install/INSTALL-TODO.txt @@ -20,4 +20,7 @@ Variables Config à initialiser: - form.secret : token csrf - verifyStock : vérification du stock lors du paiement/ajout au panier. Defaut 1 - default_images_quality_percent : qualité par défaut des images générées (0 à 100, défaut: 75). -- original_image_delivery_mode : mode de mise à disposition des images originales (full resolution) dans le cache. 'symlink' pour un lien symbolique, 'copy' pour une copie \ No newline at end of file +- original_image_delivery_mode : mode de mise à disposition des images originales (full resolution) dans le cache. 'symlink' pour un lien symbolique, 'copy' pour une copie +- images_library_path : chemin vers le répertoire où sont stockés les images source (defaut: local/media/images) +- image_cache_dir_from_web_root : le repértoire de base où sont cachées les images, relatif à /web (cache/images) +- imagine_graphic_driver : le drivers utilisé par Imagine (gd, imagik, gmagick), defaut: 'gd' diff --git a/install/faker.php b/install/faker.php index 23bbed2bb..54d5c80fc 100755 --- a/install/faker.php +++ b/install/faker.php @@ -1,4 +1,9 @@ beginTransaction(); $currency = \Thelia\Model\CurrencyQuery::create()->filterByCode('EUR')->findOne(); +function generate_image($image, $position, $typeobj, $id) { + + global $faker; + + $image + ->setTitle($faker->text(20)) + ->setDescription($faker->text(250)) + ->setChapo($faker->text(40)) + ->setPostscriptum($faker->text(40)) + ->setPosition($position) + ->setFile(sprintf("sample-image-%s.png", $id)) + ->save() + ; + + // Generate images + $image_data = file_get_contents("http://placehold.it/320x200&text=Image+for+$typeobj+ID+".$id); + $image_file = sprintf("%s/../local/media/images/%s/sample-image-%s.png", __DIR__, $typeobj, $id); + + if (! is_dir(dirname($image_file))) mkdir(dirname($image_file), 0777, true); + + if ($fh = fopen($image_file, "w")) { + fwrite($fh, $image_data); + fclose($fh); + } +} + try { + $stmt = $con->prepare("SET foreign_key_checks = 0"); + $stmt->execute(); + $category = Thelia\Model\CategoryQuery::create() ->find(); $category->delete(); @@ -50,6 +84,9 @@ try { ->find(); $content->delete(); + $stmt = $con->prepare("SET foreign_key_checks = 1"); + $stmt->execute(); + //first category $sweet = new Thelia\Model\Category(); $sweet->setParent(0); @@ -60,6 +97,10 @@ try { $sweet->save(); + $image = new CategoryImage(); + $image->setCategoryId($sweet->getId()); + generate_image($image, 1, 'category', $sweet->getId()); + //second category $jeans = new Thelia\Model\Category(); $jeans->setParent(0); @@ -70,6 +111,10 @@ try { $jeans->save(); + $image = new CategoryImage(); + $image->setCategoryId($jeans->getId()); + generate_image($image, 2, 'category', $jeans->getId()); + //third category $other = new Thelia\Model\Category(); $other->setParent($jeans->getId()); @@ -80,6 +125,10 @@ try { $other->save(); + $image = new CategoryImage(); + $image->setCategoryId($other->getId()); + generate_image($image, 3, 'category', $other->getId()); + for ($i=1; $i <= 5; $i++) { $product = new \Thelia\Model\Product(); $product->addCategory($sweet); @@ -102,8 +151,12 @@ try { $productPrice->setProductSaleElements($stock); $productPrice->setCurrency($currency); $productPrice->setPrice($faker->randomFloat(2, 20, 2500)); + $productPrice->save(); + $image = new ProductImage(); + $image->setProductId($product->getId()); + generate_image($image, $i, 'product', $product->getId()); } for ($i=1; $i <= 5; $i++) { @@ -130,6 +183,10 @@ try { $productPrice->setPrice($faker->randomFloat(2, 20, 2500)); $productPrice->save(); + $image = new ProductImage(); + $image->setProductId($product->getId()); + generate_image($image, $i, 'product', $product->getId()); + } //folders and contents @@ -143,6 +200,10 @@ try { $folder->save(); + $image = new FolderImage(); + $image->setFolderId($folder->getId()); + generate_image($image, $i, 'folder', $folder->getId()); + for($j=0; $jsetParent($folder->getId()); @@ -153,6 +214,10 @@ try { $subfolder->save(); + $image = new FolderImage(); + $image->setFolderId($subfolder->getId()); + generate_image($image, $j, 'folder', $subfolder->getId()); + for($k=0; $kaddFolder($subfolder); @@ -162,6 +227,11 @@ try { $content->setDescription($faker->text(255)); $content->save(); + + $image = new ContentImage(); + $image->setContentId($content->getId()); + generate_image($image, $k, 'content', $content->getId()); + } } } @@ -188,8 +258,13 @@ try { } $con->commit(); -} catch (Exception $e) { - echo "error : ".$e->getMessage()."\n"; +} +catch (PropelException $pe) { + echo "Propel error: ".$pe->getMessage()."\n".$pe->getTraceAsString(); + $con->rollBack(); +} +catch (Exception $e) { + echo "error occured : ".$e->getMessage()."\n".$e->getTraceAsString(); $con->rollBack(); } diff --git a/install/insert.sql b/install/insert.sql index 1263f47df..a7255eba2 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -7,7 +7,7 @@ INSERT INTO `lang`(`id`,`title`,`code`,`locale`,`url`,`by_default`,`position`,`c INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES ('session_config.default', '1', 1, 1, NOW(), NOW()), ('verifyStock', '1', 1, 0, NOW(), NOW()); -('imagine_driver', 'gd', 1, 0, NOW(), NOW()); +('imagine_graphic_driver', 'gd', 1, 0, NOW(), NOW()); ('default_images_quality_percent', '75', 1, 0, NOW(), NOW()); ('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()); diff --git a/install/thelia.sql b/install/thelia.sql index 1e80ab01d..6d16cfdc1 100755 --- a/install/thelia.sql +++ b/install/thelia.sql @@ -521,6 +521,7 @@ CREATE TABLE `lang` `code` VARCHAR(10), `locale` VARCHAR(45), `url` VARCHAR(255), + `position` INTEGER NOT NULL, `by_default` TINYINT, `created_at` DATETIME, `updated_at` DATETIME, @@ -719,6 +720,7 @@ CREATE TABLE `currency` `code` VARCHAR(45), `symbol` VARCHAR(45), `rate` FLOAT, + `position` INTEGER NOT NULL, `by_default` TINYINT, `created_at` DATETIME, `updated_at` DATETIME, diff --git a/local/config/schema.xml b/local/config/schema.xml index 1bed327b1..460d1814b 100755 --- a/local/config/schema.xml +++ b/local/config/schema.xml @@ -385,7 +385,8 @@ - + +
@@ -545,6 +546,7 @@ + diff --git a/local/media/.gitkeep b/local/media/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/templates/default/images.html b/templates/default/images.html new file mode 100644 index 000000000..c72beaecd --- /dev/null +++ b/templates/default/images.html @@ -0,0 +1,104 @@ +{include file="includes/header.html"} + + +
+

Category Images

+
    + {loop type="category" name="jsvdfk"} +
  • Category id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" category="#ID" width="200" height="100" resize_mode="borders"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      + + {/loop} + + {loop type="image" name="image_test" category="#ID"} +

      Full size file URL: #IMAGE_URL

      + + {/loop} + + {loop type="image" name="image_test" source="category" source_id="#ID"} +

      source="category" source_id="x" argument style: Processed file URL: #IMAGE_URL

      + {/loop} +
    • +
    +
  • + {/loop} +
+
+ + +
+

Product Images

+
    + {loop type="product" name="jsvdfk"} +
  • Product id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" product="#ID" width="200" height="100" resize_mode="borders" effects="gamma:0.7" background_color="#cc8000"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      +

      Images:

      + + + {/loop} + {loop type="image" name="image_test" product="#ID" width="200" height="100" resize_mode="crop"} + + {/loop} + {loop type="image" name="image_test" product="#ID" width="100" height="200" resize_mode="borders" background_color="#cc8000"} + + {/loop} + {loop type="image" name="image_test" product="#ID" width="100" rotation="-20" background_color="#facabe"} + + {/loop} + {loop type="image" name="image_test" product="#ID" width="200" height="100" resize_mode="borders" background_color="#facabe" effects="negative"} + + {/loop} +

      +
    • +
  • + {/loop} +
+
+ +
+

Folder Images

+
    + {loop type="folder" name="jsvdfk"} +
  • Folder id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" folder="#ID" width="200" height="100" resize_mode="borders"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      + + {/loop} +
    • +
    +
  • + {/loop} +
+
+ +
+

Content Images

+
    + {loop type="content" name="jsvdfk"} +
  • Content id #ID: #TITLE

    +
      +
    • + {loop type="image" name="image_test" content="#ID" width="200" height="100" resize_mode="borders"} +

      Processed file URL: #IMAGE_URL

      +

      Original file URL: #ORIGINAL_IMAGE_URL

      + + {/loop} +
    • +
    +
  • + {/loop} +
+
+ +{include file="includes/footer.html"} \ No newline at end of file From f028d2b2db0388eb9c6c0f381d9a16ba44a4e404 Mon Sep 17 00:00:00 2001 From: franck Date: Thu, 15 Aug 2013 21:18:16 +0200 Subject: [PATCH 10/11] Added image-cache:clear console command --- core/lib/Thelia/Action/Image.php | 5 +- core/lib/Thelia/Command/ClearImageCache.php | 70 +++++++++++++++++++++ core/lib/Thelia/Config/Resources/config.xml | 1 + core/lib/Thelia/Core/Event/TheliaEvents.php | 5 ++ install/insert.sql | 2 + 5 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 core/lib/Thelia/Command/ClearImageCache.php diff --git a/core/lib/Thelia/Action/Image.php b/core/lib/Thelia/Action/Image.php index dcf4390c5..eabf03b0a 100644 --- a/core/lib/Thelia/Action/Image.php +++ b/core/lib/Thelia/Action/Image.php @@ -490,9 +490,8 @@ class Image extends BaseAction implements EventSubscriberInterface public static function getSubscribedEvents() { return array( - TheliaEvents::IMAGE_PROCESS => array( - "processImage", 128 - ), + TheliaEvents::IMAGE_PROCESS => array("processImage", 128), + TheliaEvents::IMAGE_CLEAR_CACHE => array("clearCache", 128), ); } } diff --git a/core/lib/Thelia/Command/ClearImageCache.php b/core/lib/Thelia/Command/ClearImageCache.php new file mode 100644 index 000000000..801e2e8d0 --- /dev/null +++ b/core/lib/Thelia/Command/ClearImageCache.php @@ -0,0 +1,70 @@ +. */ +/* */ +/*************************************************************************************/ + +namespace Thelia\Command; + + +use Thelia\Command\ContainerAwareCommand; +use Thelia\Core\Event\TheliaEvents; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Thelia\Core\Event\ImageEvent; +use Thelia\Core\HttpFoundation\Request; +use Symfony\Component\Console\Input\InputArgument; + + +class ClearImageCache extends ContainerAwareCommand +{ + protected function configure() + { + $this + ->setName("image-cache:clear") + ->setDescription("Empty part or whole web space image cache") + ->addArgument("subdir", InputArgument::OPTIONAL, "Clear only the specified subdirectory") + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $dispatcher = $this->getContainer()->get('event_dispatcher'); + + $request = new Request(); + + try { + $event = new ImageEvent($request); + + $subdir = $input->getArgument('subdir'); + + if (! is_null($subdir)) $event->setCacheSubdirectory($subdir); + + $dispatcher->dispatch(TheliaEvents::IMAGE_CLEAR_CACHE, $event); + + $output->writeln(sprintf('%s image cache successfully cleared.', is_null($subdir) ? 'Entire' : ucfirst($subdir))); + } + catch(\Exception $ex) { + $output->writeln(sprintf("Failed to clear image cache: %s", $ex->getMessage())); + } + } +} diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 8181c60fc..a404fa6f2 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -43,6 +43,7 @@ + diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 0f512fab3..f64a071c7 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -140,4 +140,9 @@ final class TheliaEvents */ const IMAGE_PROCESS = "action.processImage"; + /** + * Sent on cimage cache clear request + */ + const IMAGE_CLEAR_CACHE = "action.clearImageCache"; + } diff --git a/install/insert.sql b/install/insert.sql index a7255eba2..c9b740dac 100755 --- a/install/insert.sql +++ b/install/insert.sql @@ -10,6 +10,8 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('imagine_graphic_driver', 'gd', 1, 0, NOW(), NOW()); ('default_images_quality_percent', '75', 1, 0, NOW(), NOW()); ('original_image_delivery_mode', 'symlink', 1, 0, NOW(), NOW()); +('images_library_path', 'local/media/images', 1, 0, NOW(), NOW()); +('image_cache_dir_from_web_root', 'cache/images', 1, 0, NOW(), NOW()); From 87d3a4583b4129494da5a5f5da451c5350a06655 Mon Sep 17 00:00:00 2001 From: franck Date: Fri, 16 Aug 2013 09:46:51 +0200 Subject: [PATCH 11/11] Faker generates images with Imagine instead of using placeholder.it --- core/lib/Thelia/Core/Template/Loop/Image.php | 19 ---------- install/faker-assets/FreeSans.ttf | Bin 0 -> 714456 bytes install/faker.php | 35 ++++++++++++++++--- 3 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 install/faker-assets/FreeSans.ttf diff --git a/core/lib/Thelia/Core/Template/Loop/Image.php b/core/lib/Thelia/Core/Template/Loop/Image.php index e7a7ddca4..a1e866cb2 100644 --- a/core/lib/Thelia/Core/Template/Loop/Image.php +++ b/core/lib/Thelia/Core/Template/Loop/Image.php @@ -277,25 +277,6 @@ class Image extends BaseLoop } return $loopResult; -/* -#PRODUIT : identifiant du produit associé (valué si le paramètre "produit" a été indiqué) -#PRODTITRE : titre du produit associé (valué si le paramètre "produit" a été indiqué) -#PRODREF : référence du produit associé (valué si le paramètre "produit" a été indiqué) -#RUBRIQUE : identifiant de la rubrique associée (valué si le paramètre "rubrique" a été indiqué) -#RUBTITRE : titre de la rubrique associée (valué si le paramètre "rubrique" a été indiqué) -#DOSSIER : identifiant du dossier associée (valué si le paramètre "dossier" a été indiqué) -#DOSTITRE : titre du dossier associée (valué si le paramètre "dossier" a été indiqué) -#CONTENU : identifiant du contenu associée (valué si le paramètre "contenu" a été indiqué) -#CONTTITRE : titre du contenu associée (valué si le paramètre "contenu" a été indiqué) -#IMAGE : URL de l'image transformée (redimensionnée, inversée, etc. suivant les paramètres d'entrée de la boucle). -#FICHIER : URL de l'image originale -#ID : identifiant de l'image - -#TITRE : titre de l'image -#CHAPO : description courte de l'image -#DESCRIPTION : description longue de l'image -#COMPT : compteur débutant à 1. Utile pour l'utilisation de Javascript. - */ } /** diff --git a/install/faker-assets/FreeSans.ttf b/install/faker-assets/FreeSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9db958532c12ef7f4aa22fab57a0f71e82acdd38 GIT binary patch literal 714456 zcmeF4dt6n;`tYAwYlE->MMXtL*jz+XRKyz=85$xbDw!54DHfI$rYV^foyfGzsIaK0 ztgJk09V;p;N-8TdD=JS?S>CY7P^i3MUO?9SowfHiw97fa&-=cg_n+5uzCE*Mo_Xdz zYu2n;8&M+Ck^eX(AuVm<*omcO2gJFz0^hLFsiV>^Pdu-)ICGOkd{>Xo9Dni9r`D_x z=aUmf(r1mnc+$v&oAOVJ^O_owf%C>++&}TG`R}BNsB+?8a>eW!b63~>Rx2`by-54j zS1ibPnL~^XB3FkJ9(d*4t7f-b-+ztBmDwW3%&TV1pDW?wPkM2L2Va$U)0IKpk$bqYX*~9m2_G^G51)T_eu(RQu487+&R^KBPvk~y1&d5rb?wY~*KO|6 zyjt2!KOpMJFL`sWn30t66nVQkhVZqsXDpoCd9X2<_@%^mT{mO)%(8>sBgKDGjYy}A zxpU^{U)iNyq4-}LFLLbo+<7zSW-q_)3Xxfr=uZ$`cPcCR)#~>fr?*Q!Vg#6V_{ioB zWlpbbn%C0D=NCseuKhsAu>Wh;wN%R#pPfzfPM+=ai^ty%)c*;2PWyyBM?L1s4a79K zHl(x1fFG@;)SIeUd?@QOYP7!;X=z=icFO=|;2YrMF!Vo1ZJYb7k#f=!Nm!|Ej~+M4 zB`M;vEYoEriI{aNK1bBMyN~Knqe8N5$$ynjud@`WD`b!nFKr>xyh(Z(kINu=R}$1% zxd39-5{Wa?B@x|Ax$bAn&ek#X`@oeD1uh7KXwd%speMwlf1L&!eYG8%co}ORCEnxG z9>yDAN&-yAJ;k^}rkGBN=lWve<*G)HPP}BABV-Kz8HC58JJpt7%4N6{h}Vg*Nw~w! zGU<%e1mPcsofJi$RVV4JzQT6AwV$$dCV#zQ2x&whyFnbf9gsaBO?Jsh*=7Ag_}REq zNk2{dLktXoZrB+`cogw;9ge{5Bp<%W_7DOQYMk^@4$3kPyXi6pU0wG#qp#~;r+YpG zXdPr9Y<4yFScla->8Uo_^%ke=-u4?yJx`NIbUmtRjP7X?OjtJYMi^abH+MVr!he*S zO?fs-KXay>Yct1AD~Ec~_5KIw;Q{15fv_p9@#J?jb!g%CM<)dAcF=9m8uB%r>u|y+ zorZ3U$7Cw)q06f4{STOh(p%RTVR5aICVFj?oFz@xaX3Jju77VkX!q~vK6ZuOh9mGl zg>DO@kKNWGcG-3Mx(?;05aM;S>qzHS*Vo@j>VrNfJ^o5!?_$E! zkiC#?sOR4(=N{_XKpx@xB=RS&yV?D*vrMNxCK|Q$sX`e^p4;PJLq5jiK3k*h(PvYT znYtfqspd$kEgNkq_zP)fXx%@^cj#}MBu|Iw_C?10LDoqh^Lgr?F{sDE8FB#m(ebR4!U1pE(H1cDQ5z;s5gTH$FfSvY#(?;%b(R!Tq*7J-W>)1MNT#%MsZ{9S#QkTbQ zD(HaX7wCsk6p&tEtIdoJJvjD z`<}{!-N&srNk{kfzV7l{hfmeR@9pO9)Bd!<-L#o^Yh{$4mPY369Q>w$XWlepnD_NP=`dq+FS11)#!x$+o)`2S(B1fs^}$&BohILw zqx8I>7Rf|4pFBs=$HC59A8hxA!4j^%kanaQ3T??_TVoz`Mt6H&^WIDKeCuM&M5t!Q zCVjz(v+te#@pr@6)pe*&kS9Ol&q1#rWAZEP#p3@W{_Z-m_04t60Tob2y}gW%Nj)}8 zTeAawrGzq1f)3JG?d4u}HtF3+UdPg=AZsL08YC9NRS0W6-JEf8=9?YN!~=fW`X zVGh}e6#76hvYoue{b8(hhxV*TLaEERKhQ?f4M3+0===--ombtydd<^ajmC}-d3?>L z1AhLL_d3}uq0r4Eb$Pvc8obwA94<;1H&VoU#P;rYrs8~HR`1lK|Vgy4S;@@=?|IJyikfv!Vsv%V&X)=LvIvDp9BcHV_^P@d(S?k;3=rPCG>wIH@eV^0! z$V|efq94ax-U)XQ_iX*F(%IN2gNQ$f{P@}a6Sxku+QU;QYE!Qm z%D5a_sFO6LUW@2^ihc&--mB+pM-p}Q8*4?alaJ1KFw=hCxR|v=J9|B&*EGa8^?e_E z=G}zr^@`TjEQDux)*FZXH{oHF18Lj`I!#@_*fcN0y&Ri+@t-G2=5TZ`h6`91U4!3~ z@EP~;eaIKli=#gEJj?v6O6<8doH~m&4%0XEeMsLcKc zg1W30A9DuoFU7|gNt{FEWj*1Wp_I6_iMEI3HkwTYPv|1ym|e-5`D&6%VJ=@vD!co z(L{ZW#`eq9dt2JMi0fpoC$qM?7fD}GO9>m#^>)&Iin<<79v-zAh^x1j^6*VGT#eZol{ z`p`F=Mh2A99(CATOV}Ft2m1c7fPSy*c>(Dkvh&s7*udKKDekXGX(1immuOGBp9y&@ z=bjwM7}Whow`Cpj9Hhq<&zzauH`8=nyMO9FqWdY*UZ2fz_ffl_=yi1j_B`@bT6zrV z{-f7`VT^y>hiNyjwEM4aCvSUsr0$#arx@Lr?KVDB(x>h6GFH?*lvnp@-LG_d_2lbO z=8u!oS&vVi2V%_C%wL-+`+W3u-`N7?@C*IrE7*YhSDwk=LB5N<&d6e(Vcw*V-O2St z=)(TUTlh1E2un2XA^ZW#bd>lPOJCDL{Z8eY_{LJ6+1?_&j5xA-iNS_up{b`aa(og0y5_9l;!zMt_WEP8-4eHo_Rix?%=? zy>KTXhY?19QX$yx&b7|-S;(#+xRcO}W8L0SM#yoi!Dxr>L--S)az^VksJB=n0KG^^ zXAYlZ$IpOh~l z1sH>jZjm49&#WEfCaD(g$Hr~AwLRjiWkw;-!sA)1e963V3HiEC&eM8oI`@bmIPbxW*KNqmvfCV^riC%Pa-Ugd4C-K(_}b(x2Nex`@KZj z)?#-B?NTgBwev{rrY-I8HH2%P z2i88e`zz*9y$%6uxEesczC#;vUpJGv-)$i#a4!>{XT*FI_wD$-d^%>9xXg3JFh@xs z?r`I0bm>I~yR@_sJE)Kc^cKdIa32wa9MFzJ9~R~np?-vZAgm3Qy(4Wnuodv32hB#CaUKm(u#SJf_}~F0$3yE#Gs!$0CO%5w} z{PW;?SqKY^XViSw0l(0vr@-})1-UQ|W_pN1E`r9UiTDtb)A#TbY^ljo1+*1zfZLOgqSUscg}BCOqNC(n`3So`QBebw89 z9cHhRoqX=QV!sLa1h?)#k3lo}p&f0#W@MG_^ev0+w;S(SFAMQyeT#mE@PQOyx2NR| z)e9T_txdRxz=intSGf`(+glo#C*ApZgY+iwJVzPP`IWZ%g7H3rXQi?9r2#xwwpRyv zK5OK;>U;51ML&L2G%qlB-)1!-yQy9D#YhQ~CwU&5P25oGXD0hG_PXA> zQBCLBH`_YyNU@HaGp!nPrS+S!)jDqTsP&sU8Fv+7Q;^TIcYibc7Uj6>;BM=v@r-rC zD8~O@;@yDXZCu}uT+a0}+yAI>57&kG-wY4qw}7zg+0$A={Cl~ci<}7$ptlR1JXnR! z7goJ755LDeT*=<1@Gc{q{q2#IudfwF{hV;q!l*sTXlseob%uOVV-%3z6WA-l-o40T zSSgXL7b2L?JK3agPaRABpJWZUg!SMHlVYO&z_b?=da=rE^QEbg`0Y zy^ekAo2j40RwH>*Mh~mS=nkY#y&g8At!85u?<9T^gLsY1;YSEFsJElWtJbf^ zOV$B<-7?NPZukFlsK1x2gGO8HBs#wt=Mi7ao>r3#ZmCpH(LWAKGSBy&UQh-Uwy~*0^~CMo`uywKJ5IMyUx0 zBPomNBCMZ;nRBfcQuOG9TnD-M|uMcMJtncmZ%`~2guIBn>#;%2X8}3)2m-v}e$)9ec#mrUY+3ZOk zX50DId*n{~L3`eT)zMcH%_YPqPv#4_TVZ@ndVfJ{z0=(Du+a(~zxB0tYd^+nqM8ct z!UY~Gk(vCr*7Yy3s6!+jhGfjPcX1Y3UZC~ScYdOQ?H{T<5xYzG`x8JFB|C@BQ zjyD~z+Z#{&>wKLV?#YjuLiuzb({c=YiLm)UW9HHh$!@g1c6;OTOyusnNUz`D$=0?` zxv}5c?w_S)r^8x{_g0DO82W)8>F<$#_<6&$I}dapqc7R+RUYZ}zm;q4=MC4gzqMG3};B@(*3rOydu=P|L+n$W^5Z%04`beJ zOL!}I*O};r=XQPn{QWx6t!vzge`~0()?-8WY4&UW6dlI1^%4 zuhQ`5&)7)Z*4)Ll2d_?R`FCMjPmhh(c;m94lXx2X9-?WLp6&htKh2@jIc4WC{;lx( zpDB57o2WU{|IBOq9;)x79=ze+>r*o5cU!0Y{!^U4XkT*(d7Fnl#;_iPJ~0r*HESpH zE4SMxkvy&7nzq%j4{GDR_O7W;>*Lt;Uh@vuy{^&yg882Q(c`qS%RNZnhrH$0bNs0} zn>o{-_qd;UrG0;6F7!&Xmas}U-ZXg!l4wv*_FC|2q-F|y3A)UBt~<|-u#VB|Llc;v zBlR3@E(7$nJhdkK4L4{>{$Bov^G(>b&oZzFG=+WF4z!bft^>Q?b4_PRo@3*!-QIA{ zT>QrQhA)Wg!@HVBolo{g&i;dRpJh6mJaeYW`tc08%jCTw=ranZNz%zc_m5|sJpSbO z&(Ak`{K>~u;_Lcz%hS(0or8USCd4CoUeWIm{_fn9H(bA?@t%MBGx=Yhe3Zw-Ccd}7ohjLSv_ATq z@H6%Q>e}7Ey#4HtvJL4}lFpy%k;jXrNyZ_k^KQg`=SqA2@jRQ|-qxDG><`{^TmL~) zKc}5r;~Cz4X6rvl@_*|5nq9wVUhDVRe~0@Wds|~K`>l;Uhp%TJX@m8%@igP@amEYp zz5kT&(EWt>ql>Kr<~-}5c?IXZ<`74}AO9On2f9w{sQI#W$b6N3gO{vE^A(t6?bN7n z-gW4A>*4HygLB};P%lg&P$vW&9 zjEu$RS*^vxese^v(0j2t!ntRI-Sg3Uta zuWLE?R4fxUQf#wb1$={ZzQfPRCpKUa6luH2T^A z#+b$&V0}m3er)_m|GS%W9vaSi{aIa+&v)(fEt%FwW&&Ez_{hqJ?-z6 z>`4o|+xm?cbB;d8$wvf`3xDzt8~ThD=jYiw1GA1g0hPp=m?74+%wHp9r=)l#y85iX zKA+WJOVZHyvRE~ZwZJrczP^-q?(@l0K51Y2CrO_2^5ogyC(}O5HGs2o19(@a&$9jQ zUdT5bCpZTL?EPI%S_Lqcyzb{+_Bk5$I`4tgX^&#wL$9&Msc~`>L^!fI_dn7`$LXif zt3w31^mhiNbDkYve{*m%d!~)-FJsT_$T(#Wl|7{a%&qqOcBw&XcQ$+8xNT0A6TyRlyz%ig7nb&_5mb<=AV<9QkF(^IB8UXjaqPoBt`iDdfb5cW1>=$E1B zcH+HQl(CMv`!nuu?(sF%C}iE}5Et)Bj=Qmj@Lr_{Zr*m;@Rrj)bH+QYmW3X8Lv`{c z;N9cN0WiqpMyH9lgZc~`?+TRXVyqlpO4n_bTbnlu;1kksXo2t*$$G{I#EUch=XW zm5aSx%9U%rY@dM(M}|8-l5n4$?1j7iIwL#dr@vWopVMN^uGhKD10y*zHIgwtl052f z0rZ(!Cv&LNai8tBzYoB#J$`&Az})Em#=`D@=63qyRO(|pV+-l%Afb*9%Exq34j1+7 zmD_38?UZpl=S(u-fv zvzbFF*GJ@4lg^n5H~M=axBFxAH&m{+iJ{%nnIF=byFs;B&1$KAeHqtljBshgo^m(n z$_r9`4t0!ju`Xu*R1@v|=sbiI7N@c6K8(7ru-jp}IbEK`&KR3>sozG%%L%;Wq?qX_ujZ zu~I<4D4-9x8HF50Sf4YY?J^)jx1miI*EvwYS(et+QCFH~&b|Qs^itjfrtq$3IBC1{ z=t+-u>7_Qy<(#QZhv~R4pkDR+pj^^$-xDs7uDmm8rwWrnYerX!mAFg{iO`bo@H_ z9JT|`$lQk;8M`jI)(oM~|2MD}(CY!d#H)f;Zuj3^+j<_|*7~Q}`5%O98?Eu$@yb6- z!yEShN~!`+eQ61;^I_M||G>X>-2Yo{)p&Xybvov?o^~hf&%#^fg?%vk)PIC?J2e_~ zb3L3uo;a0u0eupTC!|n=dzuFKdU(>jh3i|mhyJd2`x$ymPtyzGS-^{nF}{y`7V>|F zTE==vh|{`!*ia9^GT#0FZm&)rrYxr*Uh6o&yFK~0%fVXV4BJ}ocbjha6Zoz0@FY@S z>+!BxVLr{gslPd4-O9OzD4y4&&%9=BJ(T^9q1;DpIBzjh-NYL80roL@R^V)BFE8FX zQ_qtshx^Pd&QAkpM$=EBXs!RtSfdHpSP_QG(t^u|>&T$iI?&iYX6yO{HhyYGJDG2HHW8*J`J_(zk>50%RqVTQj?-oW@)`W~8QDhor4?bg!3=cc;4HJo zd#&S`zUX9~j`2Sk4#Wdpt=)42(Xwr;q!iJE?XynCiIJ=N$W)N11)Mtl17`ga?ou)p!t?NUV zMVEOaY~`Bs&>Ec<@7(P4Y(GzVco${oT}z`A1iYRMJmYTD3rL4Pz}cQO&Sbi|3%{%JBM&Bh#rPMJG|WZraB~oDO&sKaF1vQ? zwpt9-y-hsQ3+-j@BEGI`;us6Kz7P452i=z1t;@EzmDK*Nu=|C!p`p%)QKi!_BYtk>7%iOF-YL?M&LWrN`VK`E!?UA}(bpNvZ#zy3R;tWFSHtUI;24B0e z>rl6at}9(nC7|1fJn8=E_yTt@?oCJ?2YYtAk4G9@QwF;nx}LnW$F0$JHJ`fSJb#)Q ziGCXB{9WUA>oL$8d#vg{O24+_=sG$BJ6%0aV__J2Pl7)Pwyu*jAKiY$ahy+|cpG;g z@FV<6*n;~`HI>fR2^j@wLaFbtSy`-_mPc#0BpDt%1=yub69zVN|(R1iAM;zv? zE}WydL|r0@^1cUY*~zo6e!i_Ep2#ii)zlHj7ghQcv_>jhrg4rp1HBA&7U#|PTd(lE z-ATr^+^ODYe_2|3!R<2FGUO5cP1VT;u17$B+;=0dR^M7blfDmUNS!K?Z+qKXb!reY zkn^4outz%D+N+-BJI`458~U=B70G&YIr~}B)*ktSy@iSFBMj!5E5WLh3TrF2#;B)l zJHM!VtY6h;&c61y_UnA9Zq`?Fh`c{$ea`;sH|lKkZUk(R_CZ^xt@Vq%*s@DSSsm11 zt4tPJX)sw1T6;Jj`W5Fc4{;7qpZ{~HD)P6Vy}us3pBYbnzsA-!uASDm?AabP4E81U z8QfpdJxX5oP|iJ^WegxaeGd0l_I)cj6B%IrWb`4Q+pOQzH=KVwM4fzT)vI5v20Nc0 zvj4UXzYW+fB@apHmfL*BdG>F09iA!GZgkIPzcC54)bYH`BW^8cLG`)NKI}07<>{kg z?&_n~k)L4n$FS%52K%jVa5k?q`_$jyzmK%`v6sFN`=dE`w%n>WJ6b=T;(N+jYW--o z<$Nd@ms$Iar>xJID;=EI4PoD=3+I(1)d%cn*Hdqu*)P1r`kwvjea0H=Tjqrz8(~lM z70z-##&eLCPw*_BLq6YUKaB4csIQ$Gb%bX&>ez@R{xeAJZn6Gte8qX_{qzSgy6A5* z2nT%@+A!H`|JnMKcKeY%cKd9!F@@*SOmsngK{-?0=ssn1r7gSK?X-vUs=B@Q7}w!H z8?NWtpL2iNEIAm^6#cgeK57vm~x2krcekxn|-!c_95 z(fxq4&W0cF0JP-VXhZ$?Lw-TnbFk5>qt5o3S-9!n#{JYA*nM61_sz7+9r#aYEa_{l z-wk~ry{(EpZ{ua_OPgzGXTa~Eu?hD~`ZsQ~4SNMZ`|ifZSL{8C*@gCMM?a*08V`D; zul2ccF`Q4|e*?SYITNev0;%@$`wQzxH<+`uozYoL`kMZ@(~+~RZ^-92woIU`M`^pB zoayw+Ao^Gb#yew`IzMQSg%jkTabXr)-<@?qlAw^Y>DhJK6W-{JcGGXiQ@=$$WA>XvuywaZb?wCuoen2iDQHx5EptnD;Ah&~^{G=Sw4oGU>K3;U&s;r`6yXXno^o z2fe|8{|orvL*2hgz3aNy>34Xilg@7@G`TQy5(~u48*&klOd*~a0oodz%Vti_S$k_`qeHd5zJok4{3B2Fo9ENcA zS!f60xkePVz_|%gi?}Afj;B6`cev)RZsy5Z|JwSTqa*z7fLnXnR~DKt^~J@T1gq-A}#7k-2l7zUhNBhBj{E3@15B2 z<(qw9%caYL>?J1Ob?mWz@WeliJRp4Wg!BbgUbMaMDLm~@KhXVQE8jHG9~5sdWQUc? z9Hf_<)BWwq8D-IZL+g0cvE#P3r~8}kUjvzs8?6&OpF0$9Xw>`kg;Cg_ z$~ud68e_{)w{dP`J>PV^$@|jJtQK`S-yR)jZ=e(3?*tKdgkFcBw?=>C!8Pap)tmH@ z71*rAp2BY%_r6Woe~ESBKE6Te!MOLuzn*(w1-5B_=5_8zxZg$ZThh_X3W(y}a*Vz!`#g?m>;rt6#(G%n|(=+x-aUzq1hct5_aSF_m!54frLJ*H4*W^mjR|am^ssd!5N!9ryiDiCas*?ql`l z8=DN?)$cY3@*Z1*+aB{e4gLL({tk$~Ch;x&f<{ZSB(w~`JyBv>uE(9j_c_zB!P800 zRO#Q6B?DSkOYfF38uLeMi}K~&<@dDr|Ngf}M^FFuhGl|U+QmiQN12^#DkL;V>1R1xAFeHxl<%z>H>JPf!=} ztyTl;-et6Fch=&s@eRm&sHCl*qdk7L+x#f?e}Z+|G5edcMY!*x9Ur2tifJePjhgnG z2alq23;s8d|9c6W1J}U)=yJ4u&7^3>stvdjTVO z2R6bH1a-W}=euJyfHA`N!h8$Wll_^q*^h~3FHXOY7-mku?`qsVkk7Fv$@?Xqjgwo$ zJaqOc&iKxmz7nL!nZY;Csx9xuT7Tor_sz=tZL{~g=0EwSS@>33e?QH<=Kl7%ko~{K z(!tS|al8xrGnfaspPHMPGrI9ple;KSwwUI-%p=YCU5H;lF&)g8yi+we+hVZSAm+2k z*O5i&KSqE49^FFXbzpw{2z>*8J%7*O8oOoz(g(k1C0^UHbw9;M1M#?z`dlx5j!VSf z@jkly@LR;KzYBEb_Q&t2X?+LxRrVQ#bN$g=+j03l3zKJk)BKI_S0TvOG0h*5PCHM^ zIL3INgU&&qIF7OS-%8%J4ekj((Zri84xj5_I%)mL?=Nn*EYfoD-Lk=%ZL#Z#deLQ7 zT^MWoS@S0Ip7B2F^%%dk7|Xu$0r-Ud*JAs3QWCglB=FtpQ1*ca7-_82x6lp`&@U$Q zPA-;rk3aKG*3ZOekH)+N8BIL>KC%Pr%%Az*tUY_Xx!B-aE!JYG>%wDm62l)u@Mff$s zHr$j!6%v+$yaBf3$G$o5sfY4i#8C1v)F{E<1(mRYYx2RjaYMOZ4rNU=l$nuM*59^D zJUCc5q}rdOOS={LD%;-_r|s|X)pz_wc(##6@(;B^9Wf$|fyPjCj(LN5v-uBmnOS5$ zZGLWkV;(e*IA%EJJ8p9v_vz>p;d6=4bf3F?mifHtQ|Ytcr?E{?oA@>t`VaFT=Re7R zp8swBcla0i7yGaEFY|xJ|4si&|IPlN`+wuV)Bgwm6He3VbOt-)oC(f>&LPfW&Sd9E zXS#E&^CD-qbDHx8=N-;_oy(nTon_8foo_lnbbjpo%(=z+gY#GC!QhR-M}m(BH+O98 zd|T*|@W;cCM|6tl5iu%aY{aDzlOv`^To!R_#QKQJh^-OZBYur&jA(J?x~_NK=PGf% z=z7gn?%Lxz5a}No6FD$4Ir6;7)W|WB<05a1d^B=(?^W1}*oE{~cSb#2uAs9U4%jw*_JG-^%MYf&FWZHn3)^+U8o z2Si6l_l{m2{bEc^%+)=|^vvsN#m2{86+5R_N^eJR|GqQ(&gs`>b)PjwO+HOsnuatb zHw|wZ(UjUW-a2Vnw2ezvs&~{;gWr2GGR=Iu4HnY|_nFU{|27YpjSg|lbrd)j`2_oP z^BLeX*=L5&-9BYL8+^9-9B3nL+O@66gKS2c6G5Uva+X ztZ;th{FFARaqguJRt9gO4VpTx3{jzF;S#=*4~at~ToLIJnVvS79#I(adc>xPuOoIw z9E$kOC9b)yd{?pSX;&F-u*FpyDUkt@v5|u#hewWxyfAWX}LQGkX@&205`;(*{BtBt4pBuyQgdNd``1}RPFH>K$|uzs-Kw>Dbu zS{tl#Yo)cqDzzT6imm&t`>cDdd#w4^_10C^Wa}bpyfw@kXhm5rE5ZtIIo@)t<>!{V zlRHoDIQeaJOmkFoWOGDw*XGdXF3p{qJ2rP{Zr|LtIk4H;?AI(!%}q^B$D0l}9cuce zsiCR9X@Aqcrn;uRO+Pm6Y1-Yiqv@-r>ZZ?{-fw!ZX=Bs7P46_l-Bi)^R@0kJmR6JUSC{)fBmxhyX%+K-%x*b z{Z;js)n8gazCNRVRDE=PRDEQM}1g*xB5=?ZR>;To%MeEkMBRWzj6QJ{Xg%o z-@kAFPy2W8|7!oI`#;(L@%~r#KfM3`{kQC2u-|u|weQ7!^XqojeOtGw?yaP6h z;o5I%x9)ji&#Ib}*L0foX6Uz}RiPh+ZVLS{v@-OA(Dy?+x#ucI!vFvG|E>n~`da+6 zJQ>)8biqGB-&a<0&)^AAE=RrtJhdsp_!S1>7X^gVi(Zg{FQv1Oy53KxTZdJ6$oIyT*r_rcS^&I2nUF+Ya{_&0n5*`U)n z2v-14hbH+nXWF+!am>Jd74Eq(A2+)djsmz1_h-mOz{*71^C5pes{5#el%ivAi&mpNlpGw@XBDcVP+;1Zf0C{z6 z)3;;@!o3sO4!EB?>X8X>A$tC_5jy_Ea8uv@$uJK0G-M`B!hJoGcJ!Zz`$i=B^QVkH z4g#O@^&3)veISl@I)Cc;46VaUNS1a~+x38*(;7c$w6ZxnJkjKn`0IU3S&W7jzb zXmej}`yw~KeUXzP8~=Vt>Rscj)4URHz)jjt>e+b*?(>nJgKm5u;wR--!bbcbMiMvp2<|tK$KCkSPQgvkjQ=iv7$5zPw23da zLujMU^s6?5MMBAYC~^JQi-Ze2?rzI)^uw{`#C`<+5uI=!K!!pOkpN$$3r68)28y8W zBgW#UJ|i;WQrxs#1a+rMQ1i1;e z;$DsX8n)v`FM@JLP(J~0ArAp%44_UUeuEa=)D77bS1#^vk#m7I2^@~hhx>4oH&-!~ z;3ki*r{P81Imj}24fl1(ayNlGp0>LO{~M6CZ~!;$6-io=4D>*3MFv0&?kAD4K>rHF zM&w|i9|uyVNb(VR9`4VPBOnzwwj(bD`f*@2l6s9ChnsRoUJSHd;5KA2Jj&}d##tow zq6un;d=BWBLBUA!t_kXZq#s6pfV(5I%1uyrq)zWE{KJscrzR*$g#X(FMI#L`@uxgd zq!$&0n=(a_UQ`#{{gGXPIX8%QkLm&8xX(tq+yqhPC~d1B{^ueGxe2-esl%v?Aj%z; z0{8_{?kEpI^rxsyH$hp*9H5T`(YK;kp|e$cT6Nng-}m`L*0gpCmL)O0?i;`T*SHvKm=La0}MGu|eo zgDA5Qp1{8&@+tTL_WVPI$C{N2=xi;`MSs>RidY8&$LFdT)pzNT_ zikLBLTk!91J)lZ?-L#_te>eJp!){>=4+o<98jm2b_?b0uBcp4fL1Ad>M0x+$+oE zekqpaa-TdTj7%w!74n2UE{BaPjRJljZlQ4#@5OI6ZZ&Q(7%gQIUnU*Ll=aTcD!XvO zz9qKAe z$;^r@OPSoa%n`4nMn*^8oVBz2XOp|5mvyrH&y%}HN0#~Y$tp`*Fxd{6JQ;gF@j=;B z`j+{|zZ|8OlDcbYc6RqN!AzU@mt$(nb+y!?JjwF$Qc-NP9aRTFA{ma_) z$+W zi*_x$U|IAGofBOg{a>A*VBHKIXomK>0NT;vi~^9+=(Ok=*W|P=iH_Pao4 zxzWqol({mqlDlstBqaV-{ec1Nh_k<@(3 zgsfK>!{=Wy@)hM$h%(m|WnE{6**V2xr}#2_sTcm!mu^_DtR-dYUKvy7mznjlQuj@M zIZgMKvS2z|$OIgPlY7vx*;!I%x<-|meNt7K!|f>ZagBP5XCh0CJ};YT3;Lu^E(>8M z<~c6V_?A(A8UJ(ti$k<#BG-$7Ian2=9|IeqhN&wMn3wJ6zm>?%fS%dR^Gzt^0&~0r zU7rkC40WtCxkvjhWsND22iR>>3559t12+9iS!-qjdj1WpFVlhe&h>!30PF=60D1w{ zta$<<9&!MCf!vdVTu=xHxG$mGb|v87PJlGp8IqF@*VSwL7YcG}0lLf9 z(20OfDEeJPfcRaLfc$ksb}NHpBHhDa3)G2(Ere!~9tn^Md92HWAs+H!9qU{_z#UNx zHLOKLfpAv=koQRP7D;-M=tSX;BE6{fPzAMs{b<6Yi4&a)*ojGibjShn5TpID6|)hx z!2#A6DUbzoVJWPHa@fMU!U4pKC0;D?VmAWuVu{yl5TM%&-CpSSs`GTmP-Fr$h@4dj zrBDW&p$3kz772zpNP$Y&0gZh669_So3=?4~P_B5&6;HY1DOY?p>G>Qxf1j;c4J42SjN+^ddKput)ghC-~g99Q- ze&B*6$b?xyn!`wA7-(>K-h(TkONyp#w5X7kqqKy6hfWI*i;~`ao8P4e#eoY@$rCr{AOX% z23fEkxV{M67Zm_{6G8xm3FQ6aKtS)}E&ScOK~Mt6L?-!x3$h^($k(J5upX+Q7Meva z34wSZKbN3;Nj?<8DyV>JXb`#70WpvQIZy~IVI$OtkOj%YR@NXOZ&`BzJ6YJt!p`I* zKzH&sI3O~G{7rE|smRno!1mN+m5v+m=sD=iSX$}a3L68BtPyi*c4k}>>G>S|QgcwMMiI4}2VFj#*Dv_KFAWjZ( za)>hn-5Kc2KxYOzmlOYT+VJukXcoC51mYnTvLPQR&lPKdI=X`T$#uY7z)o(1u&{=u zaEzZ4&xH!uB63w8R6{L)=MNiK6YuI&!0#IB>Y7TCYr_EB*Agd>wDSsKJ=BTJ=6ZHM z5H_21uFC-8T}Qk*$xs6L&&9@E@-vq-ug`*6Pyl5>p60~^?J|#a=Is!f9|y#rzgZ+d z5ORUA8?bXj0+8knRU!+>>w;2P2OFUpnniBJ|3>t0#P&k+u&_qtCepYm1y({iVEg7l zK-`-vIOHA&$&dx)zrY0raDbopE@Hc!uzwKeHf-P4C{jpRA@X+Y-kuJHuuWtU;ft`b zC=c*kMEZ-?LWA&N0UA{t7 zfCtkMNPu)G@IV?RHgKv{~d);yfA$=subUg-{0QJ-Q7Jh&+bQV=;i; z$5H{^$MONYkCi|<)Bw7V3k1U~SO`mjbRVyPDv=cq2!SL>hXN>q6(Ua%_5@*15cdgm zpQwdqktgwcG9FSP8}gw+*zU`Qdon z>+_%-HjBKL4*0)@`*lAE1>(L=yw}P58~DAE1cgAHH)?@AmZMi52ZWWQUyjW;Dbt&j z>CI%A3oBup$Xj8+^;_h91L<$b2kdXy0oba@g#xGs>{sCTHhOOp?`{0wt`d1C29jYS zkk&h;a7^Ug6v%`eC>PmCyp8dY0odJ0{Ed}xK;%90_g)wz!9v(5^8PlF4-#N0?BHW6 z;#T6WME}DOK=;F0PzvO26W5!HfOsD*6xr+m@~}A{Dxg{9W3E3g1g<~E&L`BzbFNQcEx4#)WOB7-0g(Ep-VWD7c5a)IkDJ4F5+2Ix15%*?(Es|F$TxmK{=P|qOqd1h zMYfTLZP?znLgZU?z6}HN_H72_0ye%a0rK)~1yn&TG>d!}0`Wjv-(^D{p#L5E-=Y6q zCG3Dkk?nyH1IaKE(A~ZmRsee28#rw3fG}7kvJ?HCxOu*g1s%Vd5Xo6KQlnCamI5rr>u3{Uhr|ehY84se27szoWb zz*GwG*E|$|CBq1WILLxkKs+-6aGQ0a9E3UYVI}ZaHhhTdGYd*!Bh-lU4F;}#x%O=k z)n*VB0`~nvfp-vo>!4ATe-Tsydd{UD&qG_NACw0xVTY); zgtsM)b}>L++7$yf+o2o0SX6uBwqF4aqB^8P84%Vn9&&+`?YvV_AroOCtb#3~I)wpo zJ7J^KTBwF*QJrG||IXyCGv)0P3~`VJ=yoA)C~-rV!U0iT3GYf;U9r*41?06`0T932 zdQsic3rm7JQ9X)8g_DnP(u$zYT%_f~o{O+ZY)2xavLRnobdIPP(uvt2swXyLQvlgZ zpcqIyt^}GzomDQXH+kq?2o0k8%!Ni#@u{#z57K??;^e`1dC~!4D?F zdQk&H0RI6iL?seG5&gspQ3I2K^anWrTZ76(4GsnT2Nyw|s38eJIoNYiL$jb5wn3w) zBy^KmKB)}}F5H*8(nSuX|T2Yt#0X8o$5_JXcD@f}Ku6b5hS2T#q%>eQ| zleja{zmj-YZ4osq2Npt=sH@Sxx?I#X@vu?UwOLRnDlcEuYzGi$cC)DK=E4fVJtq!| zMa>O`bXYIydKVM{ap#2qe)Drh<%a?88zw>?EC%e{fZqbH7jS(eac?BQTLRJ zDjEdj?cPAh7j++Hy02W+{lQQrsyH3iidvowlz;g)Q4eH5v#63RSS9Kqfp{Pv4;>Ko z@IpX7g5aHnQ7h-dHc?Nb|8%9OXDHJ%D@8r)2PM!fYE>qn`%mOQ(OFG;tCvEJs5Rt&%|=mc ziMN*guRSK}InsEpQPlH+kPk($L)5=wAP+W+T1Obq4{9B0ts{TyYDK+3IL{I4g+f>% z>P7PP67I4jSTE}3Y$zA?${<)J>eVcOo!CFzDB0tRm;#Cn|)hOz- zxq$xXxqxIntiISHY7622j)6*1U&aG3b4zXQJqYJOd#Epgr6jzCka1U3*?dYqH2kUR3JYs`G9@ai>jp((6by627_QC zpktLlofyLFQHg_e;0qlofsN20hDreZRSqnMm9QBIGaL{GgCGO)p$OJP6*P)r20}cf zLN;K-Tmk5q=d>e8M0FvY`~Jp+OAa7)XYN zPz+^2K7DJ%XcG#QqYdR~Lpj=@(*~V3=(Itnjn+9P2JdnWzc|3YUlyR}R|@5DKn#CB za6uAe!U`aN{>@@I$-fiZPU1L;2=r48UdpHUqL?E-ZzWP!3z5PK-c-P)LAu zm<8+LfEYo3;DRK`gd$i4HE>J}*2hNM49J7Euo1QaaoZ8M9dX;GKn^T~Vkm~f?Z^7u2-yhecjCGe?aBJw=tMntst}{I1HypvcBZ_YbD;oA zU>#J6(IpsC0oz?FVTTx@ArKFw8A`rFSAzC$6r*b(#6U7kggjUbD_}ifvuiChi_r}` ztnZC(=yfZC3ZPuwiQk?0-HF?sxZNpp_botJ7-3IJP%5tQj7@77?A_mh^U4JFAwtr4S_9}w1ya`Y+(;=~arE(3Cbwu{3*4*#e}BY}J+!~k}9elilO#263{MbIEdVg``kM05uRLJkmrU=`GgF(@8Le^4GQ zh80i&)j*uV#2Jjv;8ZAq8Zm}Y<{|%!wYPz*s>&L;*ZI1jB7%S*BJvFiBEscEK|}>a zML|GC1w})!?Yx`qIAm2N{hk+`+#`k z1)NX_o8XA(IfUg9mQw?}K!ssSON&cxv_9BKeRW}$P|PS^+dG&>0D;i%|y zGN2f+Q62~AnHvK5HqReg;GF35(KY{==oJNkj>=p(Ao>F0EZ8afLQiOfv!YiuK&R-7 zGGHqlgEOKpMrLt2>=S(npO;ia6JTq}Y0<0ES-lI;vD6Eqfcr~NioT3{%k~1cm!WTY z7Vy2s2au^D{)#%_UTqRI!wEpwN_4HPg00X2$kv$<0!}D|YCwKf8MKSOny}S`ttM|MmWyBZFOevcFOiM|t^JJESB z@$YSe4$<%PgbHW?;@`Ii4uZOOTJ-x(2my55UkK>DzX^5#I_^IVCq&;>0p~>D?E~1^ zT>zwM_a@j0*x!8wP6BcdAol=r599#;K2Q%^p%o6mQRo!=kJ&sJ#FcxkUJwOYPzH6- z0{GF2AFcS&dRFv@kb4NZhmd;+xrdN@s2O&_erShNa9;F>{UHHzp#mD91@^!}=z!Cr zKVm`%IH3^gpc#;R1i42}z+^k0JLMa*rYR7;=vx_gDv<7X5J(Lcj@yPz_D61KOY+PKmx3xxL8k zMQ$&0dy(6V++O7NBDeQ2oPe{UKj8&YkOgH>2hFex_Cq_Ig7cz3=?@8z3l-1+EwBd; zLI<1{{V5YdzzKy=4Nb5M_5*THA=l;wQIHE2&;Tva28ZDkoEQD+5J1<{Wl#srfUc+a zLpvb%G;+`QLjn{+H6Zs4a?c!u4md0NvtAGdSx^RbfZVglJ-Z*;;S`(~eP0MT0l9t1 z?Q4NOa2QU&S<#>Kf+)xWCfEUOa2QU&SGN^-Q*aiEc9Ztb{(GU1T0^~vkG(ZdNfrHQi zr$v9+gb;8-Ayh*X?0_~n3@6~M=)dxUD9C~`sDozM1^b~LPQiK6f9($mkP8*i04=Zw z4nhZ<7X6?JA>f2UsD>uk0c~&?PQY2wf8zyFkOgH>2hFex_Cq_Ig7c!k;tvUs3l-1+ zEwBd;LI<1{{kJBBfD;O#8k%4Sw83FG0cS-&OG9}*xJ zDxd*cU=JLG4md6Pt0shi6AGaknqUXC!C^Q7XGMR_3!)$k%AgLKVHfO&b~pv+ML+Bh z36KjFfb8KtKwoh92+(gFJ}3I?^c%0o0sY47z$&%ArJ&f zPykiX2-{&V9D-wTM)Ws5Aq+C07;0b>?1X)A1Wv*^(U15*9OOVbG(Za+1k!Wl1e_K9 zEiZ_IEGPrg^HwwLg8hK(TgbkJ{r|7LjjgvsAOQ-X8u06F?7dAI-aZKU|BeaBypszR zfXq8BZ~)GV-j0s;3_wSF6>Ng-|2Mx!*B_Ao1NQ!at#>^EJMUHl`NtZm{x0b}iv6Q| z;gIO>#Q}c2hY#=Vfp$RVk6ysNKW>Fi;ScCS5F`OM{zQ8IbVBrwFmOT*;C}};I!MEx z(fMa|zEAx3_X6SXpA-E9{9(;i|DYaP;V_*3?;MK~{a6On!4c7qW9vBfk7N5o^n8eo z54Qt0K0F5K`ip=+#6cDmLp3x)3t;yz`vHA_LC;^#h>mYv!D)k0QWyf_Vcr% ze}UW=JK-pt61_7H(ABvY+M!eQFY)b5;(kdQzVd=i&<5Q9>ZI@oP64}L7XbIZ-Uo*P z8(*Ih{j?`w=bLiTzuhJJcP4~DtLSGMME`pN;NRb|`S(Mj|C4l{je~mN`}chQmjH49 zymj|I4}B-&7z;j-g)j_C;vRIj>0)HJpCaHnt^+)X&QY@2!aeK zggtOTjK0Y9-3jXRF+i5JOoM%UqhB%90Jd4jH2Ptq-$^mN1cD$Aa-a$t0XeT$I0T(y z^cO%^f8_cXKsnR^vi-NhPS^)Wp%c!D;f=g^5+Lhc51Rlv?*niIjsddX=foI*+<&R9*FEf6^_1v=f&^~0w*Bjw;j0W zPndrN92O%W0q|iE=^BKNL3_jq41of`*Ff|IVI!y!TErM^0`UjuKs8`P z=h$XAAx2yf@I9^os^PF0!=r%D!|```hZrNcKOz^fIig*R_zb|$cx2y zAqTjZa9WI!Wq^N)p1{3C?j_bh3y@!lC&d`$1x_f2I@kfk8Ff&MBmv?jl>_0U(KC7z z5HC3g4gmI(&xw)Z59moje@ZKmPS)=XC;FX9Kzf|S% zLn?Bqq#+f#RAkc7ot6dF&;tA61e_NmJp{OyUI9(83l72wF)~a@fHL4-#vW*gvto=1 zfm}f67<7(7=a>%Q-dKNdLKzTm>`5^)(Ulnm$YybGoEK~rBRc`kh%p{LIfUn&6=MSF zpKuUJ;{?7>^no0x2jWlM3#Y`G6b4y9x+gWlPB;L^fOxsY%SC@~0iZv36YK(Ha@*k~ zAeToT<|RQnG{ZjV5F=lJ`1xf}1EeK?JL~~;Y za7>J80wI9?X~dmIylF=Oy@lK>+d{~CwWk=wI7|Z>k84d&S zmLpe#Tn+xz6ac=|;7dT}MXHRr@wkp(rt{T1k2aRAPUQ5y&NQ`-pGUg-sdtwerh zIUu*P13Ja1GXXnw1yBvxsl!g)F*qy6Do-(1qkD}H92BD-UG;m#SX%@8;glFxoEPIt zbXIdJ=X<6G2qj6%D;Q*KY^xTz^K48**R=9D+_U zHVY88xgOBn%;)A!z`Yx>b7LKx7Gp~;VB@9&Xn-~`wpIf^Y&{BR#ke^NT7Y}EBtS7V zigBwK92TR6?=AbpU|rO>?Ti?=cZjhq4$!;pycpZ7pc(Mv7s&i#E1VGH4*b0nJ$IsG z2ljX1-;R@F+~p5t!2P>A#kjj(jCml!)u;SWv%_U=6^#(mto-xILA3mv=K#n|nH z4ly3U-v^2F;2|+u_lWUO6dV=fVd6Z3o=3Keu?N{b=f!xmRgA|f;Gh_fqv!EDI4s6q z@@g+SpC}iDwK3z#CP4nFYCvyWA&{=8bK!^>&k*mK17bXj-e+6H*vEBWn;6fP0lJ?r z2IPL31BCBK@BV#aypRBVegT^=hQKB`BgRV&fc^u8a6*iin_#~fzls9x{pze3zuqdw zLGJ%1NQ_tTVu zoHshfc+&~!d6W1@kUP=^=+>25Z;dNcKrK&7*s*K7=OqS<6R%v3g|c* z2lZmSN7#G&pi_)LR*S*h(D+lU7#$fv*q>M@!?;MfZV_Lh;c4g z)E{9ren93&;{Qn4e~5FwT8s;%@4{g*Tw!8#g@`Eya9T`l4;&Ly&wvIvDW*{&rpceD zG}{0fs~iY-@RwaZJmI{Uo=3#&a}dso$vF+P?_n|faj)MdF`2LM$7A7?nBM3b5Cq)! zDS-WA`WC_&F$dN`r zu^D_+%puqai2`hf@O@}5oDws%8ju;518qQ@Fg}OzIXnxHjUerj#Eoo$R@euJf%s7- za4)J5&=W-(qVS0^yBVDTgh$tj86!{y9b(2N!CpW|Tn6j_(lWdZ&^ZFR5p94k@qCWo zFJ?j*w2C=01a^s;=nu$@5+GiZ7wiD^jK=5WayThwN+A$0<*b;_1|a_!Bb%u$fS+lN za74^>wj$0cXPtnL((@rb$XkeJK2idmB-=87OOYyAQFm4wxy zzmCtV(6O30_2pt-;UngiB4z{E2Ewim6Z0B;xaO>wjl@}3C+2$myS7!#CepW|O3dqa zin)>dn>xk39$h!IiMg5UjhTe{oFAJCM6G1P+L~gU@#n=dKPh@5c5$#bWM^gOg(3yIsutxOX3)@82or zt_(4EqjxuP9>^8*L3Fg{K&O}wwTSsJVGrZ)Bj?22b41KXYs94AGaox4=Hq+C+}kSV z6ZK*~iR@E_a8S%PWS&OP(|mr0@Mrn{EIRgK@3{&%FXr>7#Qf!cG50r!`2zmD&>`lF zhs1md`2+a!a+#R)S>~_yi1};c{F*oio5lQ%6FS9w1^M6Z6Y~)Fe~0X=ChQWE{>eOi zLd-X^#C+37%p(b6zJ>m`qr`ltLQMJ`vz@rVKPcuOu=6fqN4JXkUZI$O3=#8B=%G(B zJI;vt=W}Ade^ks5s>M8(Bj$1Le<))9B?-=oc>*0D;qPBt#rzn%Cz1Oba-TSX`=7!o z^n7+m%+Im)1$H{Oi}_`hm|x+?*ZyLj&K2_;FEPL6^S2#he%B!8nF2BYPWV5{#r!97 zXSw&iDdxY>{qK4)&t-}ELxz|?hKczfX!w`c@fq>2wKJRZWe1mg;+j5a7ZlQ3^*m$z!tIm z2=hB4mOuIeJb|!5ae!Q4lUPA~9*ph5JH-mF7i$PIL-vXlf}M~fVhtrM6g$HdXT=I@ z7b~3bh<##3a*g793^rnO#ESEWqhirsS|d(~6~9ZYgiT_N%oQuqDb^_DMsnq@} zSl8|mtEoe*4Nkz$b>(7hj1p^;K$}?CfX;&Dg!UU94N;;E-6i=E8m;tc7^DWr=lr2pkh@8{fB`5Nmr9aQ#J+WWhyvo@g+F(l66@|3vF<^R`Gd7{yIA)I!C^Qr7IO&eKH}V81_#92h1@RE zy_@R;KCnZq2f6p)P9VIs0y@Nci0ebU0R0b#!6rB-)+5Awq*bgv0@Y$Y%JtDYu^#gW zY(5?Zd*GB^by2PuyRk z>z9Yb+TRSM<%LaRy-2(lcZ&5=u2=_xV6Rv&bN^R$V*T2LePSJK73(*Iy^;jS#QJRr z>=Ek_-w*8obo~x{uOj~{;jcM?IEMww#d@9a*Rk>XNwMA_&KpO>dNTt$#5&Rh+&gkg zthXBB02~wR?F6U-?7!pFO^aCVL68I3Yd;~@@4cWJ(D{cb*e=$)o^VvGqxf<3uvqWa z1GfHH44q>AX%pac#}2XnTn4RTy&necVttS$)-e)%e>f=CkA(f$0OEu(Wc@t>T>&|OJpGnq(0*|QCc#N@1RWH|VB~`F zDVY01>VRtqa`at}p-$K(j!+Xe!5MK3Yl8FQ2tzguUEx81OoYH*aYT}qNW!D4#S!fZ zq$8ToF=22>9I=h!h%18=;uzilq-z8|#)m*N;Cn(AYz2H6=>s*;2G~z51necA6~`z( zkK*2_gFw6_bSI&2bgMX$lb}-^DJ|k~mcw~*q@pj4IINF5(y^5h1a0CN!~HQw#WA)~ z9GNB%mX!cp$Dw~5c9{b>#&d7{UUB4bFNd^Dr~q^^4{%IG|D+aiM}SzY4K8{jfM@oDxS7 zpNo(!LZ+Cw#n_-vb`&FDTmze6C+veGa1zdmW2O(pK@OBdJ#2+mH~>eX6Ob)IwglNy zFK8D>8FFQN;Rtk!W0og`0lH=Ffqfn#t+9196wxCyYk5SvweuWE$-!1qObUxbZCHGtfrRzT+>;x8ip zVowNz3_xx%a*L5$yc71p5jY9w#IeK&;vfggp&qtED;$8M&?$~;fgnhN0;qyr;#leh zd|$c`Nc%GKVHt6jN5NjeMokSI5yuLyE4bEX0C`c1+{!R$gk$2U%K>ES+MrV$tGKsn zuQ*oM1G1~ni(^e4oDxSpwi(+v)}m|eL2+Dx-78uExhr!4eGTYqAkVG}fmU%`odm?Y z`m8vvX%I)FCt$Dfyg1gC!#;7W_kt!kBaUm4X%eUczHg|8qvE(O47Q77Bk?!xfYajG zMEp(obA7!yZXj&)VR1B?2eP-xT{_mDr-0AUZ| z=fj22DUL^+&!J#yHbf>hg>B#rTkbQtf8swbhYufioqL9qg?HVcI}BYC z#mV37m1uv52d*b-45)b!D5 zf#k3yL-}Ra`Q%+6{!;N^iIOC8FnLgbzat{XnHCt~2=E`2lAMND(J5M_X5WeY>8&>l zmQ=SatpgSY~d;+Pun95!JU>WX-s7Sn=5PtNxjpFghl7)Zph^bJM1$O_?!z zV8p6k42g3WFZ=$Kt^_TTa@$vxL~<`MGDdf%old{`=JaXh<@)iDemM8>V(B{V zLRSp3;+74JB#&cLLN$L!Ww&gHEvh7y-8k)KZ4R>DO0P$HphuubtVe8mY&1&*Rf8K?B=gWk=5_uYK0 zpZfRRcirim)3r(tNsaQKI^-XjnoY5doU>v@V2l1qIzYxcn9!+)L-)Z)^Auv95FcqGAYXAlxs-i2N-5n{+C?AJRI%I{2mbAM&+7 zb*+xpTufKZi66WipN??3wVoqjw=QV4uxLUi~b*g1*zBXs>*6B$;u9jzC{Fom1$3|Dgo&!zLEUp@MYP7W6QN4#`jMwxj?nlgn^#ch1_5)rlqK2 zH9+&$Ji-IQv$gS>D)f;N9?2e`F1_yV>IoSh+EuPNN6DIss^Y90`)cq0tD&N~BrS5{ z$T?SS9Pdn@HKyywq*D=ufzlRs!_uD9*{iKKpM#0$sA zfN&4Di+Go4#imeq+zH2bKkbC;ct~c!vW;6;4$m7I?dNM6<-@KhC@q^jeC)89sru`4 z-iY74qW<=QgNF|rHPH8(^1`C|L!?LQ`zlw^-9o~lh+u&pG;XYrhrj9YIgx^79$P1+5m z6LaU!nKZdnJSIvGDOJv^27R&O1;Ag*bn>w5k5sjaSepL|y9`@$SbV03pL z_|eM5p}^hbr8;{xF)^3Cb3{10+d=K7^*8?U#&u~Ut~q$kh%4(SP0C2m9n)MgbHb!j z?W(cYELwl}_dybgRex`T zBHmpp(rI&P-cpi1Y{T|*&@PZIIlZ!F;vsV7yEEj-rqU8^E9txF5AQb%g3`Vd#3b_?qI^=MQ2rXzeo|E#;uCf|lqwP_~oO6mxRRQWc@ zz<=#Rv@oA52W8) zI?pTAKd0usZ4Z2X?7^ZdLh7$*`s2E?sS}@{`|N*a7p|`Io>-V)xoc@z%qtV-r^St5 zJXZVO)fqWpVDRnb8(#cs_qNx0*$)P&Q3Z;>c*8)=flI2;>OJz>Ay68{DwRB z?;kZf+dp^wr$-lDp&yUR%p6ufYDn2_ot>^<#ydmD4_yJqqzU#&WMaczUeNUh&#oZSbuRJb25&wz~TIx;FjztFE@! zO19r}>vrO5GLN`RiK|A70krnM!2e#-p1JV7_JgZhyG<+nu|z*!@@2_I`ANvzBhknn z=}O9cgI1xkv_}-(38eXT(oFmB=O0Qh#xNx^HQYC{yP&9!t*0Tp**j{?f~@N6|EeWr z2G;yy$FBw^Pup0$;UT|;1J;%{v}m<4)62#WzizRAiR;=$4IO)v7S$G~u3wWs^AX&_ z77d@?>`sS<1z$CsrmNFqT{l-&YS)16o9lHg^Fl20O!(wgKR_^S(4q2RmH6Byi*u5`fES}a!IZ2gk7A{z|FeANex~^ULXyNLbxjCb9a@~HYvUG>r4_XkS zYAJmfEVkjm%0|}*TEc2qm+))F$6edBwXP3b#oE=j&0^vO5YJNnsORvsR^!UVsdZ#N zJ~8Cdf8djsNO+{75;%k|F49-)Sp07J^~XA{FV~k`*p2*+`n4oviAqNyakdbLXQk2W zt4Nx!zGa2$rt+oQ20Ot;7oOwVrk5eA+GG85o>yP-Cx)G7AJvpZM>u>2*%ey<{7~xy zufDpw^>?lZ8*bm$x$Sms(ZlcmNt^wrjvF3z{o~O+&9^+J@T>55n8 z!;=SDlmcf=yr!>MJO8svZDie5uA)~bO`A69Ro$pu>v~5&zUI?hR_5LQyl(sBt$KIM z!!9+pL)6RIK-D!X$7qdW^^Zoan7sne9@zcb@(1P?DbE_RvZiWd=cFj_{`h3u+Uuvx zy>-i@%FB>!w~v(=c^n^y^1CCVg&GV?c))=Hkul>m<)hnULSxmp06f=&!s7iL+Q8to z{$sPxRBFX5uS|7&2h}O#e;%8+Bj~E_U8krP*-JDk_^w+)(tZxb%zRw8Iou zZELmb$LjarUP6JpM_+-=AR6C?kg>~jKP}QwV*Fq4T(umIkNby^;!)qE ze?#K@^lwzUh_B}P#1BlRa>F3vcN7>y3(nKPDgP6+DcTc^naEea6hD>t*QeZ{w|-ro z{<^DKOK^2yePS2CmrSiuBaMj{_Fk8q?2bQ(Ec`-0Ww(2Qk+C;bW!zIfMU{Q}h4_sO$_j}Z9WyRtY?f7;S3Y>@)T}gZ?UPgTUG2m5@qMD>rk70)j2SxE zXMjgv({cm{4~mH!ndJK2lo1QOe7r^$Cn%rN@Tnhp;%(1NQhaT%R8fo#h-ApzGb2wc z9kZgQv8iTd=Cscy78g&rPcoxe(}NY7lexU%-Ts+D(bykXa3 zrB9b&^nHhq0~nF1QpNg3kDfqZ1EM*D7RL{VDp`fHcfrQVraR+fjWJpI_b(ed}* zxZ$3e+5p$t`uP=WR?lCs2EB2lUBgd*HEM_s9~7wCI=7Q{GZ;9?3h$nv=$h*~ZAg6S zvdA)@tLLrWw0YIkwSxm(o3t3MY~1*guL|OFSIn-uOVjV4nvYyJ2zvzm8Vhab=FK`v@h{7 zM9mxmdxn3MTz_v}l^S~zMIq68=fn3EP1ja0&YnInY2lQL)gH6F*Op~RP79wjV@B@8 z!fAo`Y}oX`{6g2%X-j91D4SZoaM6(D1nslc3l^?gxnS`sx8M2r{W*EgjM-fn1Moe? z*F74gv%7QB@SGW?rP0$e3g?z;E7Ow}6}vvBNPL|XJAI<7!G3NN`S)&g*yD0F3Q+Tc zyGvP9^SW?W_xk;c70Q<0^=(&-+>4x-_^4Xv>rd%RwHrY-NysnV)_;Ikzo?<5rNp~w zl`&Z#7HdS?ku@2MfBzz`8ejRQr+D~98Z3bM-uBm(FTTJ0xtXez&id;Mt|zpR;&#ON zPZQPq?X>+OPNeTn*7z=tO-Q%?Bl*pImDN3!+`yhR``VRKR(p+q5gT%g8P~`+%v=Vo&I>Q`mgFMHPO}?ObZ$5tC}}=nNLk|&o@;E$9lwf zJ*`UC)X(zl>RR-nHmFoJDzoy(+ckBb-Kc273`CoNPWl%LyImOFPe+?jR#rAWYEoRk z0PQt>>T=f^-D_cHiu&dA2=eJ2;zTjd40W%C#EjCq*Y#K|bI-QiBLdapt#_p6rB8~9 zpHVqw^^1$Oa${LaR$@x=jQp#XyyMt4Dt%=1(1^Z%gC=E9nNv2sEIukEk{<`l<5B%m z<)y}2@0a4zciF2-ltJ|@+--ZRUF%Z)sGQGv6aVPHV~C zzTMU_0iQo%j!fAI?`i1N0NJh%j4wZ#7F|5Ha6W}&!i>@>&V(5gv>mS7RMF6eD<7Dd zQE$E6;{tcLJ#_wo1uZ)kugv7p(mp?G3@rBrs33=I%=VkTD z>yw%Pcy=ECR5ONX?QT05LR4pE>BoD<4nwi+;9i(LzEFL)GrfDLn@VS|oCpl?)|5+; zLw%x$l#~pK_8H|I8y+7YKGxZx>^4SUZZ<1VnZ@oj%}YD4y=a%M2#-kBCJoc)a=^uRl|8LqiSH8 zRXb@_>8j#>kWVO2C%tqjD{Z`w6CB{|e^*WEh@#5h{F z4oI1lIX=85C@y})n5pqwB2zPx@-l)}&y4W9dFjy9?1W)jx!IgEUGEo?kljB$J|wmz zH+ER)#Eit~iJ7w#W8%`sj1HfFZJ*H5bH?09!>rOjNp7Uijb*eE!??hn7pe7c+Ay^S zP6HXpnz&k%iS5{(h)G*Zb2HNWzvOg}tsczkO5 zlcVF4(-T(iT2z*r5R)=E?2d6st3m@;76&CdV+XH!Y|4~}V#9*H^HP&yl4Gulm^wOn z^3ar&ysE`TA;F{4lcEPj1T2W1ns(*z2xnM9mFJKVQmF0j%jo)N*H`*?`se)WWwe_6Y2N0=4yX6(&RFWqzfJ zW1`b|=qU>m9P#nagwdltbZ_7O2|;0X3w{~6-m`Du&{1)8x;l1iwL54p9ID5pyajj! z26SIW?yRj%g-_?MFXg{=?hEBFPG;+2+BNnXNjP0rc${`F-!((K#`W=ERDJ#L`!MFk zXE1~`C-MuT%=gtc1e;P!_fwsz>Gl+#A!M?e@24cw{l{xD|Kk(Uz8m7F1r`m^LL;{1 z|KYYk*Y(pPc3GfpL!-*qU&4zH)?5^{JKZmsJ)>-^OG@^Gi}hN>4i2bd+ywvadYP`n~{+o6PKYs zGdDY@d|uPsF&Qzj8R>DcN>6gv_xd1x4Rv{dveHw7Qvz81V@=xL1$&oO=~nkfnCpJq zz9xR`aOG3?nG^d(c&j}HH9d515~W<)BzitL%GX27Ht)30_1t`@rW4T}t#q?~?N+T?FuOMN>=Ut99GPkl z%$`V$9BUGNCI<52G)qfL^Q*Of!28Z`5>H4+{?} zH8N|`qDo80j%JiI(sT6qKBc9>AM2exBOO=aaP%d073qCx!&FY&eS_-a8A$U#=~}e< zh6O*4$tlUv3~Td(rMKpsf6J#o8+&^$w;s7775ix=N2gD4YIA+w07SqSW5$qT3=~0oPM~1~G zN8nqY79yXM=ZstYB2%gHYGZKkk^yN^{o}Ls+(gY9n&h(Qhz9$uqqJPRy|8EDs%-kH zhwt8_VN_28>>ed#9 zIumIF?$lnSZ(pSy(!&mkm@9Q=~!3R zSl#zvd*Y-?+1FomUwh(0Y-6U@*L5bf`rap>RBfNqU)ZgG#80(r|4YffXzLxft^Zok zd-6^h*S7w*Qm@h)j4!!%xmPPL>Hlv_zdC(zc|QE|zt;!tN!wkIo~-#_sz>T&nZ@&| z>WbBU?6FsbUa7`jgxPy6#x9>oeWmP`0|S}u+0XJ)c&+fu$Ug~x5cy@&CcpYg_%(z# z@w>`T_6pbZ+l;k7ky6W#{XA-iYZvXlf&6;xzUr2zJ!4E_ylB@kW+e8W59@S2{~OE- zo7Um_=d9&gyuR9Xn^xs&)oyf!R^Rge`}RJ?k0n~1w$Swu<$WfG;)fwe$XEd4W7& z;6dKF!*>&2E6>ZzKM8+;@MZjB^-sea>^$BtdoRkXTzJn=dRBIQWy`Y!hyKZAPLLg5 z+x7LOaPFv8b0xowaP`dH@@g&=Wn7{3cb$>P+~GVcfBaYbRQ>oBa8<9_qp`QD!u{xW z(|qhT_JFy0d0Ox-4?J*->+{N|SJv0BeEKP^bdoknZCh!juCDFcplyGjWcyW!zAeTw z>^I4qaxZp9+u`;;hH;-thn$ob31{&WZ{6Yd6J9Hy$xA;8Z&m4_<^AQPfM7TFA)qv|jW#!SD#w+H2_UeQwQzpFno8Rci8`mzGe^rTlONcz4 z)b)2gQ$ME03Yr?Eshm-3Q}#(H#w9(6OVs*YDm%AY%>6}EinGhtow%MI!2!;kTdwdA zA2jI6Cw;W1)~1Xr$am?w|J;>}OCr*uy!(1DOWwHNW17M16Qskv9)8RxLSK31S#m?I z%UvE``#*$#fc&!hfBa1Tb;6t0p8Hui@={yh@2BC0iTwIH=?SN-;Eyqj^`cRnq+{(e zTD3^-^Vi8K^;&du1?iP=MuLr>C2a4!5&R`;!)$G&*=`G^@pPw`S-W zOEU{Af=A>}UKVwAecv+2+nYuWsYshr9~^LDd;Yx8<&!hg7%#^Z=dhIQoEGh~V%DOS zx;EBXHaTWYRFIcv@X$dsDxWNgNnmxk{=m%OrTu;TCd9>#JU_W-op~7J7q#ZjTskn( zv{&1D?Rs^mqt{rbcXRu<)EO}WrdogZ=(Q+sHB|KX_KqH*hB!2|zC+y&tye(bjB&*Y zfvnC~vRJ>QvUcNwRqi%6eE7vS)_#ue_4NSJ;$DKrS3i5*8i2#^UrSm!@2%whu8kTS9sSCl<6S-xGF!Nsq)q>Pa7&)Kb>+Y zwI6u(gj1i~>#Sd}3Zh0b?%pWIUI~azAEa84P}3fy^;##58ags7BP1v`Hgi$btWak{ z^wdRh^Fl}D$44}M()3ODTCAq$EX|4?&_8bU$k@2Rp$R^tMn(@0jGSJ0W%f;X-l>&b zT%e_nFgszb_*GT58@|W4ncZo0`=-*ea+L}%xh!1eN$qNt_Me9@Tm5tS!%F|^fB#G# z{ZhNCe@{4dgqE1IHplqnVYkDKRV`L2)Iz;|;wDC&_Zg6%|2UU=`@oAK1G_%aeJPvW zZLroo^XOhvQ57lO!=OE3MZxlOx5c{e_=F8>mS>F%o0xRnnxzxQR(u;jKEK%Y<#)sL z@{6^u$x~J}-<6#gGIjEm&38?hu-Em^q*V(izNGbcu3DI@+7S0Ts+~V|D!t|1`Ex0} z_P>NLTcgUx&*Y`HM&(0KxO-hw>93us^j9eTlo_?2-dBJ7|6ETm%~-K){blRv#-6U? zT{rw}J)N{%v?aB(l@GQp!rfy+)jzLb?DqtB++#&|ySf|SR;)frXivN9mcI@8M&zIS ziM*pQZq_AmFzAe}X+6updcVXr}5wjbK9y5|hk#m!MO zJuSsvyH$%Pem%RRlN|5ZyQ75#F~K8-hK?OQEP9M%=AxoX-{`oU)Zq?ebo5nYGp(6F z+anDfmySa|3E@NI{QFK~yEGytB5*(-OLGh!GHAx-d!^*Jea6T=PLt#II4#C*=iK|9 zm+G8aQBY;jEw9G%%j8|VpYAQM>fEv=AF~pBxqLJ7>*PZ@z@6Ums;sT6=>Ic$HU3d_voKX0lnXF%kQ)0S+c-SwGR6{?P8=1(Eg#X#R4Nzp8x-^<4N=> zJ0mGigY4CLmN!{rVg%N+H>6fNQ;c3qs^5+uKQ({xvL;nc?!LS9Gj?=yCl(j!x20a# zn_05^hNgRF+?rbGIW_Vn1OhioZ@R0F^R=>W!o}PW;Lh3hmZ);zt4NDq5 zcxkky_O{Ijhfhq1OBxz9r0>W+NpW6-273EA93Gx`Y9^cAX^RKg1D0(Lw!GCA4CTq4 zr|xq0qFv5<=aH%>%bQf2*^{UCIX2@apC#0jGg_Yy|st?e=r)l;_dbTVB~{T;wA3a(Q>%`pm9dz2)t?Rj%sRMR`|;I$P%xtG}VshyFzW zSJ-`Cd(_@XAqIYyQem3yx#Kc9BKy(A(i`E_J?(Sj9^{wNcRo+}G`nt5^Ynd`3&WnP z(Thg2uM!S+wO}Z%D#t#SUK7;mx`c#E*DVVYv~%<372L~z`7VcQM71B4dUc+~-m6!q zBQB2E?b>ATA@uBDckkJcA76U+-9Op4FHbEjOx%Ob2>tESr}~Qg@?(74-4n5Hc(M9CplVOxg7i4m@AOoe3$YjL z3ug>c_}m}*^^$G z$o?qD5DA|yEJF}pXv=d(QtxNa@s`Okd695-5_m2rIV;hnzw5*1xsukGwSQ&H7g1h0 z7ipJQr(IqX?eMX#4s||4g=^Tw*BQ32V{!Oj_|_L+1JczQ%4phSj!n4EXi3XmE`0y% zUtQ;2=Z+oIz1-zk4=|o0&9$suyosJsw*DOS_;!b%vcrq)@M8Soyru0AIdD;aA}6RG z>-Gmp!n@_E4*`tXWAzHwQU;M;w|>Sh8fSRyaQ-$1;l1TmzOB-~`^C7*S88I&Ecekr={!IU0(7(Jvjrn`@Qv&pb%xhxw ziVytBiJ6Tm8#JlwI-}pKcdF5%6_Kd3=UWa-v9-m=-!fu_emI)5AJm) zcOQS!Zfls85bmB6*=@~A)zOX;|u**kG-?{MNEG|MJ3;Z%e)}nYzF~ zb>`N2Q&x|U?cb;^ZS;=KS&a{dO1rUT5%3pEmOAHT74oArt)drQHda0PZR zSX{6dEbQZLbDOirZ(iHfwDzWP!@fdFle^e(btXYKIf!qJDQ>c-4MJZh6v9d-0j73!zF&kAC}Xu)Suf*1cck4&x^D zxX%ckQvS?Q^0T}Bam%~M?rriCrK7j}QRJ7+{+du*p0b|QHNrl7%xK{MI(w`S(3tbO zci%2w_Kt~U+1ow_|Gykd4$8cyY=F17d++Ju3b?m#zhQm!gt^QA*Q3gDdAads*yRi2 z9*#W2!*A1kkM7gU>fF=_``lCxtB9fh*SRSV$A3@Ge?L*>OpGb={vQ*u*ZA)ztwzo8 z_qBfJ{$$@)cNua&GgWVw%aeAQ>;24B`@6hMtq=A*vw*I6`;2zPPxk!O(2KFTZ)C6a zvV*<%{=zuN{axV24ZvG3ZUD|#C%Z4KOYhzWq+ED+4b`GK6Gm@#*}fv%8(2}VMydf{ z_u##EPEPD)FeYvU2gYXGr^iA9{CYMX@4aZZ)Ep6IpCRi$Qf6tRdR(B42hd2(?4I}i z!mcaqz!1)PHSIqA4f@If@}a(f(maQZymWSb0IivQ`h?7|-Hh~YyiFzjw%aPTr3D|B zlzdn~2e?$l>C=7ojgz#Dq?B~88Hsu=#XiMCa$U2Fih54L6&AYB!EGGsE`Ty?*mso@G=0Kk&F`J;p8X?h}sKeL`<}do85yB+veGd3T?1 z#O@P%%iC)qb^rO9{?{p6>*Wpk9h!Q{yVsIyRr_(de${?#(7bxB>EpjXQ2&eFhrHOO zX6Gt~dKVzYKF`k{MfW_>ZniJm8~5f73VV{L4;WJz5j!Sf^WFCA0hQ5CXS93Z%e#?5 z{WsP3yeOcq&N*X}oI}*`RoR)qys;1CKKg#m9zNUC#_q*!UPgC+x@1=SByvR5u)ts| z)-!u*)u2m<57pS#KXYhMNZ*l~XL5Y@=${-$y!}@#V z!7_QZ>omE{jFE80X6$S1w8Ni~UlN{Whr8Fm>^b0UH3#fj|8mRs-ph2$Gv3fAcaOtb z?ead(*2Dh3_7-_hTR%_bJbjcM?v_Un>n=O(eW>2@_S~>o&FL?fclSNJex~1UXUbJO zW6P801F@^lfcxeA`&O9#Jyx>iChv}@F*Zo^(Xv3k03XUtsYbUBNb zUfZ;6asJftTGXT>&ghqw>9;YjyLHArO*iZ=$<)hJ53j12TgP&VO1PoUN*N;<-}a&Y z^O=52tq|}gj@Yl{MMtPn!^QXX)M*i>r4e?$PD|m%*QxH;^0a(j(Q|FTcHCs`y6%_u z)Ej&yoJG`q`URD^U((a2cXo!~H+n|T`+F04neT?NfuUNFrJj8;&#a#QUpE@@O|7H4 z-%IGL&M5G9bN30g7|nhqu2)8AL%QEb;3ednTkZYeH#U`&jLRwJow2VPml;bo zYOmeetqVV~z&z?FeqR16g>S4j>7t)Kr=ByXRbF&c^Sbmlg{_-BvDXh7%k+~N{m=Rz z4v`Ud*f)$dSyAa8X_6QAy969{?RDDC-d?}>%Hu5s!-~}#2B9JU%d3w?nO2b&G_>R= zZ$NSemoz5o3HCee|FgB;uXboV2A8;P_1aA8e#4_o`!<_58!&R&dmf~8Z}}l+*6Kvftp0*iS!= z%^3Wl{y|5{h1mGK{IQ9{M+R#Hh9vwC<S39p*{l0#|+%+7hcco04xBG^TJ7&K#Mb(d(u1xxkD4%}D1U*gnx61;pX3x8& zyf|h5&zFC7PnHjFf0Box|+txYPvb=5C zmiLw=c`sSsd&u&3Y$tKz*v_8LBqR<=7$J}Z2n1-@gt9&;s}yLVtfqX05(<>P$}W^0 zW+{dE-v4>exssKT_WJ{lqocFOyGH<|Px@UVe>u=5#0SE>Rq_dbibG*E4f~@s?u17j zNYe;~_0HN-m$Yk@pS#>dTS*~bwaJVQg zH$N$@yfWR`waNuK4CcV0FCl+dz{q&r+ci_T!U+$M`O@!Iy=j(*IK;Ld#fH_W9j+>6 z7V-4>0gp+rH5DI-kn$RsOX>>nOFj z-&$b`Yym&#dwM7Lvb|(DWv>4E{)@BiV5@w7Par*qqdqjF^oHF6m*X9_{s%71YPJW?QRjGoqud=?$aO-%f2`(b>@Ls>GhTv9@OH zIV6-u;tl;6a<79A=nUcS4*o>AOY-8%(sDnSpUy(JJt4^DSzg*0;iz324;Kbl@gC;` z^m4Jav_3zoXtOiGzOy!_ZlI+YW4C}#{0w809L7ubia8wg5`}Qa*{f57{917qpcfb% zd4wDW*b~GF(ahGJTepr+O^pld74?x;^-j7E^rp!^A96y_p{Po{R=f#^6v^PoNPfZ@ z&GqG3RUuIs>AyP8UD#2d-Vl<0o9;4CJKhOiM< zQ)R{OyqdJV>mLe=H6|&sC7Fqt5y7Wjvhaz(TaD*O*%B*4GWna?u8E#rH6|uVaVI1s zC$q)s0v;5-xp#4DbkHEAa+qI}_O(KBVKRLFCJ1XI4rIpZgsd{jOs;|J#Ic{`sK39{u&5OUtUGO(7*N_-Zx}i@_oZS8X{N7f&dD|`|g3C^a%W= zdpo?(n|!6=jMYEghBw|L-?&?=5^^LuQ(a^vY*Ogu;U8`(F*?p)3f(w$e`PSi7V4;*!eGA;Pb&gu=C($JKU$9e*v}* zZxnJRB^Hqhg9T>vIdR7bvs%)<5c4dY7b@{wO>yiT>C^q0bnxwvuNsS5B*%k{hr9SztRoYvn4yVe@6wuAsC)#vbTG4SZ}5O^ zflWArt*aUgPfs?pXLSpMU**Hly?urB3$unr#{&!N>$--2igke-!8p2e`pmir@Xffa z{cK?y=L|0#>KsqE+4E9He!jA*`W3^|&-30iS8UQM8ZTR`!kZ<3HaVV`)-#gf5f0gF zsZ47VL;F_7Ji~EW4r{qw-EdV?gS*MMy0Pg$^Ik_@Oy>@{z}#HYPhmWwEno)%y$Own z%_5@LsQb|S5x7<_wZT?M7kc&^a;o>z74bxCoIQCe+XL&V-NLzECul)ykdKA*t$P#e z!i)AhFNa0!pLhkdL|PW15tbrI#Nna0z0P*S4b>KM4E2$T7hmu7xlveB^K$?CDL$EoW`5R+v>scfgpxz~o!8X_AA6TC(9qa)g zgiHl*NAd@P0)Te~96-t|8kyi1=m80TB#aWt1g*e2BpqO@>g&#JUeS;fIjigbmWp{@ zbI0Lef5GWf=U?>Ob3rcDrk7Ww8|xNSTEo+d>Z?;*7si%Gm*iEp^>(b;ddiY>Y$evA z_}siC%)`%@&*lX9AWFqI0UBQj)F`Hsq`25ABY}Tea;m#;z*$u1T&|3;#lKtEIo6kN zZ>?-EzvkZgJvHqyF=5t}?0oq0&FySxjf)A%O0^Y2G=jq-nYHjuC)vM3!rT}If4Tnk zIuBQu|Lt$WLwzkv7#>vrp?(N&epDwvR#p#u5n{+dE5V!zvu)wXM5j#t-f_B`*0n0p zW-GI0M?}Y!b#|6jx1`$@b7c4dekeO3F*`dU$$Gb`bE&7TYI@j_#yXU>a$XV8|B#O% z-0kB}CPSJbfNskz@Cl6$Ncno4lJ74jx>3?TV!gBgidO(xk+~e!>O%fy&SzOt;$Y2+ zX)I&Ud^wgsSXvPhlMuh1&rb)J2w@lUUK0<8JtO}|4eQ6;Vu)XzSuALbxcA{8m`YW+_!@2bqu( zq>Kp8i~#V7Ar{QAB>`c@|86_m7iwWF0WReu`Blq<)gk|o3*Z_yD24&Ywe=i+DXA2k9X7PdM>wTAIe6Ua`Me!`j*qK6bwg0~NtUuG+{PW!N z9}@8+zHC*s!9m7azos`j<4@{qPa)V`A_^lsf*#sFbly4SS-N}d;7;LNda(8S&hG14 zFY82G#9QO-@*MC$02E*Vm(rq7J-rIbrJ2cF%Z<0~rY%NmEQYk>4qnu3PD;)%eSVmZQ zn&petvu+C>iTYv3)y$G!T99@hK_&J=cvxunq2}JpKisyI@d9^#MwIE}VY%)wZ6hPU zV4QP|=m-cw7v;!708gK|2ojVxFDkjTuifJ@jzqn&_UuJ0_O7nZ+q=(f?e6ORaBA5I z#qG$_D%juA7wjxWEHgl3y)TfeCJCGY>;x48%<2+*#R~2}V^Qqfh{XDexr^h+S`rc$ zEn1kmAgE-~kf-D#^-Zw8v6f2*7Mr6|GVJYHfxM@sKdQVWzqb4KPAFCA>TQYh z#?))lK4V`2zJfBKI90$iPMsVn!fPWSCPi^j=CQA)##Wxv-{@)d*efdR0@%_&ZXa8+ zV_n;LRZXrdH65X0Akc1$OE1i_x9K!NI8Oop0~#*I+z=>iau7_+s|-(JoCF;Ht8?<-w2)Yf8; z3j_?&{XZc~nGo_#d}a}VDOrYzb)*qTso2jltpL7iGRA}8sRYoL5=yL;1=PKQKXotQ z4;)ALx|h4vM_4OK<;W?7m!Ow=|6R<5aDx_mzjr?JucZZBYmIv&I?%T?m_@DgB zVGE}GQ!g(NJ$2(CF%oCz+dJ@$c9%yZ}=$I3&}b9kv5hj8(y*DJCwH3 zmZDt29nF&UVOLD`u?pC2e2H>#27JYvRR3GOzSK=iS@Qda-{YGy(T~(+i~iS9eR{>z zztnTc`cH}aRib>xu64zFsy}jE{rj<>t6`UPhR>H^BR>6z{zN;)MRvaHKE$_Zht?a{ zPWi_AShRi0uk9AY%Phdxc8_TLrQTLCY=I2@M!&gw+i&oWjh%doDZcjmjvHISw;K#M zouvKD+*=L*`?K-Ab64QK-KmeS$9IAJ)WdUmz+u`yd7gg}Yr4y@A9KQa!nb0h;Wie5 z@5Q+))ikFKU*KDuEA7YR4qw~Hgr49w!})$~?_fq>+f3YvZIjS&d)uyCitj*2D!)@! zVBC%DNyBaEbFWyV^f`D$lt+uPZpF#T*ls_9?k)tBkg?qeN67$hLKpC#gS@%dB|rH_ z00OmB1TT69KOhWA7#WfF}5bjOHoZ%e&SSU#b!M8|?8i0z7wDoC7A%S3BC>RZ4 zVo~H^Mm@~T6A>Fb>`P7$v38g0;b=m$UGZyr5RisF>kT$D{ryNzd3F;5(0GH=j5^CJ zsu1D|dnRrC_-83(H>+#igdZtU>ajp8KJzlg#{{!;VI!7%{w)-vt?#m>(o`%}^7U_( z=Vet!M?QP#_7`8ed)fc2FnZ0#Hh7tPdX&WPT1EU85nteE;|3l#td|#N=Bl2eyamfn zU$=4RMt#^6oxi7XtIUxXZ`pnD;NESQ2I<4{+r5qi*aNXvWr*$>Y+x>n;_NoDH*zlY z1~;yG8l|_>6j5K$I{ID;9T(ds%40!C90mLY+?#-%JO{L*a_t?#mptXOOIz{uhoU~= zg+u{w>-h`fe$U_q_^M$(W5<@;PHso_@Itv8?3o&ToV(7XUDBYLsd(&c)t3e7tLno6|0%M`KtoY7L2wJ z6t%?A9`)cb&sAtnt%hHUIqA3rujV68{wl3~G$UXVu@@5d+za?YK9*t8iwX8Lfwczw z0ZcXg6@5zhbC+1pm4>I#`WDev!VkIrZ^c;t@I$Ph)r<85exM)W_on<>>{poKFX-ng zQ7(NkObf=H^Otj=COu9pg!h?e!$aFj1DSi&ujlgIUpj+7QO#W(Z8@~(teNm zKvpmIe~0KF7EKse)+Zmp-|(oJ`h+joe0~0Fw4=~M%leXTkms8$>I=F7aT_S!knI0= zqJK~T=wH^C^S6lki~71>jhz4Q#r$Rc64-A+mn7`B@G_$Uz4lVD-$D!~VZZg9D2Me8 z`nRAyczRJkOq4_Lg7OI1heEy~>Q9RDxi~@My{=)Of%Ye!g9J{J{zqsZ3g&1EM35Nh zufPlAUloE0FlgRj*QF_oOKQ&^7%>OMHQab!Xqq{pX*71bt;ZYky0ky4bbE2XvnDyk zsLYLOS&*Hcn;aaPmC{|7P*O+XuQ7gvb_Y9+i}=kVhJqC5P;4PVusa&ya|bsSee}Z) z*PO-uJqxoe?s!+(f|@FGsC9mOb#!V`mw8cg0eh~hWMKJ7TTV@wbu7KSAU!)ax=RVp z$Z{p8r^h75wL4-nasf54A49koyLC7Wn^L@|d{OSkr2e7fv~vYc>lX7&(Q<^`3X)tA zQ_&|6s)vfu7hX}92dTNfD2tCsSx}b@wn#eP9N0<-PtsgQ4H3UG6EWJok=YQS{5A@| z1db7*nDqWA3KOC+-RG4nVg3?MNV|L3WclEVgcF2EwoQ`VJ)nx1|9q`f=rn0>q@_?byLzMAo#_-CxwO6nY+mDFtAi=xzP8wFgPqa_JHiej?oIc`KR zB>;QLnb3g#7FvooIN(+Ob69qY&xu0D3yfSl?3+t~9xw13-<;-{esS7a6f|%Hg%BK^ zFzS7#=d|i;)W;Zp_5UvVf0x-oIeg;Rf0n3EG_XFWHOnwY zIPUU6od&ssXprOVdjt(K3>rlDrDJ+rKoO_xxTt_4A|Tld>+t|#BrL|3cPbh5ej9Hl zdLQRYK1bO+3A8N9`lWY-ps7q=qgWzey{14{9FgX zX2kxfe&(PSKXVpcE_yPH7G2YLrEb=OvGtgnSi74Y)7KuVy~17u|N!=}YabJli%p8&gpf2J8aa*&Ysd>BaR5j@o?Us%s$f3v51W#sbA-H=27Y`jWHkNt)u^Cn&M;vMhC znE;~t_RoxW@$?PeK%!R*O)srY=P{w*OoRY`}!I0D#ua+c@1>R*j8Jn zxW=~3BIskJ0tT`8gjhIGY@(v8&5DfdR`qpA(+Aaa*e;fkSztBGFs4fz=e37AG9pb8 zAz`MlfN)-z*I(amJ$r3QPl+`un7z_FGDBg`%KSOdeT|c9T5%UFF^xBf(lq+=g%$#OlpvBUXhOYeDrV6Q?nPazg z>roanT|E`)QZIvhPB8Bo&=XuagpCs8^5?K84Su%D5IIWOdKC2fo5z?VqR7pYzP`m&2xP5Ak!;)T$w_H zRMMZkf7oP-4NeKz1RtXI8l%D+;*+{<_BncdNRC`RpRjlF9%F>{mN3T0_}-8T&}dcq z@!GycWU)o3E!dErRgkx7$+q?HbToGKSJc<$yK+lP8(GBObLMvDxME^!3w!48zLq~W z@07I@g*JU&*dMZ;43l^qx^tnF@!@dN$xIIQ_Ud*qeSJLaC6B6Wg;*U3Ybgt8;^*Nl zl^y?fk%551&Pq)jp3%%>f==ESoYp4|=%5I+x*(vgT3W;S!qfW60}hQZ_6h@rgn~06 z)fcGNJD=2($|k(<9I8NJ@8LHK+y5>`8smKP5Mgp>CZi^kP-337 zDAc3a)Cc^-<%+vUc5xItl{ifC7=?iNq~Z6s^e!%1xbM9JbI;^D7ztI4*N$z8oDzQ-a4y&iX)-iw3S+E8}VE@fpl906r6MTu+?SRslqr6f^1f&~` zOc6gtM24G;3(Fs#f6+zrA1<%#DT%z)8e5!`5@A;IiubWc)O%Q;+HziwyDq<+`VG@Q zMl7y0U`5DyVx(FfnJw(3%@rm;6kQl+T8S9&1YP2#6i8@%Zz`{;bu}#PDN6~>iOjD{ zE-Xr{AFs-_6_qPJ0gJD1FHB9&3@PAgjg1GIQX|K_o|<;_>D34?1U=^6U|`rX`Ybl8@@t6;0+O# zc!o4+8%~pY^0kWl*x!U^T(7^8ccDIXq%!g#pj;(kLnwrR2B3q&vfyEBVF%_dI(zLw zS7)T9G8f5@;*y|z8XhL~Q|OYBWm7AP5)$LOTX*s9+tqsh`ZHbV9(c!%xHvzGJ362= zdG9FfR!~OoA5o487J`1HXQNM8rnVq-hZ6qd$%92d$)fdO(QKc3IR%Smo!;Nr2hvMW zJZkXNy6uxU9`(!>ow47O^evf0c@4EX`*q&zq~WPUB&WuHdqR+Efj4+K#>M+PiOto_ z*pq(7SNcdNhOFM?We4e8X+2FR_B%uP`IaJ$x<>WGJ}wk?j9CzKX7=^k&xR&HBUc4>t-1uNxci_@_y<^9Fug8xB9`T{8>Kr8xpxz3 zD6E)Z|0}GsChXa4-S;oO^rL!DWgo(Iuj{K~UBZHC@k@)tFYLLxC(=$qyKQmkKN* z?v>>U^XDIsZ=neH{x1F`Xt0I09NEc$&g~W9)X= z3;zGb3eVv$>9NAwK_^igx(g8d&j1`ueJ0SjejWY8jo&24=G*jTVEke9u^D}V--W+N zc?JygAsa%kw+^$6;iRmrBzD)@wVAeb#?o!5AA$K6$@=kl08|tCrZOz%H>fV!JjrLv z%9(4|PM?QE5Z;K8TZ945#$z;4kw`XyV54whNaH5q#DT{MQ&B^b0q<(%`kpEEZ^b!Go|4%PK+%=&k z5(IYE$bSx`-dC*e;TmT8FA>!fd%U0>`$IHrJa9H)6n_hEA31PXLY{OTN%Qe(mxMX| zHF2;2D*Zr-Oe(x zPc%1yXetC<;=8!6Q)|dvs-{^t?_$@wSi7;YN{y2DhR!k)eLRM_g^(UfkHstqF&JWj zvi6@{97tOSCU0M0%_*_gWm!{ui>or6rTWUVhLU1Cu9?%b!kn0q5fvYr=Q4+T&6210 zg`|5-i5ofvK1(n#yxIFebIoOO{95s5y|!hv7TP21k2p`=dh6%$>!)Aw8fy2;`1O?U z^b_tDZx}Gp8^PXZI3bNEAV;LFuV?HBX&u$sIrP&|U!QspMYR`}QB$6m@W(TkKs=t2 zyjkC66oG)>mH8?ns2$ z`b+FpuT6S!%dDE%+MV{!Ugzeb*t$+9tkw%6VYS|ijS}=2>_NiFhAiHT+E1{Je;cOp zLnkqae@>l!5)*j5w-9tJ>D_tM_hEvefw%~W$&d4Z^jp~Gf*hP(D#v}snrh7{>_g}=2+#QIF#;*Pgy61bvUIjqC8ZC~q~@$%9$^Ylf5#4Rk(BfJ zzKXCmT0=Zh?;?0A08u>K&+9!kt^E_j=}A?sr!0Hj$lmShLrTvAu5Msm0j7xM)uSsv z#QoFf6&1?Mv3HLjrn#2DKbmst;U(+7X41io5*gtA>Phun|G!!F{;*e1tG9AtsenO3 zMh%^jon#A9iV|=5NxKAdAzJPwyaldYi9O>&wnTE1NFhIzR#`q@CB)#zvi)UC00Hcs zb*C-aG^csPg44&}aWnr*@8d=~qXU*@C;-wwM`PsU3X=3du^ThcOPd_T* z%zxtPeQrO%>tfq~&fG7lP3t2WN6mj^@yjYH!;e$)`TCka7Hhr<^H2as?d*@>XB6BN z@E1f8C^|Yo)+#R+s1yg`B4ojOhCUOhV91LEdc7!uSj=O861X62`foZG$df37V2@p^ zgbpwYaHfx^@F;QibOt-{hG5t$9d6viNK2wN_24{^-vuz9WI`v%bB`AS`6Yf~A$oe3 z*x0mjDJ6 zwUH(*(_av6cBV2j^9j9?RFTq~WY5UHS>}uwx{>mocm>fc@|jNcW;Tj3>0CA{hcIRy zQFJ~?dLkEm{J`LdZC>Dqx$zHv&Kr5hxm3K+xTx3dtD-zPGBANpMKkQu6jfuAEbz}&g`7} zkdAb62^sm%Roz24i8<68*f^$(dq;H4wXg#Pq|!Zv|8wS`Ok(*#hJfxM@k?ynE8mxS zPLf7w%VPDPB`#qnYOW~C{twB7^lU(F>b0rSG#A9+1}yjz^r4k>zkZQ)>P3(@-_SD> zSYm$(GO#Oj!uXVAk#gvlI+-~1%b4WY87jFoLLXC_+)v-e&Zo>oV(bWQKjJ4}gEMRP zqY6nf2s(ErHn)B_Bu>Yhgd9YO5A{vaj~Dos5+H>xD)Lh$^|^^i!1)c-gwN{@64PW) z<5(->^#n;N?p0o;(%5P`rg}QPJS8DUpS8LQ#~K!sf%(GMUaRKsVz0orFyXM|CG)+a z5p0dLaP`srxOy@U5r2nux&0y$T{`2N|E@PEQ4-wJL{y@ir1XJ3d0fUeO4cRj(T4kT z8tyy9St1g%`Tv83x?*@Z|CjFnkb&xgvNCu^K45nt3sq)lOnl4FvQUZhf*xJOSPUX* zps)Zyo>qb`JY4{l_+geUQzk*S)u~?3$QT$npitA;zYu?`7_k`g*g3gZMnxFr=NWRZ z#QjS%Y-LaKmGGB}#2tYC-Gv`KN%1?4-R4%`cgw%|%6+Y^@8C!5L9B+1b~p=?A<_1m zT(~rnwHBf=DKoRXCMEfKk)MAl?~^pBnnPZtEOWYw1&|b1@7K!mR>^5SlwGQ*dA!z;^iXOj#U8h+p# z1P@8kP5s23;)y$wDl02u5<>z^Ve<+~Lqk|MD{1|WdRk&E#0DL^J2>W)gLw||O~k{q z1$^Tx%TZ=Q**hqU#F<9xb2l6IBi`Iblr2EUCpq_0Y5?7(M8 zm}NQUIhXy*aF~BX{0kf|%8Bj5+c_-qcC&xYhwBoptN5Q*MgyhW&n7$MgS^%71^)*7J;CaXuEX@s`%!ia<^tw0#v)OPMJOz8 ziB3w2&Mq(K-xMU7qmv5Cv#sT*pTG_<7oQf<7Ntgm_;kok0x7eVARvBKW@FX7v%RIe zAln>U+2G9QPgN9lb+^{pT7r%I)Eii8o-OZ$zGmnKtIJ0(#Kj+DImPyTXG3MIIlG{{ zrM;8$6(vqIPh~fp%8kJ-wmNuJpsy63iTibw_`eur34%jIDvNphZN4paZf0A%v@6i- zVEv0(k1_UZZ=anX{q_F+cqZ64S?5c%TgrNkg`!<7??(dI z55;)0-R6mfjkEfj_=lG*T!?m2;9j8fxVi^g8{r4*K53dkjx0<|q@tlfhC+ zjHl<A4lJ*+GbX)Js4#| zKkV4FXgdTNHCy`&EG1hF^~YePhk916((oP1OnkNWXT1y>CBuh2E2@}pWIa6VFy)ED zZ19H}R5>^OCD*%38L$ zr||zr+qSv4Z4>oALcK!T3x6Y=IWgJd#3{GY+@@4Q2d4}3ybO@J(p@3ASFhCdR7~L>XBWDMTitbmtA%l>M{I$3OQ~K`J0@%|qmUPEl-4_{YH*G4s5r`0HcmR8SzmgQyVYt%J$=gamzKilm zh0(qu@FOZiTe%`pVBG=T@qELn%SqXv^+F9EQ* zf`5YkT-uLRhPi`QU{5F+#B-4n4!7V5k9wPuaqM0G8tDeT-(v^l_j(OBN7Qk8ZpK_s zTF)$clJ(d+4_kebdM?Ox{OjH9;m+gx!@M9%0zJW=P#3c~9uM+F(0Cru4)5@Bnm6g{ zGA+){fS3@k4o<#))So^)lA(rtuQA2T*o1%C0m#$!|VPXBLY6ZqYuVGeItFKpdy# zM~`~MbLP@J?pW&gJ;tXT*N~_JB6-gA;7f6)2JBm}_65B&e2@HqCI@n>R>CJc9w?Rd zs^26g23P`Y&VT@?4gW|?T$!Gl5fE$4F9|S~KeA$ zktlmtlx^{rsek7E+CLyGQgC7Pdg=pw87%IeLD>#p*Xgo$9MN3##`7*8ia>Tj3oama;wCHpNWqQZW1;Jjfp4PxW(@ zKMve%=XdrH{=4%b+E|W#=+hqd!cZj9bXf6o6Ec+7i!9{;p@5;@JyD8bTTbg=;=eb( z{R&0gX4P1F81=PW-l3hvKZWe@UiDsM{$boNt&BHo=V2_+iVA4JK#^I_`s_$?ZelF* z!*%8t=UL#_4-dpJqdZBcKaGMxR#>O0zRwP)y_laCS}i}O;C=bUq#M~6H# zcc#9pJqx%K$sbUEr`{>%?t&Lg2kr~*z5=rWm-R0!+WjOS5ZhIM~&jFF+)wJGgoz=u=Rn>EPHFs~0V*B7)GXGlYp9_dN(yG4UdNT`0b$?=kNev}cK~@P1G72dXpVIfwol8lrs~(Uxi#X}4kQ zt!l5jQ_O!hY%2`#6u|r)M4x+AVMCN@o9t=}uhLcaOuG|xM`T@>kYEX1TF-PQs&Jd+ znXaO-zR^at`P%=AcXP(Ee~B}>R2$ds(w-3S=Cor!in3p8Ogme9N!RM? zX>+yvXgx-{FWA&FsEyQbm%^&Qva)AIRkOV>2vsr80WDA4OA=$lY3eEzQQ7C3Q+t@o z_;%krn%2U#cI^eM{Z8%aV}BIm{8g*f-qZdh_MJFbY_0lN9PhdAI?1+TE{C;Y?HlYZ zpuCB$uGFK0FOwoXzkftHZT943N468ZMogmkt1QdrOiL@z&dQ2TN{rF}mUDapXZ|7X z8hjjaX9bQ^y=9?%h4uqaJxptP4E4U${(yRbNyq*!*5@q~?~cccdONYY`?Wh!Z-+W{ z>|IgsfVM)rfyw~?HXr+n%BFA825<{^fu3%eegsnyW$LG*%t2+^RsP?p4Tk5mDOQDj z+o4vggzq$Unc-vH`y$bArz+_C>1xB<+Qlpi^ESDd(!jLgwF!51YQuhQs4z2t_$b@`01|?3EU7!_f zhj1o#{`|25^!WU-Cq?-KnpxYgy@K*1o&b~|c_={a+c#Q_woAK_U@6`;-kbW(f%>7b z19P#b7x5wOh!RaP2^5pH((Y%jYx1%ON77pJBZCA-keO(6G?az}3pOE|?$Sfq1^8}RHgZgljL+{t6sA zrM+c5^)StKKugkQX@5igx3tqGf2*$6tlH^P7Ek(OYdk!+%PQzlfFH1AUHw2R9ih#C7#?lB8mkuU_CQt-r z4W`PhB7osQXVm87mJ2u!76=w-ew8sROWk;kW#F@i_1Cm3N z%*heiWx+A_%+&P2@bHjuQ-m>+vxq>Lbw@;*lG0gTdTM%7P*k`%G}08#c%(7HglgfX z@F@!mj4;AzI6BB29AdPjCxv8HnZm*&(Q!hsIVi9yD~xoY&9k&Cl?;Mj4Eu&_Z&g2Pwp~`;=s@u@ zb`{BEQSV-@n)PXKk-bVFRILdAfzXSl2nN@JBE+Hic&Wq|#EMI${Xi1|hlX9<-^9mdbKWMjA&zo0mYrnOqF~!-`=uBy% zJ}@tBsS*VqyiL7=wMdM^NYZhg*!RyGfr_o=I(u{g@Q6|T|6lI+XN7+2}fZpG=DC-tw zqw3|djAXb5A=BkjuN|i~7|sVYz}br2m#aftcI|Bf6$Sp{4Df=^8awT9Cpf!I7W7!q!X$D}iSPe*1mMg(1cPKW)IiLkG7sC|=xMXWm@n$}0+BPA=I~^s-j2UceagO~0+k9;?-T6@$Ze;ivJ}hTzm4V!unUz- ze@DnBy#CYunCp7+*@g;?{NWJ4^>tb+18-r@>x>8 zm{ZAA_>0qvSoAk_Y-5+i_b&&yjy(EN53<15Mf|m(_pELP59ETnSchE2c7q0VjRE` ze5N&1E*ehJQ?X_(Rm#}~-W?1<$*5cr&qD?pI{9Cjs5qL_|4LBA{M(bYAjGSNZfdm8+pBGf!V=-XR?RlYTJq~+_-kns$TVnoBHQJbm3Kx ztsK5vJ=zmo+`F}T<5j<0x8y!+kEiI4W#>Kp*nw4d6?nvb2*O3O5^aZ^$6r$X14%#0 zeU;^gdqsJfs9yq3qXX~Os>B)~)xZmF5akZ-d-f*Evy|BF@Rn6tuq$+430fCy>^>Fs z&oKnzn>JBig?FCMKc@O0A^VW;otJ6fu#e^YUr6sC?;3v)TT+Z04ZMw8Bdn$%8`E7( zMI69-WFV$T=k-O!mY0NOln#}zcLsSZp<$MMTbh+kw0yv(23xw^7kc_wU}kGqwT-)@ z2GzOg!R?le)~y;nyj+Z1rq!??pd*MS4|$9W&j*MmbO$#(z^)k21m7$W zRG^|rXi-*C7M(Y%c4F1aL+dAM-I;Tkr?I>?H#vP{bNdZtd5syq$HA@Rl4NnY<4l->!2gF5b`giU@KG2p@9G77m{N|Jk z18(qm&SPeP_V~YwX`E`bWp262@GEbcf}=h$V|ATLf(B^kCSq{m`u( zaG`xhW+2Geo1tr0ys~`xhULLaR)+Q%=hU9n)KpZ|*zDOfV%$5>a>+zm>cUx#ytUt9 zn_Zk!n^RnnV*|-g@X)R`um||Fq!&j#KbWkN5o@L}VnsZBoSK8kTxPda_SEO^Tk$Si zy787f+uQ6tS*ZcR=|#g8=e^zHscU+F_l2>>qUOp)DealoMD#1~aE#Aq3bAp`WRoo9 zk?F$A7|!enMSoRM!+9fdfgurT=^5FawJsVQ4M1Sdy7u4d;OF`s>=xeuFB@;jz#?=HKf5c6=ypezIkVhhkI58q2`ku#u_g1G$0lMU-)R~x zj(vL{i%CtXR=)^Is>yHeWGm;Nxx%@8+_RExYFM}Z9nCP=gA_;=L$iyvi2b2A7XiEv z&P5owi2%stRdXO2!qc>(g1V-Wy-Dejvn-x=wg*kH_B#CaDcS%=XId4A#9+2x=`^uV zC+}z&8F_Bg6D*|eSswPn3s1=Uk=l1W73;~uYk?yL;wfVtf$=8>Tz)wsEGZ)a!Ia}; zvy+k|;sfLO|C|tUnFl%2bHfo&IV>zQx+JQ`sCM}WT&B5!zIvAj5}k}_KX{9nTP#i* z53mwe(9$)6MdVi`j*NtbR^{f^2b$*$B-DnbWgX+szA_1S9dzPtoEvy)J$=iF~^v76JL?iUlzhjAONhPJJDLJ0n zVoy`a{Lr+*9Cv3~Q8kO*a^a~HO>VQJr@W}emJkvUQdn28E+cLrB07vK3AXeNw7x9d z#XcSlItdU#!tQu%60H%$nQr4*4kPNUg6{r;^cWVjx9O~nr<^f=w7#>y=ZYQ{(7V1m zF<@|T`Sydq*s*4Ga{inRo3NHx?HEJ$KBB)U$`mBoV(Wnba3HL#v-BqRrzg#s;juB+ zfYw>e+1aVSoS$m!4?$ar-^lJ;e}h;w2n3oDZk5@2Ug=PsH7|d!KBpk>P zGrxe>A=X10MuGr23koU48l%8O1L_C7?{pU9RN`s*ye=s*D7!v-(E}?#Js4(53=d7n zXvsMH%7y=Xc2ssm?2}j&gZN1Z}jDXrr0>v?f{qDCKNa=3uQ95BodVro92*1yGC(57y#DOgRc} z3h&c2lLhj@2oYQw@(tm+$y!sb(Z<`--e;z;#O$i<d3DhZ`uNi z5PMH_>k-|)-32TrJS%ZIDO*5c|&Gc^udAdhR}>qhaEZh%Iph`u|@Vm ze$GPY{8`TNd)p(jBZ|VS7yNGO(MQ{dH%#Q0OE|5Z4PFwo_2dMi&NK0p%D(gc5Wh5*78amxr6m>~y)ni2P`dhZ1zr(KoWxULJo zh8ImN9%rvjELt|o0#Cj2zWXlURyE$6|LCKaPYtbMJJ$CPtx zUc;Q-PCx}_2ttga47{HVtPv0ZXc{B?DWZr(hG0y{`a;hA#g$7|tp2O+Tl&N=R@VGt z%_1H)yyX6!XZ3A-P%5hW6E3^geeaU0JaMiDXmm^9FMvJN^I6Ct1mGj$Zl?PzQ{?>8 z+I||M&{|wj5j|E~-%n%M(u(rggE`d`%YKV->O76kY}fd58l1z|YYv|4}VRJ`unT)2LFQl0ojX!xNzVD0ogMZYdpgGQgrA5#Nm>8 zrf?A*0^9@fSvY6!v4Dt_0(ViOEg>?9vuiIsV?R4}Q803B^)~&M@7dnEa@WLg!FXm{ z-{xfGQF5&+_fHs7AMTJ?!j=ko==?q%F2>{_I@W;au&? zSwc&@8W|ez*6-GNbl$M*`$U}g8Dif-MCSt} zdRNGPG4S;`+cLgq4D@azqPNJjM*MNR;7i^5?NaIvv z9LV_K|BDgs9HY+ARGw27tTsaMy-85Vm_uxwCCWsA7l(yK(ZX0D>sEhc&$j2W$3_RH z9~eMjHp|LX^~Eh2U%!6y^v37+?0Mch_9(^@e01#SX7xkXzD50XjJ2r`v#m%D^E4|LKZn$PR3`S@oBsh)IGNWJ zx7BCqA|iv}a!Emhbjc)(0&n)xg{_k#jT3%pA6D&(%xPHBoZH=3Wn;cfrA5Poqeb4N z50izZJ5#F>Hapx}xuDLMla%)KJgh4i&=yI3z%!Ydbzp?;TsETafv|4+Wy@Q_+KIc!<_eJmx(!Ud=ENa#9JhJB=w8+!_Q6h>$J*PGM{fe>zj?ge_%ZreME}dj%uJu zO7K@9>QS5+ND#rZir@l>X#lFX$VgDPmgHMV7exUH6f-C%ijDquh`n`*+nMZWtmrOE zpGYt2u4r^5JKalK?I9EKB_5Z<;qsKk&-|0`Fr`47f!H(Bn4QBo~6(MZV7UteD>2vtWBgTd`l)RL=sv(O`%9yh<+5hM@o{I zZ!F3FiEp7jp~ovizfeDb5N5uCvK>;^L$zM-ZSDB`O8`=+%S&YvL_Dwn_LAcET?aZm18-ZRbV&6jlBYPI;=(D`4COrY!uc!CFsT=_$*?J4`KXEf zqdnU?O3dcsj;-D5KQmd#>SdRnK6uKm-u|QI{i_$3l`dS>=VX~QSLk^j!Wbl(rFaRT z%p4?+z!o&%QpXAHhul!*p@%L!_?w_D<73;RZr^|C*Xq5ScI@1=@$?;R(V;i~c!NZd zm*4&T88@h(-*Ek&{WsD%(H+G5!#R;{H7Iv_tX6=QEPDmeP`UI=laA0xIPxMxau8R?}l(u8kH+_bM1n61N8hYjfL0Ur0 zTZzD<&e#YeRKqaiCT%(0iLC|eH}0gQNRip@vWUjq;)Je1OH8S4C_Sg`)~nI4UJ3H76}9Dk$0%(pT?|9gVv~L_7R(!MB-(t^%0fLgP5}I1?2P zfdYtQ2m}&k+eUZqhQz9GxvPvngt*^~!#0PN7wDfycNM=~KK6lzJ6mBH7+ z#cn*j<{K8h`n{p|R!tD!uwKCY7~gu$SH86HC$UaMeM9^iERarv>LU*w`vX1z z;>3t+42)+K#H(wP4GrJHgTfOs%hID$qCx`@Hv|(nyx3OPS6iQxIFMLXy~NYt8yB%R z_4u910%sG3u)0_7*|TzZSJ^I{vHBo$qk}b+SwcPNYX{wmH=Y%EV6wrqVAVek<9{CZ z>Z{Y=eewzF>Tks$<&LnhkZb)2ZGkW4-03!5Km2brqj{=Lv`?_`O-7qQ!%&po2lj{V zhnvu>@M^xo+Xvl8vo)J-J}?aJ1+FAJOl^$t$^5I(e=qo&;HzD;E4BOv=+%Tb`%Fkr zXz{#$ZbGZ!a{9f~On)cX*9w;|pIp1Nw81)*-soDkV$HJg(xJ1PT3ef1Ar4*I+R}o5 zwXjFVuQ>ONgVucYOBPpXKXCTBSB`)9^5mnFlM5EETRT26xn^w9TDdo*V}3@=ar8T} zH+V;M9>9x!=*Q*8?$je@2Q7^r4jRMvAAj9}x`1o2KNk>890M5IlHsg`tA>X!ubsog z9#2gC*YtNsTB=3=cvtIW|27&xAQ<4p-Iondzczf?a1T2?{hb^~jN!(7Zj)pD3@0v~ zejhC^8?N(COim8%gv9~hgmywYNwWe8PY?(Uju$1qd_N1_vS#IY=M6hrN~&shu){s~ zFBt3`?5ol#yKfe%mG;|aZ;&=u_=!Ik$RyMTT+Mj$3ymL5-3#5$39G0(Ji zboCiK*Nkrn8n&!y?lu1X-O$dO@}?lRV8N1WcAar>&BD{ihkH8*YKh##p1FZTo=3k4 z1hHo16(W@z-WC8VFrXKG{1}o^I=7NANaftJ%+PU!N9*!p4Oet&Ta|+_hrPz^9H(eJMn;G5JrheYIrpd~3_>Ki)estzL5DN=A#p6Bz%)JV;pm_ji6HJkMc0v&T zDU!X8(S zpE17SDna}91mH7r&LB}4f1G5yul^ggzNP7)9J%QXSBiSX(;%)39s%WnkE4H8LJk4u zQ-4Kx0>G&dPryJxK85u3^e8s8aqXH#?(gq#v{dob9Xo2ON(TzgzhK)dtt0Jo*x^MN zTwC$!q4a`$sJ+E~L;t1dKbm#`ae(9kV{;peJHUh$|c+vIJS+fISBgG`~b_mILj-SAP~rE+;;(IO-)I#H!a{WC`9Et z+)?N$GOczF`Yk#hb`wZ66<-le)EqZi5lfy`Ebrd1)ZI~-S7BM&(mgP^G`GFQzI@bK zbvoPi`tQ|G_YKcIaQXOspIv+qDXQ1M^XUGjD_$hITom@|ChR@Naa!$WXDkHU=oSHQ zoKd3ZW8)VNu5p$Qu30*`XS~&#g`nbp{BpzZSKavK-(FVVKe~D=7$dB;4*fhzJf-3a zqR+bC1D|JO&EO3IQ@#RC{eR_E{mN@e^#7GtRoW>5r=#Eh8k;X#lDMb;-?8~Hcd_Tn zORx=lnQu4j!0%U-Ji}*L%b&$sY0rKIJ6wFve$<|%@A+h#nIndcNlIyvCPYlGu7l z0vWNu#!=<74f(J+3go}3!)MLJ7izch2cq`y`;I-qJ}?*#8=6p)>S|$pxpp`I1HQYL zeWjEe@XcZI9c=ht<*nF_Pw34-OT(Z6B`%DT(iL%aXSyS!X>?ZC8ScJ}oW6$B`Q^cm z?9Q>w+|1gf3@Ei=M;)b|%fgj;QT8Z6C+v)ywQ1YvxB8&`&7M)6qTGG#DE&4Vjx878 zKXmMiC==>ARi`27*t8bIW-DuO4=m997UMp48ipx*neY&i9!2DcE=27XXG|rm8>I1s z!$kgQu;C!RS$rid_JKrUI0`WAU=Gstix9!4cq6jl$rNucxZwabkcWUpJtqB>=E+}2 z8lCB>Y0)tm)9-r!71~gqmX(p38XXZ4lfi%K_bGikLOM4o3*_&v<3Aqz!M`#;i=!pw5Wr(>;PsLNq3>2*hKr)S71d{Db$9tgLmQ z8`3i68tE#0kr0}ZD1^jjL?i5le(oXgS)yO!He^@OqWX_Q>_?ru^Ru;$$2lMiZiEO( z5o_}y-5nYIlC0@$z`J094RxjwIYxyHVg@%m%ebAGVo1Elwk%TbpEqx8!Gim~|7&UQ zPx~;twZc|x5wk|?vZL9`Zn zC&x*;n;5}q!M(&F?2vt^oiYJurZknF-B{XM+_0!=xR-JQpHew{e8c(&)<-mzo!wa0 zn%V~k+JE#TCGZ*84k>q5stsUbNbU?!L6YYS#z^$M@E+PX$setSKP2kJ2w(#K=*8g| z!5*#pt=c5((0MgrFT$yg~!E8s!zge zi?@*ne0*Ema0B!Fsb|U!uUd|$PV%`yAsPUtTm~RsgfX?4f zn9h{Orhzo|{V^#`e{TxX^eOeduIKj%QTors>C~rD+pFYBoGkmK=zT^K(3AUZrIYb@ zyWE+oI;6smwM6}D&D%q7uTj5hdSL1`{9!>X;BEX-k5ONFnv<^p-mMW*H?N4ng$sqN zMRqAd1P{Ln#Ja;y0vGSJaxB}##i;(B2OZ;e{#W8 zNLFQDc}QVMMUu@Da^_|smru&ejXzO#PxH${d;p3airfEx%0^C{z5Qgt_(@bUG31?Y zQs#|;*HG-xndtjcXwo(kWOM1Wv|A!?pt%sNBzZshl9{t4D9O03bD%(dNSFN6;q}7% zK$rc?w*s2(1Du(!tu);t^nFv4JNvz%A&5|LLL@nX2t~9Rz}o?xO?W>>JZdwAiop3= zKu=q&Z6F0xGw>eZ4QMPYkN}zTGItMn4qOnr26-PF{usKiOVYI&i^8gMP{^L^5;pK%M zUbv90nNpXs>(;4z$7atSG@YsITFh3GSNjc5;%ZVk&ZwPa zTfP@#>ur4lKm7m;of#EuJv|BofO)zdImtT!Bl%h5avXL8)M~zQ z2u=d{@rN*uXyY3LfQo%AL|cGOatK06Vm*V(KQIP3C?+KJCxA#Sjuyzz@`sW%Ixf_) z;~=HFQ!0yOziw?K{{iy={{fFGKbT3Pu1sk%A)zL(*1_h#huQT%gPSBy17Gvg4D2NP z=TDRrz@{<-?y<1i( zn-o@BQ`*&*I#;i3x_MqOB;JmsVI)M%ahIbH@V( zOc)gNiv$cl8+R3TD+MkV;y&xQc$Nnslf|n94A9>T(Jk;h5wsz0G9@v0vNJ{A^5@nw zAZ)}$d`P{PQ4VV(Y_00iFX%`c>WX9(!%gzB%@&J4p_qwkNqC#W*1trv>BaIE0utms5^5g8Fa1DMxg_ z_L>{H*eLuU&21Z>!gxM-6be0(O!vXtodecCKe>_dZ#F*k@cQowmX*MYehXVdlUA># z{ROQ-a^IQu;5}nRq+k=fA>W;R_Bj*3|9`x_cYNzr{XgDw(lp&GP0}W9X0y|DBu$#6 zd#8Ih?d`auy?b&8TrQV!83F-fiXtiqvSc_=!M#NVrSE>9uk%iN zd$0KY{yzWw;BhPLlN`KT|K?a2eZp*}D^?-O>c@ zm2}lwm>KWYV6F3*4|*;|3vkHrs$3w-^`MCtVFcEDpPQ$}rf;2P8tK)lYId=pj~c8M z@gmYu6lJ2rBVhf=%`70PJNmC~o1N&q76IP%v*JXvKkfDW^}m4KqUe z(e|XK53rK%ee?7Cx=mtwHg&}n>|*5V(vKfc!9eiieTtJKR}wxodul`y^3N#=g3Rvr ziHY_k5Zksfw(|C4^LU@^g{X{g#GMhEL}3kVHhc@*n_BlgdkNC~cVzNHkiRO{O@{P0 zFfZr|>lU>*q_Hpp`v$Fd0_*;2x3tQ0v2Mt^YRKiYa8^l{I2)AijLJ}{Q8v|tYN`~Y z%W*YAJlz9kR?7u}!nssrD6 zqqSjYSqe=*%f0`kDmt`0=RX~jGVWrWa92%xYfm9f07f^PM}!ODd;=xKG3WJHXw-lKG-Ir zdH``E@*5Qw$TeQfC~CZpi&&eSpZ$uc{d#frCy2d5tP!ukZ@d;`!Q)4=Mz&DMxgiTi zW*M^U*=JArjQ@glFYMg2x6a-v{KoHqhh8Uxn+#5j30nyHmR#!1u+u2Q@PoM?UYh{U z6Fbo1-aRfHvcZ8FxQ_0QnQ#pCNg=AmyZ~sv* z)H5>qeicIq%wXAoQ41MIIVP+dInAUNJe8AOV&hHS{by!nMIh$!8h1ycv&UaCQqk6S zV6;;nkMKw}MUc5LSxM9gNuTn+MST$&$_v8tK4rtML1WUPj7+SXm{1|x>2}PC_u$jO zI+t-lLY8vFK!ThdrlpJgFy3jzTqNgdt>DzaDfupR1bca;BPC`(@Pn_U1Um_Od7Y$R zNWPPPNxgqc#js7?O-TiF&O;X@6%2y>!tYdcVP4n_=tm+PQvzJxJND}4XA>8_^5R83 zBg1^l%57kYOZhQTleC5QoBR=!IMci8b+4Vuonxh^vgcx>Pvy_SS4o~L%t!~O@H@Wp z4=U~!{PelBr@>EWi_gjaRr8-vy}(|MPydIOy!O24wM@G&?Q3T|FZu)aQ_rJ#9&!@4 z8Ey`t{Uj}JK_LZIRVM#0L)#{MQTp5DHuO>Mm9AzRrH`{qCF9bSFTb3;kCnODq9hV8 z3d9b6qZouN^CP;^woaPCGIp$;T#XtK@H`zC0t;1C?W0CWkYPS-R(P5%IiS4bNc<6k4=0sHeg8Gi{H|2~38mX9I^oVDiHL0;SoW1phFNcAc*eJJ$u{5WBm)_1-5oMJA!F+b7gmjr!&Ud%7(6LE@K$QT4l zA=2g6qh#OjX^wBI?-ymwJ+VozI>GD>L;Y?TZ?1w9J3e^M`B$NNc44}2X0au)yJKU4 zeJExMhD^%Fxv(wI=x>Tt9Ivg~z2)H9yLtvY!~P9p6MmiB18ojG{Qq)qD&{F&9piDx zXcHzq(=JIV{(APi|FBJD8{qxS6X)0*;_$QvEo^}=Ltj-0`$UWeqe&DIB+JHNqQDXe zhR-xo$RvmxUGG;vCV1sroX&jApiV9PUWuA3l4BWZ6WR1T>h~bgsOC8;>L$r-zT{-+tJ2s`C5u^RE8mljcv0>Tl2= z2BH`+#!zcc8-Sv+HyubEF7lVnHNsAMx|4KGf|HkdE3{lvKoOqH*9MC1F9ptkRG^PS6;mA8J3eN5U?VGCJZ zIw*5m8`1Sq{<7FlJU2*l2X1&17&7bTwQwef!8P0?Kg?Mo3`?%wY$^w;-!bQxcL@Ujnlpt^OkK_4BQt*Bq(vb8Y=mU`l0f z*u!7-PVE_ZVBuPJTSIS$mF+(=I#%7i(C8)HpkDtd&Z7XW1K+}0!`Vr4->NW6N(ki# zhZghgO-r5QX8}co8K%lJ*rNmcj*N~*5@R6?^Cor=u+M#T{>uh)$m-F7+|U;byuZ$W zN)ba+*DBZ_NEthYZ3y?9j=%7uaWezaAq!wf8zVZMKUD4tdP|O7su;IaN;9*w7v#n^ z3`c!E-PW0l9+BRv=(>2m>-Y?NDZ0J4$&!6>xsC^B??XP$CVHq7NCbuv-N_5niPTwP*|juK7_x z8IiankG-_=4ADg=(F?o%>Z>CC?Ivbw8;nQ~PqW(vVN^};25oe&N(wE`{ml}7x^Q%L zIH(crO;|M%NeDGwKnUmqvk?`d0*rhqz=>`ae{kleMNR$w(T33~y=wZL2U{k;VD#1M z7ybPM?#Fgq5(=^X4GWVE?221HX>aRr>YdHu$_sY1w{`K%vS`(c#B-vMzz62~hlme& zS{wHIJoLVc-f7gJ<63u^h6t2W2u5SWEyXw>5U~zT2`|5B&(4c4-1DKiEgS#X)yr>e z>tauA*w6PZoIkgZKmK^XbbfUB-KNo9SETTF4$jj6&oX&O>Ff+bxQIFs!*SdZ6>sR< zmaSUYoPD%<;$U;x0%Hw>ZKhzoJu3a2|LA3%wQ6>Ee@}AX79ay4qvXI?_u|9+>6Pm# z-q*eQwnB|_{=frCU8E_bHtQy&G36~rM-8vERe3dwf1cPM(e7GY{9dj-9xw21?0@5D z(v!ZKodee)7XQK%Ka2FYnF%kp)%O%>{9mY>0Hxwo1Jvs>6)4kbOqVMPiLt^?9P=cn zOkp-7e|jW+j@`acnbnrARTrLL;B2h6edqEIe$7!Ib!3d5$49Q(w(}#`EG^x{{}rw( zY$?$wScbN~V`uXfU-tsbrCs}PzGK(MYx#%7x|!fbTAR#)=>1oq&lw?; z06GM5z}nKpS8izx&js6?Uie7j~gJ!%$tMLD$HkD*jTz zHY4{-4?S>)sm7X}eGhwx%og-9zs!e0)750fh|5Zx$(RXHr9xjY?%YF77Q{6O3ycGg z12pDWD6AqXk2}NqJ2xzTXy2i0`0`Y~!ITxRE_X$=>f!FTXklf2y}D(x!d+*(x!!Cv z)p_{U(>+bRJ#pm+_O)zzpfT6z%C3V6&u*3^D)Ci#I*qG}_U>c!IxjU`}f7=gQV@-Z=2|^RoxBM%eLu zCw~$2Y^4qqN-a3hXRgpuZ@CIR7ETCU$TPlkRy5K7=?onhZb2B4N9re|9TQB@FXW5sz1{N=9249lj{STZ8^s21$ zkcch{=v4Bx;NtiIgm>9oL!UkW+iYi9^MP@pr-u5??E_);IGg5bHynCmnQ+R4>92&?_Pwg$Q&$cTDxbiw1?XQ zU=o5EIa%1{kEh=7>J_h;A3kFL5$muQ@DGu zFE&g<#fv6puTSy_W`OKf!K#L*4r=2)Recjx|HGxd7hiOhF;r{mnP!Wv{Rf-3)K?-6 zaiVd#!;|S6+c9a+`M}}H>UL{E`eeM7^^SM;J42n-u)?qooR7{?(jwx3$#vkHl>(kb z*R+sBi)x?Ox#=RsnagOOs?lUiv+T}adc3Dr!Rgc?+`ITw#M2{~A`})fA101D^gdc1 z3QzBVw`Rask ze#Q>oIePbh+d`p#Ko?I_4kKxw3T>XWP8GsB)kP0Zz&0f*Ei6-MbNBYS8rd*)1-jf7 z$$j}gU^L6JUQjG?gplw^yRSZY;HvrQc!|5psx7lsR~B!#?bP&5ZWudfq&8-Wa+VpJ>ZS)1ATv5l?ah$~PeXe^D*zz$IX8riV4buT{n z;39wFoe}9USPxPBD)8Q~pm&X^um{iB{US|GH7;_WUOKq2C_i0Qq6>hD98NY@-nh^e ztm~X_GA$Ix<^~!pk=EXzZb9Q~swcgosj!KMu4{x(q%9%afqSSDGYm&UB!L5Xt5!=Nd-}U z&bI70Fa6*ves)|sF+V+h@vf$^`KAjERX+a8-c5&2G+sV*^ym=loIB9p*W?d&-tLN3 zU>eLrH1`_lIY)R|avug+0B9BzaYpP8Dy;kp{@UX=-t-86`<~`cpPT1w*&jduqlU(_$J%$axXF>DbG6>#p9DVhup0OlWNRXo zAx36$y98bCEX01GBv9le8;WdfO7-b@M|rhR=l7RZRh3IKd#vuQJmaF>m$q#Q+p_0B zT~!urui-nscS=^Gz*Yw!P|7L&$ zzdCuh66%N-@c~P#XTM3i1$03%7;H4)!2wfE3&wz^p6}T@66w)fONQ{Akq@NZ3tOCW zJt&egCc-=Tz=;!L3jT6WM2z1dm5-SIFc$uZpcvBROGAi`wi744R(Hx+N!7t z*C^^`cvANUW#Ehef+vp;uv$eK*%mU_prQ>!$qZAExG;?Kyh2-7b+jYsnG6@_+k5wh z`2}TlwZ@ieUtm*-)*W8~~y8_5^ASf|P8m5Mgw30H8aysBLDyOR$VQokM>m z&Ib5mVz_a;Z&+)2Vza)yx~x3!hg-D1D#H}ZJ@-1Nt5XWKKZU|a#jWEr zJLmToyT=;#knhrlIjXr<#D2ofaEEaNZBjjvV1`}}d?X_yqaatKF<6S*2hx|85<@** ziE;KwR#t{Ot1vS=y|Y=mr}-%!nq!Oo5?wYd#{E0abNd15csu+{>hc1%(QsZAmR)!) zQ(iee9NkqJvFr0x2*8a>_gA-lc9ZmlzRAK;r=_-B%T@f3?Jsrqq;L`AW$+Ubr3wpE zo?w;HQIw$&?hgbOe8t~SpLJksxF>&X%R{v<_jW`(cw0wToASmzhi~E%mq_Jr4#n{1#gktb=OEQ zP6Yf+&q7~EbD}LAafJQ(EAR3b+kDo_hT77R#ygfw<}CG8=@W_O`K94RkbOJf+8dC{6(5mSd$yx& zoW)zn1xb!Wd<&l&t|8cyrF|vwp$LC*WjXbC$oKEaG)9ap)0m=O?hMyZ5ej?f%EWMF zcWq~-TFGuqB>v=W`7E=p{H<@wVDAi9y|Hp!aoyLXN89O4ARA=4g8v>hCFG*wh;DfC zqKYi+a0bcEf>P9|gk=en1=@+-rnY9huzdXd5p9!VG7w`6*I$rX;x*3pwa1ULZ|2Vp zNWZ=L$l+@k4&e(0wXV9>&abK);6m%DRy%q7?|fc9JM!xjIjkA(3cW z+}h6*J%lBuU-988UcLj_#g(_u7dXO~|1GZH!3_s#JwV`NcU!ih_$5(TJxH+3(<=h?i+>h%CUm zCG62j_+mc=#=`8dH{dO;@|gxFLKPlQ#e~Y8i?;6@J5W%aD&pIDpD$YLhL5#>MF0k&I2zKcU1g-wIS^b;E_Uc_P0W)GjK0@WgG>X z93@Lc;vPeh;aF~=Nvq+Om7gypvie~l66}bxvhSl$NXY1LihtlX$crHHU!qN0T`WzE zOb@q>7TE^_ZHuk7Egztk@A3KWAbUg;X|HN(?3A|G*yS;8t4-`&$VW5b1JprwFEvG| z^3yda`O#RcKoLU%nArlZfZy9V*|pv08+Tc<)8}rHR>$iuv6SbrNl#}(G_Kgz6>aM{ z60S8An%bw#(_gIf(y*Y3Rmfl+?INN*G9^H~5Ot7O3>h46;ZUzT8v3od37)I*u&3uH zr8jxrV8Y(f>Xsg64zsW-KbZcVqRMhtiQ|9N>0zx$pM^{AYSmiv z!g6V0uBSzjqj4C_4Nt&Qk?C64B=EVDKAYTSPR%4@6OHgDWSLN+J;Nwb7P*Y;%@Q9g zUb9OKcDHuDWkPgM_k%x+v(9X3Fv!&K;;}S3!cnY@D3*+1d{2kjt)l22MPnR)YMb|~ z+3jJEY1fG-FSUE^mYQmd&g~9XWJjvg^>(|SDGOYtvIsBX{+@Q*%~$!X=3Hw_udc>c zS5{F~>BXU$J#IseqOZNx5_Wl7-O8eHWX#b;^@fOtq5eeJOVqteq(ZwVbSWV}qktmL zD_K3A(I6yvx48F zHiygux;>f%^A>gxTBXE@$1+k1D;@WniS_{-B5EY0*QH z+y|08WOd2XStX?N)P3v4^K0*YszH{|tVeoS$mh1zzbP89PRhg(Ok@iR$pAuyjYuK_ zJD#kV1cZ}~+iSWiOOz=~aiVEE3<*!mNmf3XFuI%lMxx%N#VEZwkl4S8^-8aePslVS z_#$bWoWf>`EeMh8nc}2WK^EufJR$5(=oHd|&;`QoBs+`FkRUz~Eg{Vc0XEbh@d|=w zW=<=Ms7+P-R2O{3E=scfrtH<$_(k?9?W->RQB_^V1ArYcbVnR)Qmz7{EJ zayNUb%hk$abIi?r{*sDVZB^%utYzcY*p#Pu(~j_%7hOD9TQ|Ox$+m!6=zv?!e*v}Y zp>{Gill;^G9|wF4ej;JE4$<(xiMZAfO|&o=;}eZL>UyneE{LJxipi#JTZR)nN8@Q( z7-zqbexI;-I_(vNZyN}s2-srkB)%=ypaFn!_*)I!2pf*9I7H7tAL~8Yl=&uN90&t~ zt+?^5yEc_nO-35Vy)fMrqF;C)d|SG= zoP1j{hJ<=c&S|5FouCPFZSg;mfz1gh>a7_}5#MBKidQ!`&Fn_vFkD_WU7hcWR9l8V zK5g&py!sdQp+EyWInv>Yneu*m*^b7=2x6e${n8fVTtZf%uTzCIhcy-bJa$ru8zz< zt24@VnWbuDk+VkMHtC&VDpsJ(Q7T!1*{T3JKrdyjrm>OLZx%Yz?@hZH6j-IWkjEUTxdu?O=$h0m{(;c26>?tM%i>mkf>f&BTO1RVE^ zzg82jpT#>Ll*fX>YkT&QM;hUSv9#w`GubuCyVq#vfi*VX9ed>B!-sn)N7l+elJ)`E zR}??Md#yb^{B?ri62Sd^d9L%Xq&2_ytwI&>a15XjZr*@4a%u_>iT&g}Hpm z^uG%C5q$38x$GoQ&>VFC1v@DnW*g&fZ4yuNZ;SB&Grs^pe;cbMxVrg;X;<@a1FnZxzDAQ5ynMLtJJgR)P~fSO2_H;=|Xvh~d( zhi`hM5kG91W{-8Aa6Zqva-7rES6|zEnd^D!t9{Eiu8kMMc$C0SHUyHbLm6rdyJ6G5 z4_-HVq`ACLN@p9`!H%f`S4W>)dY-x}5YxdI!Wa1%=wJ`v_8~N0L&vLato{DO&yH$U zft~=mVJA8oRCS5ZeeQdouInhz8c-R0QxWM>F+X${>dq3xEmYW!SvBnGY3U@2IpBr> z`Iw3Lss&%7crHg&hQfcs!*CgF^<`jE)_QEWdb+S}_T6coDBQG%GJ2!Yyn&Uw+1b(+ zVxDGvy#eoIpGcfE`crZ!!wBd2^qf0KAFgo21L|7~QfW;KfdgIs-C7V0S<;B~NHu)60#6vkU$C&fHv& zW8XE`@7{XT^u~eN=4)GKvX#oQ{BxIX-Ei?Gv+P{ys(R{8iJ}_%I(Z#v!B$15u@LDu zHnBzr;zY0EZ=e-*${|MD>x~`PO>gS^JWpIYv+^i!Y?~gyILKu1bUcf_OYQr*s_A-m z@8J!fdTjT{@7(;&Pt6@-2RkPRE=vHCfvFBmh4*2Sa|`b4gUl3pon$=*&K#rDLcqNi zZgKkSG7QspUof*cOWH8a?qrYEPkDWLp3R*tV|!hmB13Dv{%1E}Jb8Z!$Kp;h#BCA& zC}MKE11mlIbD+OF&zU&E6BjJvilzjPYx1^EO06<1HA!5jXc#T&kRM_Ubm{%#@N`== z5gq!~vAd<0UtnjqO$fTWXrpw6pe^Fzh7@hcJp9xe4~t3$;p5_Z^oK{r zrg#Du#9TJOT+Jl-u@2hz2%gU-uhLAL3{pY7Ss}{Mg<7d+cfWQWV~0L4Jw0*9^vJ-5 zi#M=yk8Hp7ESA|fB)!r+I|E`T99OP>2Q|0}vJ-I%qdMHIB-;atSY`N`b7l?}m~7^} z!VJ}Pw%Xefm0o5YTqC8W=M|RbISdw-kUm)-jX1Rf!!%X|wnPrbqPU5uWv5mSI3Exg zGATbeG=J3BYIS|>hvy#$HBWS2P+KwZ;pY$TT6vV-C;rpmeS}8UU~#M{d7v-FabV)3 zI$n(Eq<)9D+jcg23S2!0+P-*yW5TV@D)$c6C90dOu5wRoTX=qy1Y{sM7f@j!}P)^E|EB^kEr?fh628y-8luoj^GERHRIK?$*Z7N)8z3pI^GO zyrv4HwC+?%e;a`9x1uNxIzNp41Z^O%OfX;<2ntXZ?E}V90wC@v-hCd*P*7)Hpj1lx z*srC1(`l=_Hx~{l3(C~)5(85W+_!QKr&u6(hW!a+rD%z=^x)684_`JtJogk&9Ns~K zYp9R-6M=QK~ZUp9T$v9aTy znr6QAnP*?I8HUN9D}kb9IMs3LN7kyfnoG47^H-AJ*|mO)MW?lV!f&C^ z4~ReNwAOE?eqi{)iYMMoetrfo^PBkg&j4-wZ$&bTW%5XOKG2E-;`xi=+x7sBvO&#aT(5V^8FW*?=$t@|AG*_F7pJ?T-O0z{k_nOr#=OAdB(^85bO7=%5G z8FLVg?ZgeU|NF7lhFBX^9_zyxE4jw?G@x3Ctp5(z-t}-zq;0|>V&A|Tp$pdIXdU55 z@-i$3W&A&vdjGG<9|)%D)dCg~Fku|!Iylyi!&nkU$$?J%$3RNN;uPp*e@f5+)qcV6 zN;@^$dc?1%jP-!qVHUE@GG!l4PPjMuUEXkunHg68!JoqPMBSDY7%QJm{q*P55BJQ? z$$YO*`@86|&nAy(9YkWbEEzE@w(<|QlzjEO^d?KYJnbaz&e=oxITpsPkBTsRpr-Vy zx?c{mLeu%BMm7UJhJ?_ky@~OkM~;$CKX(e99t0l<+PAO$gwnwO_{^EC6(pC0eaKj6 zGL@B@q%S3ZV0~wP;(dAf+3zp^knbrond*$DQu&+o_tSoT?a3$So_?CvPBFr>+3oyX zlEpd^EaSM~0=kq==7)?|M>~Ggk$KB=3~EDp*&%5UyG#1_Aj`eKL2q-YOV!S;iY!HG#pkuAa&2kh)wArzDyeB! zk)6Incix zJ=#9Eue(gT9j^U!E8(0Bgy?0Ls$Hk`{w`>X5vdpC>qom`zF50G*J%4FLp1>SK&5yI`p zersLAtju&5MRNif7cSPdx}NP_s@Q5O%(y&BU&G8w+-;!)N)W|Dvz-p%a6VjlLEpL3 zbMHKn@$&xt2M^AE?TNXwz7CK<2a7oWvm88|iy2iZQd8M<{GR(4rE>P5^yfZS__qJ9 zPSwqy04e#T=GjGnDrhM6?z%Tme{Jm@@jSjfj?NI!zul?A#?|ZCI0X(i zuGsdUBxP!U^84#&{JuT8_x|F#W)D#WzwC~ks)sfZT{NfUEB}1zr_}eWQa`K=rD$Zh z*gX{^>UrSHUvC-S+?k{y!eiPd+{I#NuajI++9>>HRVnNmrH+^!rISCLoonqpbRpX$ zNnLaCSnDe{O!p46`2(|)560rH6wFBO{eJ#YlF=kvz{7n1N-y6kP4=-b%(8!XtUQC~ zhzE~=4@d^VqH)8_rjr5`I2@E;DqYt!{ywED-&@<{3@rQbMv_h@m^;K<}6kitu@!!H2J!X#Z*<$3zN0#yp~@`qEP*PeoXv5%!2{g>4}nA7XE`fE3;jndsrnVywXTvqsgYbkLN zT7?ez6!;Z-%ud!DB($X-x4S9A;@I{u|J1JTK!>3+1HChj2H%g`9&vT~8pr#a!?m5Y zv&_x*c%{diJNgCh<4ZYjMZ5*}j$O#C7Dk>M4uhfGk{0zrYMADj+WqDNMQ{My=B-F%$?Jjqufs#io|* z&AB{#<<^#OT_F9&-R-I|D*LQfcHzKq#&xs2HQ;$5v(j2=P?o4LE=#*W`Y=Di3Ly*9 zC|)RpcNit$NoFP_h*T|{HNHb~v#Ux@+;GUC3RP!*@{>EVK4-J%rca-D-gI`R^x@ft zsq-R>7iEvf3m^PO^YDDJHa*+g*U}i#W?Fz!$U}T_fIme1D}bRXK2Ba2YDzSJ%Wusn z`~Dm3n(meQ!t}N!WQZo0{`4ojk|y*L-ze)g#0dka=U%U!SjDkpd)H|wo;$+I_qqr8rO#ArN~JmWK=xDY>+Iv%PsC!g|D2s+{{()vpw4?2`<tsu=V{;P6YMHQG2nq@f(DZBmOpjRJToBzl3_2^&$zU{O1-sSM<5elb&T?TfJHyOBts7uXXE3WP31{vQmuYwb59v=8IE9>GH); z`ce#qv3$}$*)Ve6!Y8IkIVF>r&xZdF-l+KNjRgDOxre=>$V~dUI#o5pbnF|(eq$K_ z_}7XrDtZS0#5$kB0Rj)LzLp#>_3X{bXAhiu6yyGa*Ryw^n?&4coejNS^{~(Qg+0DE z>2vT;CH2AiDZN1WWos}(5(B$o!Y_afv#S~`4dw=8|HlC=zi&aksNPs~V*a9{MZA-O z74HCxD#9bZ#Vir?+B^5Ge+4lAXw}4SSpDKDeBp398#~KpyU}Lrzwt(aujA4`*v+et zpMit(fP)?Q*9si;%jg0OpF!>42L4^rAjrIk90Hv;_?h0`&&T6@z}jdwH(KF$npZp7 z^Q+{S;m-I|&oQ%j@R7CWRI9`6$m*lwxpmr{H7B)k`x@GK+Glx)9a9tl|F9v|;%Onc zXxHikz{I=7dVQrqe}l35;;X%-UVcNFy4avs7wadpkEUB<#R$j}eXOi9_RQ+*@;Gb0 zUNEG>X^^PW!Y&+@Un|>T@?U(Fx6E5bgJ5W$eRhU5rfv{>$k438j)?kHs)Aj!MAl&E zudV@4d(H}0x3UAPPXN!*^$4&X*u44Xd3^rA9p`_6GnU1E#m;#jnqBX4GPg{#;Uv!a zR1)r|*Tc`53MqrLS84BcSi!m#pEg)aaujk*;jdcWNDXpN>IceAewr)UYk*6(^OC!n zEZ15$@_N=v8Ej`7YWz@Y;MDgu8;te|bHSW=4RF&rwiZ~E!aNstqqyi;_EA;qX8p8P zqqCUGbmniSe()t1wO3~`*O=&2`qq`2P|!o#J;)`!qR6HFRpX|ddzi6M`XzsK$hT4c z``xR(faB-%cb!sY{|YmgNIy4@^=<`UeHxLm7Zn!Lb7~59 zqt>V~l~ig?I;*y_pi*ZmHR`OT75Hi_HS3K0PgybgKeIWjCA%fNHM=#}mDicqk=>Eo zk<*^rn%kb+M(mmP5}#ssDh$|*V(1aGxWRgzPaY}}`=Uir8Cf0jH#+Lo8iaazY05c1 z=AQhzHZ!03^0Ks-(ii%t&C26X4-eZ%N4L?h=i-4X{QFQ=o{vHhI4}7{er;Nx;*!Dw zrG3?yQSvx=GxZs81RhslsVYwm=0w_^Wi*ULN+ztP>g{_h`kZ|gu7Q>Go!iNS>{xq)(2Q`tzPc(vsj^_Y7N?AWw?#?#sjhNoI5%iDV%1ldCKp`*I>M< zakRhKR_O_vO@hN1NL`3YXYBcoeIOM!uZZnw0Wudmw|o9^Zf+w)=X7 z3)p3xv$q<@BD WA#>c-C)l^KX+@(OH{WsUf9Q@gyoQaq^ZtVs8=gP?X0K2HWu2z zm&cl9M0fYB{1PFWH)ZtRw7AD;s{ne-M`|0h8d<2C5S(4(1Afz1cd+LGFXHgH#DPG9 zBY|RE*sE0PEq5sjY9Vscp$*h&l^bX%nuDTe){#9^U>pisOTQt#z@D4^t*W<#Z7;Ic zTvfQFt8#W)eK#q5#n~mr`Ndg98AaSZ#PWZl?V2}hDmKRB_hb|f>SN{)`AWxFOKF3( zYJY;;=^IxDowfpPAW=XK?6GK6d z!D=-*#ymNR|5!mFl6S@u^z~&10-kT*H5jVPiRD+Cx)-G*r!6Hv_l&ie4JLUN#Gh%a z?;(9ixzixTu+GT}eowGl`lih5zrxLA3{>pE*TnR+|B*uCm5T|C}V*XGhp)(+1)VCz<@a0Cb9CYd%d zzoHWJBL^wV2PZ`osr^+p0R9sI`YVBHAufVj%#Stp?Tea>R-3`rn7OM55H&c_XV+5X z?Vj}SdYOTpL9k?dWSp(j_Qr)k0c@VtgRu_ zK>4k-)xRrl0<17ssHRE>{0J9U_%%wWouEc&3H+@Sv})0S7@Z{40jZ8Ezf1Vv+~w)f z=txIj*rok&pY(elQ*Jifudk}R*<3c&E!8V-lFmy%rs&ogjp01I&)A|iG)Kq6wH;ZW zmOs9Dd+ek86hjT=o!#+2#pAzZ!NS}=x24Lolv!MU`9(K2M4aKU)8i_Pn4GcB z?j`yyYhwN0%Wu7;u+{Ln@y<=*K>C(=d~04`UCn6F>nzq=GL22{!I(Yf@iaTk z?rLlIq}dGMNN=RA9%CmJEzld=SUc`j&QK!rDez36C+KEBCGoQpCt3n}0pc0@qJkp1 zz%I}ZIb5V9Oyk-dEi2ARQFKEVE)p!NXaD znxf3Sf3h(2fW=hh7J8t;G!cKk+Za%oE1r;k_eYnxRl}MPu}Q%O{DOSf!S?a@<(S_O}gtpbBbwoA@f*8fFU z{;_c^S~3n@x$R$nZ2tG)VDDg@7E+RVTkL{<9xc>EU6ze>dVGat#Tg-?=A)!8hg*|& z$seQAD}5_(aRV%p%$(fP@|))Om~94kqqAZp8i2|S`$=UA=!Ko7n8s;Nfc*?R%O2MK zH}J75*v$9a6vm?CN$cu8>4&v1Ewx-RiM>dgRkwLJ#%p=(tPSJBsDhc&%E_>zjhG1~ z;lC+#$qy=}$4}pYhQT47?VGZ(QeU$U{xsAx{sDXiogW6zi=ryXPg!;ncN6!Ef{L{U z3B&Uxq!8ds2RuW7(l+3A+7u)f&_p1>NbHQL{e${aYM?LT-pg?NM|UfGA|y^-rD+ zxRF&+6EMQC!pS0Jzp9FyMYfj|`FZ*-zbke%&+h5Hi)9s;6hu3Vb&8M0;|z1~%GCPN z#kvfy71hOR(lFtq2~6vvbPzsCrfRU0v^O!PyVM#g?czi6_`d1Fx+c#Zt~$SG>Ky5p z9!1Qjfhw`gR^_3&6#Ocyi4+y;f3wP!&<6H~q3AsNjX%Z5n zHVeAXmyc~pN*f{!tAm0AU#nGrU25i6Uij~lkY3?$_WP`nCTno_SbJqa6C7ErI$+A} zEeRcE&nzyoqgD&qfwfJ!d2w@az*QU?91Sb|*6u`jzg5dGEt^l`^BtVUwMNDiT3rG z#>&dDLF8u>Ph5iW%b*7kYFUSA4dS8D;==w=uH|NQG$~@bgmBOzx)*R+Ox=e(4Ym<} z$%STPg|}yV);+n2eb8TCQc=nVr=-7>*jR^ES7~V(Jr5CW)na{Pc|5+qKwa+&FU3QK z9m9je#!VG^gQ;u(q5fg}p-~(ep=|7N9)vk0)6_fsF~DdA4ya#*kU%yhDFCwI=$InN zekzG)M|33~#`0I5=a2RDU2mI+gg3X^vtt>}o2zVw_cTFci02*_#JtTN8R_7?dlPm~ z)dky}vc1h8#5^_BGy9)j0k96zbDrrBBn|5@orEkHk$TdJQBU&__=COia6!4|gGCdL zHSa)EUtU3`_4n^3?;$Jf&vlkM^zKt`!pe`nsZ^d#a;pfu+t-!KR|!M0*jek@F|yI$JMQdUJ|2%hS!x42k*)nNz6Ent|F1Yb$>m#S{$E`F|Kf1$8`)w1 z;(EX!&eIQzQh%AaK}cL$DyR$8_`*9fvL^=QRz0W-}8#QZe~#59JJNz zb8XQ^)3&=1&V=ZDPZMtSZHMM*_P6XPaaIM}jXp=7r^%fEkpZP!7Yo!9e-RAt@Qr|> zP~?FGTM2w4Y66*y@B_ZXt=QPpci~`1>!gQolr|WvKFrHke#9%k-ZC@U{A66Z+g9GhEPs+vBl)^)&#L<9>Dq$j1B3GEE?HOBnRsAWg!5rgQY?G5Y(r!QtO1Q z-LS>ySHZHK{l)($q;oK9n@p!s| zk4Yb6Z}{s+Y?EeLxNDIOKr$S>v zf9$7No45xWeddDf#I~Z&1A7cM`03zw5Bq7n*As6HzaG0Q(fSh_`6Xvx`0uaTtCBSQ zV~k;<%JsD|)?0V7Z-+{P`V6PgUG+8^mH$|JxU;rv;aHb-JfbbBukWqd#6QS&Az^y04nM8*7TXwz1riVpcfh z3l$%s04zhb#XGzmb3#6<#Sw8S7NDaeg{~$E8FY|{0NDYEi~RA2iSi#dYd0Hm+=k*{ z@lb9z-%=fZ;90RfIa_kiD$TdtTwYpTU@9-Kp;B!j6EZN5eABCt?n(QLCL+0R$HwFv za@`9&qc{F+wnn#^ZF`m(^Q_5Hht&D|+NeA-FSf_ztUYlFw*&$yRF{99t*k&+SlsOS<3c(ar7-;pk|g4{g5308~Xyr zhrcXmu|>cx6L~faPF44qjxF_vvenU}g#oqMs&lGqv@HcOQ$=61^cMTVFuN+y&L=*c z6;fN>hJe1)v_b2xa{FQR%5=M(#wWUEx2%2{bUTrp_wP7con$xZDjpEWC6csWi-f>J zp;DkAn%NQX2zIyR+jT=j4O<3gI@)`2wb!*hebt+D+8wq2>h5$;SE@oUV<%<8z(UW6>(B*X7FB7Z+w_DU|VyfO~36@6=?o zjio{5u6TTJc5Td8G`W?}%x{|--TshssK3VBn3=0C)a8_LPurfut<$~v z-E4O;i#QFg5;&(8!79O>EuGs%y;|DppZR4NKZ|?@a*IfTLJY;jule2ZA}V^wSmHAli9f@%RJvMiTb-LzI$_` z?KiZP?>O&&;Vp;H{j%Vhzu|s@Wmx637J}0z?!2Ru_5ABeTSf9w#c%29|CGVeS(sh7 z$(R10G|q3i{!S$+Z04~0c>HWX{|{1M{nE7sfLid=!|a!s8`=9XscTuo5Miy^coxu; zC>IijNji0$lg!CD_UW0T{HDdRSX;lX?2ppD?3ex0uQDClsL>LMz)LGsX?V=Xnrb46 zW8r=Uj?44Jt0E2k%?1Z4KUH3=xFn}M?99^@l&I9)ud|ez5jp9XL@z?uy;0 z54=9uyX`$*vGOJ_@0IZe!Fjo2EA{p>o9HyA!z+?c%Y4Z%pGYt3=-U<8l|PPfO@Gne z$w&CIvZArhxwovQcjXtnqBm4Jv_#{r=3>sDDW*xTi3&O@U?oDR4*_iOdnhLxD0|vZ8jinnO+Fj<6x;tdVcb^_b6YKc~&&kCwTe>b7yF+&Dh~@?g>v(%(^= zpFwL@$p*h%s)^y&Zb5piy&}{&hN1Efj5cj)_Y~7;(dKWM{EPJOJ&*%jF|(GmGddZsdmH+u5R z8|)47o=^o9#W0N3hWv2`*-gqMCCHQu;VFmLDP#^Qf&LkCS7@HFLwZgO>bGQCi%Lq; zIc6%<@?EPFq~ z&+W)fE|!Hl`IbP1)#4X%W_=V^IOac(_pd&vI7IxTKs0xt{|`;P|Buij_}c&%ee92<4xunWJvtg@mx;56k| zl<0FxSc7MV-!)J)ap1s2sJknC_iS6YLsgiitc%s{o0~aU+f&n8eIqyftIYbcs#Z&W zptrw{TVAZT2Fi=GGkerEW|uoFOP#G|u5`bsjr;)5S^b_OBxn+Ht-ezcl3rqT$QWCB zLt2HcTStGR3df9<*SJH%ZsBi|PcgV!r}zu?zbRDct+lG??j>~JeZLOn`z}MROJ~s( zn`asWBI8EIL;$ zY>e_uMO%K%8h`s&esoge|bG; z%XZR9ibo5(^2g{;&rl))C+w%~6#EtS)8~Y}Dd$hpaDFOctK#{ur=5f6u^{pMmnl9b zo=4XQK5tEpL-7syb1@F8Y31=L=1}NRc4Jl*ys@s;FN@FL;qamG`LO&sP7)qYJ`ej{ zjDsgJ{>cC-&8mimVYMyn z%GKuMVr$6W_VT7ihuIr+>#pgQ{^Dh9v(b9JSNUyyL*uSmD*K*cW)38t5CvE3v zeK^=;t*Np4YLn}8dV1Bm^86-izDBDmWlm35u_x%RVAhzmw#FK$w1<0qMr$3@G@U4H zF8$1S*IcMpxv{r*DR&^?>8Wyhb?WNWdU>|4*lNb&3s{poqqw5h+KI&ig6+s^l#c^8P~mB?A(WI1ge9S){6cCMQtCUo3-1GP zO`@%)$&^)Hq;}MqoYl@s8z3&NMCG?G$6KD6pOvdDP#7%@g$}=omHEzG1x~zi^?8cR zRcgPrw52v!kXNbkX>xG*biTHnbEP7S`;9n>tiofcs5Zu&0qq&vL z3SnRB;IWnEE`AGm?2oJW@eFwWzU@ z2@SYlZ|<01*t%oG+|DPX9qqADS1WUF+OciR#$9{f=xL62b~iS6V5|da>5Ss&c_Pk- ziU9~+@GA~l3klam9*=1T=i|0W-<)EHvB9#b#ada5ebl;j5m5;>SKE zRv%%1#ds9wqrDMoiOPgAD7Jxa8G=`UU{pePyn6Py4WC@l_`%}h<@EMgb*YN=n~ zwi5q=$>4O@ob`3U?W;sTD?H{B9Q#zt}&E{2vS5g9;f7z%?d?H z&M&3~W*}(*2U5T6*3F?d->&^zD~1cIxT(Zh0dfq5EUoz!j#4(=G7{c*uv}NsUR>S& zOl?d5V5dT-X=iy^`I#`2W3CB{Qf+Op^d@o-)!bgt%(>C%F?9ilL%^YgHQU6=W}+ia z4o+ioIS5DBo?=hL;!)_Npx+2+_Ef3y)?JG|T^p8XJF9dp#jYh^M<36xP$eoOiFv+k z=+sQ^n2xs&4|nuVw+sZ#?YWi8rXuxxsdu0>OYhE=zFyj0(%%my!P1sj-{U&ehe3MD zxme`rX)ghVJU@gn@ie>AY1btN2de6aw?#Wk%w7H}b!HCxc}rQ`Bfa&uY43)`J=Vgl zH9bx0f`)PO6|EH(XG2FrhBaqwr(!A?SZwdL6uEoyU0(L8sWaZ|c7?Oj%cfk$TIYqfi!&Gd zH`W>YU5x{IU0GQc+JBCmPX_Qk2m9AXD+R*onE&+pKp_?=f*m?RVu-)!LhL|&hvrwo zv7oIuqx19obp2a;&o{d36$YQFAe#reCu*eI0tVSfxxpnpIyTvz@;}nm=V}mCOW*0vHxx9*~%Tt8|D2{jy z9Wdi~+C{6M!u!kch2VPtR&uCR>LhtU1qPi8VqQcc z{2pB@u5 zSbS{2``Jt1^3fX7R(~&I)$p6v$EwBoEy)Pxsd#nI%2Vvq>tfbY8FJCZ6t%{G@>nD{ zv8$)&ACsdI!v9+i^8YaQ9dLG5W!`h%JGb}Vd++7Fb#9q^r}y3`liuru1OfyC2*D&E zRjOhGK~^l-uq^wz>)KiPKyaI`EV`~@|4^`yJKz7jcP0sn`&)M{nGEk~Px(Lp=Q+>m zKi^;ye?1S$jTHH_Oe7t10X62-wjw^i#J1{bLxM|fYM|U{9~eJ$i7925DgnXcubgaL zw4rn_{^vXwm<3!tyjVd4g-3e%FEd@?iSrNrFtsU$il|HT*>A~oO(X{gy?c8E7gO0( zMllDD`x9~*N{*Hb3c!m+hbh#8 ze&%sRdCMow1*}PrE%Sj_A}{;Op>%i2k0Ro48vYG#WY$@WDpShW$(DoZ)Q3!Fy``u&rtE!PF<-XM$vq?={C1)Z{5C;x;rdZ|am$z* zM`YaL^IM~H1d@ULJFj;BXUy&W>{Pb9ysZ(DvDTA)p+aXUtW4^rE1OA1tXU?VEZgL7 zIyKm_eP4&_^nKNMaI7NPb%3s$P;KK?nUma$yLb@?WY=FC4W6Hy60Oex;g3WhM~^XI zHe};}Z35i4V-Whu~rp5P)+Ik^0}3vxHn3c(i&Hz$8f^7OkzK`G6LXCGQpsa}`EkdQU}Y>9w8XUnRBJUecDP=KdE!ndV&@b;dSM4}q& z5F+o3n;4KzG8gaSO*emMR|R!)g*~Vep!53XVp!eI^6Z(ZM5tnwSv&%TL@tu^6~s{Z zKDn19YP&zIiObsy^UUMLX=QtGr**IGxNN%AbTnuKCBh$meKO-FF-4GB`>0V~1H+x4|Tv9J!^TPgX!j<1X8)+k)Te`uhIjHzFN0hDX@(WWO};K=FynDnYWi@qNgnpc)ie6( zDY}MgRX4+YtT4bn?pZBeo*DA1-}$*Y-JK(6HtVJy@+PIWS|n?p?l66fMd(sYs50ub z-5{d&8W@OKU~YjG0^HQX>2NBh<~o&gdIqb5YOWkaJ6}lff}B-t3BQ3a5E`5W|G(KZ zZZy`6Y{|~f%&;zK#G}4lM|c{kR;(NeM1mflw!Lj_wcDX6%e^-8dJ#;H_dU%Qf_`$< zCaB#0a!<7R^W$5`iUV1mL9SqonY1pTvdLt+{v@jt`os=9yc-@Y>zaTr}O zh173xL|lQm&hE96J;OD3)XwLb%6@0oWml-%Gee1Vz?u&keUYi+=srb+FHA>Oa(^&s zb|~HYl09xw3pm>butt8zl<9jMR36mmRP;7R!$|vR(FsCSxB?pZ5AvQ+hGqKu#pBwk zDRWHIHE5_=`(iew?RuR+X21jA_IsH!YisJpOM-zdxrV8p?g$E_WLl}e+NI9Wu0dlFIGbvm)osIytU?y)e$I#dO#Y4(bNWa76vhYV_S{<9xX8_fk-Q{)^&+q zA)xQUA~wWJ3oQ@4amElk@_N#x_GH3}&_E&Q4_h>>*q*D*#v{eB%_BLI4FzW-y1}a} zXUO~doUW)VQnkx0!S3poo~+6{d3dgp4X1))US_k^lQp?D33oj^O#J~jA7+xb(uPbl z?W47!+kZA6%!}Jk&hTPB_%$JZ2EA!XC^DgZW^y7Id&?X}X121JiWcY`J5xKnQ`{W0 zGm3m_Vs?|&(`QeG8e?OP5P7b1TpH-Qbk@$1qYLOdpA2KxsbuBCtaDYFS2~Qe{+ZwA9)yZV9V3rz8! z4f%mo(i0B3Y&H#lInRoFFVFwMbB{WF)+D#W|L8rA8qblFpiHh z?-KTDg$qfHPUG3{FgI~`Md*H_@m$NV=jdJZ8ZQe=)2e*jaI>&Xq%iLr*~wXp`jGgu{$=K6%TZRGoNFe_8BcM8%(VTorgxiAxP`prhQMx;sh zsOcsUjLk#;oRf48h^8(e3-yLtwhpl6$hm{%40ZmirO^bP!`xe9jj2+;{u z?S(8G5NmH#PSCxeiR{3q0xtIrOh6g5g?0a7X&l$&$Y)sAdee|xf*a z(|HYKo5|#`q#b4ozZ#7tS!jyEEfb6>#(Mt`BgdVSE{xd%CoR3A7xkf4od8%Z$4gNk ztuBV1QHu}rio0_Lgy2-X4Q%Ei@nBZs3|gFtpdx1F<&CBGkT<+ERNGTWT2D zj&{lpBQE9uUCZ&cDwgPIPQ?9u+^4_>0bA(}!&Js zEyT))zsoE(UoZ}rG!=8&o^pA+CNd_C&1ZH*wEmcBx-oF0Mu==tHlX&@ZK2<166$Sf zmMsL^-3Ja0%qaJdtt?30Zm+z{t%-X?!LXa%a@&>BzUgZlVM#vdGa-`ZWSuZ9b2I8$ ze2}}At+^Co;2;t3BEhp^W>!Dge35JcjsSAkSwgHRT3?L5VSY#-K4T%>+hS3+`K-D@ zzPG?Os}_gZ`tZEE*crcr8P*Hu)@vP+r)GY}bO4hr;yfW3P$G=7j<;F>h5};fc*_yL zg$jpsamt@BtY_vxZc-7$aYF-yIrW{|UfG*1nQd;AfAIWHJCHOMxb}QoAGwnk zr2djJLy#Xe)o5zAT0t8W9g2*8oX{64wXGs1PG;Cp)flFZcn^pM>ZDh zB^CbigK}@o;f|QLF`umTvCYrqZ|(7^JRtJ&S4?*X$v7)hW*C{+kaRi2c9#*52OI$G z%)5Cr@GT&BX_f^*a$Pwo(nW0!RbLQ7Y|ATZIW+=U7V2(HWEC@|A|D8MWCtrsPk)N}L2RtR9*Fez4cxKRV=zf!S;ne9gg}XRqj*nKN~c z*5ya(zTn>#^ioN1m3!;aLo3Y4Q+!TMEBcLHuyn+%3w@ulHGiwoZ&nXqHhJ_4J1cUe zM^oh~i*D+d3Bxy8_8$$?Huk{qfp34SaoORS+*<_T4@_; zu82E_7Ha)KEI3N;Z~jEC(XctcLk`$kOO$rM`em$x zMs&|GcT!x(aSsI{oqMbB6_jXh-Fvn$CI7Iv@!m6Xlp*hOEiPR`mo z+gY+Xs!4Z*^g*NMTRY$;$b9q!$^jAg{s3K|XR(H8>+Con!|4FsD-#MLA;H5dNbqO|Tr(sA-3ptln$l#?c z8n;4WGX|2~*CVh#d}g6~eAgGmqEK@c1HEXztV`d8{}g2rrUf!Fuoq z{jQwZEGVkfj*2JZvp5N&$vED&8-h;#bghYczy#O%6linZ)6i;?bvsK&uiL?nlW#RY zzvtbtgg$8|`<0)`5D&|~db7ekaozY9@yL$tbYCg6gSSj_kPYhZDeT9o6>w~n`rzC= zT>^}eFknQI13}g8N(Ch_uR1-&_8%Cvt!@s-BKDy4{a4M#htdItu}I{4rBKi_gk{Y2 z4;#YEhCWNRXm%`C291HJ3&T?R#~Pl-8mQM?7Z)QKxK?2%jR~lmFz(2DvoY0nw)r@D znq`H~E+4M^cy0>xB>Rvwcm_hr`--KjHy&5VxbIRd(MDcljHxOfR9JAYC)VBa7)iy|NkUS%n+6F7E z{h^|Ld&svt%S<&(wNSov#jtbfvVu`(AvUo$-Pv5~YiyDDN4@zv%SMWUbS$`yjBlF= z`cY-V*|j!uE5=q(iSPp(pc-ytFKPWJR!Sm@dq>@;-i>a=wHxJ>GGmt6H@>7hegIt+Jzc(RjqE)_bx zDM!kxHFRX&4VA;%ASuXcBygT?$R|z^^~NnBX<g~$R z8r#D?wQ50KN{|}@ZZ+h;$^V%1hVJNuDz*|kd#}Ej(T=@*VGp0gI4Uli2ugvV1Ms>u zlAso#i+fdA9WE^zcZu`lNtO-YUFzi7G**LXvCui>NfU3W+t^FT80nsp5EY|U7|n{l zf-dOHko`3GfVDixjbWg7iPjNEOVa={u!5X`*K+Wj2e4iLK=a$=!3-;i)R&^E(s9#? zK8HaOa2Sks(%762(6JVk#m+=byear=PxBQ6K!?HMY{?^e6Jr7CP`k{9EcC$eZ#vGp zrlD0kDszS0R?bC>np$6fIh`;>jR94A^8oo1%Zgc}KUkurbpAj&HC?MurJ@#-?46v{ z=-fjiqEt9XPYH)5U`|usR7)K?truD^2NLF510#@lt2=1r^eD&hO^~FBnm*=S< zZ+09@=Iu6V6s0kgAIHBqJEH`T4eX_D>EZ?51ph^Kk_XZGa{QE@Jl(-|?d**>-mnjr zQ`gLXcjO$o&)cAjt*`Vm9ey^{87(M|k{!;I58~4lQ?zmWEaLJC*jl>Q902-7L8W_4 z3Ac5M;8;DUae9K8f0TA@@sT%kthB?R4_aAgsu63~h!hHuE>8YrDQ4}xAOHMtLB~n$ z?`&h)&g_1Z&?D0dX&#uYeVhCS=gZxnrpSt8dRs&-B+qLJA51@67?0Q4i=1m@h#o@3xEc+Z5XT}Msrm}#!{Ws!4#q8CFkiw>sFaE)eau z1Y6u7(p&Os$NL>LX9ADM`8ybFcD=WOknUd>BQmK5yV?FyL~?!4!d-LTJI{5^GP~OG z9tf4SKd~KyJI96sx6HTp=mh@jGrTZeH|k|Cev=A-0M{9590&&l+rr_3=Wl+WtI=TV zb?9!O@5w#B8@oYXn3Z5W)Yy7oH z+deQqCTdM^;he%}iXN%K$MfgVE9$$A6mN5W?m<(E$Rhgoj!-z18ZA{^kz_l%oA7b< z+@d%0`3k4GQ?FDeBSmLdqm=X*OVd`XT#GU_vQ}^Yvh6{v4AGtt=MO5A+oBdr$W>ef zzTA}-CD2AlZgxl0p@&^(!fYV5J)ARWIz0lT*6n>);4(cpmNi53-+?y5wBA$LiK!Ze zuimMO?tDyhY=365{}f08(tN5p$^8yep!@F$o9p`orzt_j6 zt?xOUqYxeQ{2Kmagr}vI7Pw!CFR-*PyeH5~v0zuB2K1DnXa>5+++YbN)Zh5z3-QHp zgw@9s8ToK~y~6a@K3z@eO&U6IYQUp>b@I+6n>A$y5GF{yy!$A?76V*WYUUPp%s7`6ddUp<8QButelxUKW4%&u!mW|GPo@cbIc>ZE5Ybwe!^S zp@oq#`l#d4M^A=M(!WCu50Bi*q`8~L9MS`x<0KNC1w)xYx}ZPjSw0jk;U!SJGN6bH z-mgr_hL-oJ3S0U+#=E_E4%#J75`og8GuTM87+2arjmWeD9W$~|oR!7+-hpIJk(lV3 zX=Fo1p*|awi_v|`rLNKWG=B~|_V2uGtG=9$?WCP9S{3F<2wh4G?+ACP0{sj#HO0=& zF>I*Ix^>19Q8Q2Sv!NK<6p}x%KC4lHOJOmK#Z;hs0o%NG2NQ-Yq+4Bf*6(#8nZp&w zY*0$;xQ5!LphDd8znuFeE~o!{Ot|@DsY*X>2xU(!R=1Ucc%!WS&Pn1f%O zL>_UOs2Mane~}M;l4YMT>Uqqv-?ZvkJTkcF`W2t@z2EWSJ%vn2?2ze&vUUMOn*VNg zIN@YOL3HmEM*NSv(Rq`KHaH^jmD`Me_cY3~biOYO>gM zZzQ*0FH#$ocCm+$-OUAgkp2pW#(K4DJZ1{H9X`itVI*Q~gZfZh!d}Y1&&1ULCl4op;bryCW%WBR)@Rm%Esp$4;$S0C4GS4LT=UJY8)ox^Y`e!1= zPwk(*G}q(yA=e{^1%mDzZ@z|CgRW}39QKIwwj5QE5Kt=%J)_doGV`tEW(}b`cT#Vc z38F6y0<3b>Ln{SJ&Bt4PHu*v>X7?mkgfX>8rIQe^;bJz(8D7r@iT_IKsH>Zq5x4hS zQm#ZXq_EiyLV?L`K-{K{*s^^Yx6jB=TS^|DTBwq$H4^?t&L|K_nJ(sx{^v{+J8xpd z(r`Ot*87Ss)L08-eqLIq&?;pLu}ymDQNY<@3vbDi_wlZ>jaPxu5zO5olu#bpxwed=^XX+=L2Nw?S z7*xF4wXjA7KFl5WrP&uAIe4s^XmqBfe63U^61S&IDgumLrHIULS1+H z{zKDYXU0<=J6NSidV6tbq%)Xib)!jt(I%JMih(E`HnnZ(Ha>ZZ@nb(IN zxj9fMgJ=>t4Wok3A@rc&_m)~^zSotF>kP_viD2%k{==gNKTn_(`(#q7S?e@q^ft+u zOCeT~XJwgP#mdo8rMS~BRha~l=IAZ`E7x>}qFU6@2=yYqK$?(CEe3DQ+T9xvNonB- z?t`>hkk>L|e)P2*u6_nW5kO5WCWEBf#-^-S*5HpYNaT9SlFRBClTUPW_I-+Wx+%fE84a)YDyLB$F{^iV>~Et70{_c&MmNxI=EGs}Wf`(R<{& zPVvCqhgNzaFihLlHV64v^rhBNjsX#BndDjef0PWOCr2oImSAuzr$BK)kh(tZc_X%P zcP=OsC`1a>pAewbG2CP~36%yZpJ5nv-u5B!!Mq_9bLw;|a-|(z8c91}(LF!XyhEuE zTVX~6!YitKq|WR@$0G&MMGR1_6D2tg)GyMxfKjK4&jqhsK|R;Y8Os!?|#k;xT%4|YiDtBJU2)JEP1yugEnq&ZS>f%>43 z^WAzHchR_JgH<3Adui^BPay`$qVplY4TKq1<&ND*LLZ}VvtP>i8IUw0flv6 z97BkR#tqDkAew>#j*GeU`)Kur@$ok=7`ApeVuvmHw~pc%2nLlHI}n(ZCM1Ie`6UC9 zhXg)7-h^s#T?FW7JNaj38;xrzbH+WBM;YT`+xq7t!_Jeb{tDy`%~K> z*^T}{E=Y-kthZ&O#op_27qv1p6Nk2+!D7nRXxJRdzIZIVrKePyn@cl3UAolAE+qrZ zR3xGE1S{2JLknH(@EBE5oVx{c`EF}2GXaSXk0fH&vY#&VseipQ3}}#f|y($bB~nw76!C;dtGyPeq`nF z^B?tSdx~Bg(7naWstkUghS2v>BeP_U1GCeKM6l;uMUW z)hbFeq(4v?|bX5!i5o@IEkNs0zDaU;iaNYz@0*&I|yPBj%N*`+X|4w?FA96}?-(IuY`+CaK=; zvx+^eNy55vIU8S_t%Q}H?!@FyjKw3z85#OVb8pXrmc;hM7@*Sz1(KAbr9h(<$>rNM zT1Ubj8;=G$vwRbqtt_xAM>-Nyyy-9|tp+d>UBY-EY?|#UZe!`~WWFgpS@3D?8H3e^ zy4AmBz5=!UB6P#fF&bQG7~l%XdGtwm>Qs@WdRXuDE78l*WJ_B0BD{LJI54zeV`R1h z?~4wj&E$wVpEfu{R@v0S1Jg=>%0+eQ1oIreN#EmZyAWh}0%ub?eab!H;%R+uXF!*N zJw`2Rsx62IUJilZwqmal=WAOcM*V4xx1Rjxnmy*ZF8b?OtHyADwVrRzKauJ0E@u1q zYD;2QMj!A=JXUwOTjq^Ax{LW9i79^|VUjsqVSC8K9O}W3dWvF;&!ImV@UVI$OG8iL zcl^2T?jlV+UgHW&yf$YrinaU!YuL-&z*S_zNm1Y4N}#Cm0y>905FUV!!3*59g$_-Q zo+&Xk_C;z=`sd=QJ>D)HB?sWodL7U>@@cmH;J@% zqn6RvR+tH?hg~iOwZ<14=f6z$xlBX7wSeB_D1`^2w>SdxgT|GD-DpVq%AQX)#E#@b zQPs1J(`h>2_6f|l3kR_=Uykagq4)o0&VXin^`Ls=P#Xg^NV;={(m=f z$u>|P%-YM?=i})Am!h2kNXyb;-nd*3XF&D3RY)CxE8mWNX2 zrcgz?f3R{}bt&gp3YqQuETeswtAiuC?0jd&ZIlT~57WLF=Sj@brK&twn$G0=nEDNq zM3oxrZjfwRDsV&wijl^`5pT}{dp_&3Mti$g26xn=ji#%(Oc;iw#`{B*NTd70t>>i+ z>xqKvqv!d1{KprdAAWkCtxG<@eDJbd)p#u`MUstyNh^?ZD`=c_c3y`S$B+eB&se+YAX4Rb^HTkN$Lhy^GCcawz% z9xXP7v}g3VM!_YN;01!PEUbS<*Zj34T<@hL<{p;T4Pc}HQY|h;qF8Ad$9Va^exn(n%H}P#81ziPwkpt>V zXU*A2(C`3JbVU#vdK-s><1N1iH-xrQ{}zl0zje0ZOZ7I)F4o$yDpgl%nQ3#+z)&EZ zRqMlgo!$L}$weN*@bB_;8O{2gUgzh7!=lDmZ{pb@wh@f(kOpU#tm>;1*K+3$sYcI} z8xX_7@6cXo7#%rcinQHa+R?3Vg^n;LIDU#9S{o4XdMXNMEmGT*jq1BPn*TYWBindVa z2sf8MVlID+xo}7r-MuJwf%tJLN$TG~*m^zu99LjfBkDfZODat@^AC5eE~Q8NBkd(G z`IqKD@>a&()%oD?()VOWio1y>m}zJjc;Ww6%pH$%-Hm7PUFzaWZmB*B2cJ$h7lPI zW{ZeWoIq{SLztg|&h0I`fXAMxAbOB7^bkkW%RF|j-h8DCozXjT4O{2WsMryG^Jhel zPrwE?nRnnjWv=rrA`6c1>SDg5d|+r6BI)2vzIV@|9N>Fu$jKMtiJ&rzC7DnC&So`Yg1Iqza9}rrL}7 z0P|ozcVj-V3@vU8_pMvvsi*xPTHC~C7|Ye8wU>1VAe?FD!CL~c>Bji5H~eVQTl2Uj z;_K|YF7N(t_l=FlR~U&UjH3Dx{-i?QtZwXK=i2`wxUgB7u%_H zGJ+HH6PGjJ$PCA<;`eTvn_-2Hdatp_TX^C8t)zsy1J(0ks;%Fj+h+b;l$Epql5gt z;hsigZ;#L%sr!qwDTk!1+*uRqv!Prp)i7$)7Dw|Ths&0AP)?OudjmZishy&4g|<2z zUNjDRH`Pf@5aJ9o5rm9*2xvbzD0)%3P|zERACr6Jbn`uekiU0Ze`TU}=iV&S;Uw2C z4trRnf8|zkd8nXLHlAoSe(p{$#1Diy%s*!FFCkpu6bsNG2maeaq<%0&+=#)Lge5g6;e7Uzjqx9`_5A@s4&e}dD zlXM+UxhD3_f9AWXd4UU$Rys7eaWXHj$aLSR=kAS66!AG<9P<>bKlE z9y-gp0e}oCwO_WCx#LV@Vb^w%9PclEYG`lsMUk|P+>~MH-{A=U>&Vq9fjkk7Oz!OEWQy8ZiYruzvEF_)fEiE*b;@EB?_ut`wZ6Dz zJ6~)t)fRjA{-o>Hcr-&7@JN;XE1Sse9-gd_P4s+z3q8IO-vtLwI5TC`w-Nx{NwkUs z6v7sF5g>uaRc_XglC`rF&0jIMH@`A6N)*`fOCSc<%L#U!3&E(KTroaxE97+g ze|lGaWP50#9v<;WD%<0=_-g|Sn_Nlmz{)<^>j;IUif_Au6?Bx1-F1nr2vT+g&&&a` zz%H$O>6TT7%FzxlbdUn4gIsTb6TSByG~3czHL=2PefVtixvmUfBk~Jn$_TpAcFt^b z&qtSRleJQ6^j+irvePW!A8#~1TMMYnZbe$6QU?s0{$hFX9bM^gl!-td>3XlldaYp2 zpbKu=p_%GI5HmuSit~0x{>AvmiIrwX&lp%_#t06z%0)|6a%0x?BaC$!4^)<&pomB#n(3zw}jrEfU9 zd0@C1XKq~GY&9CLYX00EP7lVagZu4KwNj^Zr-RCBWSc!6)EJ{N%h1HOM&rg6r=!C? zf0T?n-GNZ0<*zV5>QBIAP-M4p`j`PKl3Q_^o96~%X{|mi27Rq6hBo5!ns9D zPv?=&`QFBJsxA=;Q($4f@d{3Fs2%tPzT2wkqL7s{0klH01!PfUNDDG(BS<#q-VG!0 z+B-Y%F$ROWp8NI2V7+AD6U}|Md5ru>GQ~j_`#xXJDmxSzzh>m<-QM9XxBU=9!2ho? zS7IDaKk*(dWNo7v9^Q$^EnE_*{;Qdhh zU5lfgslaza)$QBy&DY_>KaFn&sKfw;Q>Y{KqOk&S9go#>p03bZ5mtb$^76E9BYC`Q zX}Y!|+SEB?^(Wo3P1o)l9J`Zw`tH&G{nu=nyk@QKWO=#KzxdIQZtn7z(ebr*?aK11 z?5;-RF4@tgg?Er1#9r7t-rCRBUSs|P<4d4FhyyOUR?J;s_}@%s%8pt%vy~<9=vtbo zZMrzAQ~L)-zsUUf?y&(nsgrAM*F+3%yFnRnEjRj>F3#=Lrlq6Y+@!}AFV3xnZzx`* zcW^Fhw1SE&4wy!*9MA#`M>7Zr)W?Xt*~y$e+x%OF4=r)X*dN8wykG4o%FB`P0Psh< zCmOaX998m-D}kk6-a>v(4mi>uI?lWZ}{=|N4k;JIdRBoZ4XOQ;uUDF6fPSWscq1v}uFx>E?ZSgTvuS9dEtD<I%%*!<}FKa1-B zOaEy-waKVbeA_SWTlDq&ZGZXA?*q3DLE!@|?_7+PKlI)sPs=q3KUrFyk2-aad{`NFz( zv4ZdnR?E%lDDz*2Xi`b|+PF9Ck{eBYWJ61If64jhn6Iy$#TqESK?u42Nqih@;A+gV zzgSvJODQplVVhr7GdzLXps?CADgMetoiZg57)lB_6+w5H%NE^%JG^XmwG#~F0F-U+jp?Y=)5jm zo)XBOr0c)r_k{rF0;Dp_m;CyFz2(d>?rX42Gisqpqgm#OqaC5HF0_e zwneSciNtBo+R}al2fs zC8a3;ViiZm;HMIMk(1eABgiT)wA%4iPxJ8&V&cPRTEs+`!R6GWK=S*4!A~HLfiI?U zX9q^1z7_(6t58A64JS%eJAfhJqB*f`5n(hOz7U<_pCNaVic+|&y_;QnrH>kN)3>h;Q1n{~wb1X8fkJt3^j!;G znNS?2gMn0pnElLA;0OctG=}wzq@Y!B(Nex`H+}i^>8)E%|LE$!dHm!xk3UXEww%6c z>$aOtH?R5db=N%p#8oFBr{~?~L|-~B^HH2OFg@6?Rvj0Ih-k57ORuSx^H7&S6MQX> z$SHBA=8L=bswH}*oyUlaql(;#_+Zp7`F`KLHyc)JGNmAS-4w(9x?L;5?-|3rMQ2jL zYv+G@+tl_>YbfP=M`y;Fz{BNuC~=j_9zop{iY}Pz_>rVIVa2LIXg`Yi0EXJgvN7JJV~H*Gw7v<+?xj? zwu8=FPHu91PUI(|;}03_Mq)JS{#K{UmhI}oa_-bXrt0h&de=lcn$d+VM%8khwb(ir z2OSB$R>0RAVwU42NxRypfee_O5fEc+OXV3|FF$%ZoanS!> zk2O%#3LC5!Y*cfxndzmKt+V?-YV+81W_`53f2hAdrZ?$rZrkJg$?Vv~pb6Wwm5(%qf#vM3&QdFuYVJ#}aEP$iM5Y{j&2R`fsqAM_XT z1$Vwqa(bbb8mINAJ6cl9{UWzL zgxt=*s?u8glp*#F8-D06U#hfkKVBD{x@_%>A@} z8u$PwBcgQ!xojs{F9}l+q(nj2V7g>--@7CRW5iPm^+p1h7d0Jyd+!~Nhz<;)Yo4sV z9sP}kv0Iq?uHND)oxuhWcYpjc8E~QgL$;Bl&c5lqlna*G=>NyySuG&O?(~UfoFE%*+`3>jF=H>;B<1 z&*e2#SKhnBrCO3@$er|Cjs_7o-G7jBFccTZT_07(<6E`$VSB$48|{uO z5?;sF=Cj`6vs<`n?6_+xt=yPJyU-tYr3M@di6mrKMG9)U$-H#Om0g%sZS&a^1Muv;jUt|{K+GsvJDL+MeR-p`r=l3cD^z_%6r%x^lPF4 z6HnNUwMRguFplt_$CPFTVdWdK*I~c`dAs>_4SeTuAv3E+XY`Ee;iIQXcPy z*?kA6l)kjfm36A28ZAHi81%zU(H^~b*NQ7?DwMy@7Pqp60WN`>(BDN%1rOJ)sa?ko0pDNDOQIf*b~r#0Iv5fjjfJsDnAkj1=Wo8EFqL$O>#{)g zK;O(2MZ=EmwvpcB$W3N%dsHbP;Hc0W}mLncwzE}=JvueLwLW0G2^$%*1pOACGTI*<8gP}Wo=is z-AMI@o+EWPE!C&N9_{Q7RYC-#5UF) z`;nt11%@)%0xyLY?cb;!8$>@*n?Jj$T)$eZQA^bZFW%uy`J8%SpdPm-T<3wdt@c!M^6Y0(U%X3>7%P)OeqK`Wc9?BFx z@d7h?W3xKd>k{lZ$C>8lt4%OeYd@j)ee^VhT5on;;}?jsT`5tk^hQNvw8s~a=`<2` zyO#MTQMD`h(sm(p{Mv!Ncq32F(=hZ~O!I#70(umF26zLZCD$1rW-XA*^J%pQ0w7vw zTR35G_>~qTAt9dBn_ej4WjmjocSL#RJ_GX^s~#_%D-zvmXWC~mds80uwr$)z*DB=K zYu{nc(wO$*m$Uh+Jdvo|kc%*96HZ&oAM`}w3%}47Cu8I}!~jN4QV3W4Lyw!G=9ZgO zmb6Q)E+*`7M|0Aya8~b$kmp1`hdUT{hCIz*M;!rFz<>fk%=+Bgi_DM7f4A768p@V% zj|vs}2$#8!ai|~0WP>(^3xa!!ktIq6u)l~e5!#{ZDA4=Uqldlmmb;>L` z&l^`hasC%X*E6x>EAt^&*VJqedN{ZYmvei$_Kmd{d5>XC9>rUHG~y$W(f`HB4j%8Z z)z$OM%5c)PAH!d9%f|3G{oVTTMCmNY7;SUmf0%{L2gU_!hip90_{pnu?X-eRz42;; z9_$(dZmzX59&!*Op+SpPVYhIji~J@uR1EA4tBlue`5n{OJ#K!OEEL)u?%5G@k_>ud zE+Xqp&70)SKXuQ3yq0z^7W=33j^IMV?MiazjdA}T^>vTXtR7-uuGi_tkRXofS*{O8 z2Svj)fG=329NC?9?;w%D)tg@@LV-qLB;^V72N&En(m6X~^U8TdY%T`leN4KB2Zfr+ z-svaQc8y-B3r-gXr_;L5K7s}`YPrnpGnQ!&tG2bL$QzJpY9(n;W3&fgX{X25gUA=q z3vMtwP#=pe0qVmh;m#A+teTh|*{q}9cLPc5mdLUr6m;%5sgrTd1%Gl}|G}<<72D^MkeqGa3obg0hvi@?i}bK6;Mu zE#_E{y-a2F=WCy5KFjMvAfd#TSNCq&~ZoShi+H%X0gLjfI9J=Y&T}=sjojs^@cg35Z^w#6S@#*0z zCg>|zWyW1Yv%4oaefcKuI`R{)S0J1hssdUAA-1MxL@!mL!&MHwn2;`qytE!hM|4*} zkp?YvX1*|;aE|16_by~g-jKQC45t;39&5fj_WdbuWV|!7m@2MB8^>-IlJ8BFG{*5p zSABdYok_TiDSwB3y!poWJ}|n|^C-E=xIu-Hgmw(vlP$AgR7`SIG*%z5Tj zRZwspk8Mk-1cE-}PcQuZC;0jGsJbcs+0Wm^&u`#q+Nu|R{?gjhye~07ucX;y2xwmnNymNp!XPs zw0h8Qq}~*gO`B)6g6)78|JxJj_ms-6(aqv~=WZtC5)zmCrJH|iibtGapxQT!w#W0s z3%cfS;Mlg4)6RrZVwx}~?S4scLSJ0GT_Bh0r6yjFuAKBo`q^0{uo`^*cbMDAuejUh zT#+u9AlR_CEh-at7^0+b%AKxtA2_gQ&%WYNY-Eo>-9gAtqnYPH0e z+7*XouH+M!*-4`QBiu9A_MF7{VcwOt2t3cubQhC0tUaP3u*tR6IszXpC~U z40-7nm=gINy#s>xs5lsVJ=5tBy^on`*s@vI z7f(%GIYm~3cAE!x{essHBzss-)*_qEdhH7d-6nD^bNBdeqD$@Uz4c-H1QEH)NxTdM z>w|sy_1bgHEs%?r%?9x1>AC)x8xV!w%Yg+4gM}F(fYmGL1R2$QUu3q%T0S!J_flV` zoGpb^inAfBN1SlTomxi5mx<&Gu{zliBE93=!X33J|Cy<;h_^TkV?$NPZmI9ykWU#* z$rQW=A_gzsPL$puI-lP{PN$)JRs123-ct|>#A%#ltTW;;-rTmdLMVGIufM|%iz z)-YgWom%Z=bzoOYi;JL3mc^bze@I{0GBoO(4~DBrb=Q2|zM$j1Gs4aFJIprB6?tsj zIY9cB!(&`o@dYcz%`2F{ch8mD{YQ@M=SzHvxm@gsJj|bPcJ(_m0nLa97ovW}9GLvv z`JaTeTc{tjb0DDol~6}5F5h|m!#;y<+1pHe3Z^hJF2I0^SI*A^FR@uAU3 zeS6U>TPPG(J0oNLd-Q|6Ir3}8qOn_RP&@h$kB2oTUp8rJOo{B_`dBksjrr5Ia-h)7 z$z~Jx<$e$Qf$3}*eIT2+GZ_n=ychXpqs z2fpxYv3WG zK=S0>9bXA|dXctcU3(O>#c{BtO zkd7Oda-%R!+^{%TX6KP3&Byvzh{`vR_W48lQC=LE6Nuk*><)6-czLF7*YAxoS^=|t z%vmaV3==y3wrI{cr8)o7&AUiP^DEsm{!L;vx2JEey+GasE<&sYji6`90`YLgdSGC< z%<2ELp%&D4V(M#0kA9%k^MH|WlO&|B^h|#8GI9_yI^9=3Nfx+x3-vG1*DN_tt1|KS z8icULI&&qVT+$nsW+S2p_qI-v!SXWM)!5bXBj;w866vHl7vIJT^sWwndcdce8CmY? z>bONgjwEjOc$n?edXu<4;SZ$p7MCj~Hi06vr&;U3lt3uA6#L8siC}t;40>BU3;aOy zvK#>nIF8#loX@#XDy+vIbJkb?&2Ug>4ja@XLtV?)?>RT7EgxU5E>@%Oj5%+ADXVux z^inc2v#@7wC|Qnnj%sE#Jq9PmmcLzlhRHJdR#cR01(py?x^h%8Wzo8qx-xDMJdXga zX!#nfn8*5xIg{EyR*G+rSFU$4OM-AZoN!)8PK_}ArP%!{awK~Ng9q*;jK>Oe@sHtsOXXS|rSYi8u1&KBdXOY^eA>iY?m9E>rgv{Q0QzGuoM0 z^7CewSZF4>^S?MPGhiRzSlhyMLw1m};A&fu>!VnJlMw*E^*A|b^ujq`FaW|JU|(Pp zy?w)O*9zUWQY|1RdG#~KJ=gEH2p&3jV7Pl;wcRt^#W3wcncCpgHs6qcZj#*Tj2R_L z$&k_+lA42y>eEGig_K|1sRdCCd0P7w@Y?NoU!}FPmju3? z0py%HFltMnUP_dY96NI47#c8p4!+Y}DA;2Ob!qUfM)HxFcVkDxh4G;J*j1(JuvR`I zy!-+B{a+)lJ;MknCehF!3B3=HVx<^?5@5(nw+^ty7U8x;;58e1ImZK2&M|gsCZ;de zV+W2L*|(`9y$~j!Q~Jj9(Q~@E@y@QX%Q`IdW@pEzp|0X%^~6fW#@Tez#$Wpmc?uX5 z=cwh(O%8T#eW;vwV`1zurP1rJ+OFHby1JjQN%)GcC5a1}zUcX5G1+qx%g)j&O;xzpM zMKsb#-0cBd=*|5xSz`{qj8J-T7f;}1clSGZmgkzUSggX(+;8Ll(V0y>Hb=o>J|LSh znID{m_4otM+ljkkLe3L-DQSlnE;2|{z_oIwvUS?@s2mLAT>YnKk2HVbvE?KBLT@Q} z)A4Z1W3?gU>&m6$Kc9Z7Ii#IeC<3Kzl|2v0CS>ZsV7f5o1M`lv{|&~v3D^*OMv*ZL zFg*EF<*}lY~B1K-ru?AT^3cn8T~&NONxtmtnO^L#Q_4E|i?RPm=#zIoN(Z zPi9Ft)Rp7|5=Y2mCiMiPEBg%|k-SS<%h5+!b}xLyAUWw*c@utN`>a4~W8I}R=JO`( zp%QBp(p~{vvKfWpaHzEVI~|)(bqap!Q(0%nq~J&6vxmfr*p0+_^r&I(#gHeVeX9AH zt@+Q1MKeG9+4)~Qp!H$jXzVbAZ-O1yLNSdSks!PsiW4{vhzcCG4?2oLey9wjyv(81 z)mxO)B_pq0E_?Tnqq0EXm(A&v?H=;q5_8@k|0s-t#hl(I6$@w5@1Ko1BmNnT^{2JR z7$IyT@Hn5w3lw1i)WR-swO`aQaL}B?y)7h6V<$K|B-6sTJbbU|W8=8-+v!ZiJ9}3$ z`q8bqO4`4;*wq+q*ZYRpQ)A@P8u_%Jq?f! ztrjEyk;Rg-t>*XS$P<=S&1Z{EvvH|2>N9V_8=YR;wrpX3or9~a zz1a3K>^;UeB4Ym7(W9UZF}{B7@0iWpUCWm5fPCTUc#y{e=#oA*G#Wnj1iJoh0`({_k3&RJCCT4mmED%VwDxFFt5pEqj|8uGvv9+h$zRJ8pv((7X5KbWzEn*+{ zNpksG{p7%^Kx0WcoG#e{qP$mj-r3#Ml3%FPjauB zyx^MuKV{zm9#?TSs<|s^)!S;dsw-{R?rMAQMXS}SuU4zxnOGxwKT`hr^9!Lbt(F8Lu)ZDhsNm>Y73^U#||-748ql(yL9ITQ#i{_4$%YZ+56$ zY63GJujv(uw;?CA3ihz!eb@C4u|nejH9xDg?J|0_jgtd=Dy0o|dFQN3;fSVNH6D>U zA!QId_bBm7Vg%-?POBsE5gwrLn*zv)0#8Z+cro>rX6HM=|!90@YPe%;@0Lgx|5G3rA1U-~umJbA|y9{q%;Ouw;n z{?^gNYuyxeyEyT|x0;~~kRRiho=tm<`U8v$_A)PJWDZc@W8yGh?lBk(CL8uD>+)7s zsM5mBO6`#6{-TSUD0tU_x}*d;x|_oE%7yj-1-$ZUx@kP|_nY2bSwX)=+5dVIDpHrS zEqz3Y4%804J0B`by#Fov#Z25cx>T3=EX{c7eLO#S z(aU66d06w$)Q8ZU2;Ron4rPq_1gn}+O3u1M?94=LHKO?8P&JdR zh9A#h#Y!^12961Kda!OKKVemYc1^(F_^<_uR3Qa=N>v9NDdotA(sSgNDX*r@s4C-U za9652%)9DdRzc3BMKZ*%Dl5_ybSWc3w?n!*TCNh8SLO&PH8&O;sDf?b(XC87$-&9a*O;yS*nkmpdOk0hL) z0mFhTql+WB)=ib0rh-TANzZ}Tq)Vv&V*Q?UXB*e^J~j$_4wBn2m(YRa@8F2)27;bLN>t%r-B?$LJF#D(P+t15q1 zS)sLxL>dXV;j7yc|Euday>-%FZ?(2b($LjV5!i7h1dV&FC8ynTVXZw}*pMx-*Ndz* zh2vd`fBpu-#-gvS)l6rrjq;YU)*R9M-*M&(>A0~9Y=-}t2F@go8xs{v^BQcGv3?HW zVxk!SZ5Ww@u4%OcFSb@o&G52VVQxWY5eGPOyuB)1qf*s;A*x)hR8~*82%A<_Qt6zm z^c>2g4x3<)th1uNrdC_?#VE73NnTCc(TUl_EotIQAK?3JIkZy?q=(_$5bma5kOXTK zN4v2DHB(htUM4Zf&0&d3A}MdO>kH(5o7yi_xpve_YZHIq6_jbJ6e^ygQd+_*HyLd8 zsD$sBD}rFetk_fmCN4^BN~qIXFMWv5e{+a|gYmRM=D~LNWsrO^@XqO%m*m4SdRbYO zy;d$1dRh!+brj^LNXo-jLspr(Vnm|&q*4z z6%~>k2?})1wYU>MkZ{B^d2=^p!ULD-=_s?_rrxDhY1I_0-e@TpU9 zK*rDfUB}|V&Ix22HcRtw?>Hy$Pu(OFi{xS<)ovMW8Xs#eSuIwJYm3l{_G7%w+UCi- zDm7YJm7QE5j$>DEpm)JOf}v&1<|o*?n7>#T9p8pRxDHJFujS{67eo*=ZW^vCkLHP` zs=7+^a#MC`ytZ^}dE9xjDxRki-&H9Q;ggv(KDF>JDTVL5!S^gOSv24=!2T3$Hex9R zzY&KB+of>W0j9;t3(B>P6T8%dq9`iQ6l9fT<)q&&%R(zWfv|9NWpvZlLQMpR>#j0I zGD-rHK&Y}a8{)CxvFGITa$}sSd`?akzeZi<(|9`Dt7@wxf@(Ot0zoJ6U*Ch6U@fL) z8HsojN+O#lU@kK+e|RYlEyQt94Q*DphLsbIJ)82y)_%vI%DeLXX0^W#qQ8=fhHOfG zSFy6&5oui*@Jx?-W#1o_+3KuHxIbEi(i=1;U(tL6cGKX^=~vMG5Wj<*YI;>=f(+Ky zDL@~L9}Xg3OX3eTUcD>OqTXVe?;AA#kLWvmgUrx9t%N87;l-c8t*#${4hP*M1B;rN z_1IKqB{-IVd^!5jpa1-TcWb@ZA`nZEUb}qv1KY)V#Z%qKhC6Is@*>_?@tr$XZY%5u z0|`W1TGgc(^>eBX@(s%I-4QaZ{jv4}F>4iI*OCSl4uUfK#(0O3sB~NtA3ucX9GK8h zAI68gnpwSDt0~cY0^7whg-9Z+Q6(Omvjnt@JGWHz=4%g|Iwyh!aQOuq^v9fAci9@X zs@5m`4fU2HpGNOlDl?hOct*uxjxN|14P{i8HkrE`d!-qrV!OC?Fn^EX{``Qy#Yboi z^e$CMy+-fNVA6$kglHfpTC5_p8O+}W@DNVnuAS3Y3ZjB&MB@_`2=z{}-Pr zt|37DJ$LS((whwWmLXZNS#9pr$|UuT4P|Bdl`@_{Ez;YDFuo|P>nS~qNltMjbB7_Q z4#)I>bxdS`Mu_O^mkB7a|8(P)*)txCdEicdT{I)-MQ+LX4erZqCWhPX~e)ZbSJqIRh?GpAlDmr8e`JL~(>Yt6QHceJ5a?HhG?H}wzNJe&I$ zqh6<{$?x`ise-}nI^jTPL@kyKpBpKAS7;Ph7G|fT?5O@k`{2>e&b7D)_9i^NG0bat zeX;;P;2Ien0Aoo4CxFn9V8;xDSH`EZ-d;HdA(rm;)~04xsEHG$_Kpqh{q)nLD|Jex zsB_b3J8E^p3lAl{0^#WFSbvi4I4}n2CK<`cOCdaLLBV^PcqB+kBZEK^0mV_NuikX5 zC|VSaTxSls-Hp!E(d|q9JBEip>FMm;I%Co38(R7vjC8w=J0g!Qug&%m#^;dvybogu zA@UEhG)Vy*8%^-^2!;3tGkB7K!8E+=hOb&>$nX85GjsdX^E3HK;}4Fmv^US?=o_a7 z_9wPElq!#N$b!7lWAUCqDEi*a+P*n~#$C~op%@Ib4iAQflJnt3RH`&ORT`@|aUswg z3kC)z01dzkQ4k;+0vnd8rCbR{F_sv`G*&>909e>8E8`iC@E? zcznFprIZoIhn+5Xw+lumEP<5@+~u$y5T%TL-Tg(x)RHOSJ z|IJH3(!^s1LoBWt{`Fwr@B6&Vqc+>$A%A5^nxTAk-1ni#~~UcCF5~*zNEN^MewTvC<8D!yI?cWO%xv0%k+z z!dZc_0?E1HwIrsvM9lmk>JmX*9taph+wgb_uo}>w7hEokWrAtWimqF)(>EC11H;L}-LSW=`I>#&JM#VU@w^PA48W*7Xkz{tTIfS0^WoWu?Wf(b4$#E)|>la!dF zR-K(bcICvN-|uVfj2>JX+8*uq1_t{5!QQ{eqTSmk$98+~3k=S-FCE@Clz7n_9}4*U z06&D*AgAj0V2gsE&u{@G3jt}db|6L*{`&@bQ+sTB?l6kZ@#B1#zfL3EC7krljvR^( z1blrxA%FiHliT-hLXER6S=CWKfB0wKeWQV)9$(W?AFN3f=L!Z;lftGj z2$EuAor32<{SZ?%+_Ppjjlge@4VZK@U;D?=vAt73%`KLn|J>4YEb+?J-m#;o{^j=e zmsuK4L!W~_(I#h=)L}F|gD}CC5msg7%|W0u^!fgg*(J5TScbUFYB~}C*xOoZ_zoNpYYpX4ZW4eRGIDpqL z9UpW|F=V|b?ExZ4Nw893ft&28+U*OQkAv`xwOKS8`;^VqS|1#zqEw&Qs(Vu1{lUV4 z<6A29N>Tf~L^_3Tt}QHgDDC`!uPQ%>-yy2g=ehGENj`obU;vFmOA$;nWXlhWP+%~I zglM@9$MPZ97+z|GBlvi|3Dr~Y2YNzgyIw3qQB*6`8XaosP}BZ>S*L5ObEBQYlM55M znt-ac+|$>;_}eYxy(_L>v7|k#E-PD+8y3~JnQc2%ON)oUYUP*(e91t4VS}X2s8dV3 zKoVd)fvlry07l5lB-CetjVrKX$r>qOWhkoV3_4)+ z4YdAixqo27Vi@c9E4rdxH?HoyswHTi^#rFK4NB8!Q?Spy`QYDmkkM|G%QWdqr9!Kd zOLQpTKH^c8@Kmlr%T}Iv|SQ{EOShV7+Zu7!1tg?W)u&}5IuEDJ< zlU8~=!F4D06Nd-z*~p8j_!I|0E7lI{V1h$O_7`9^F>aYUa4Q}oQ!`Rf&fx{@E4QzP zcJ*`Px$`{(3xyh~+oAJ%^>S~1=DyzHV{1dRjqatUg~V0uR#$h#>W)($_fVnws-?ZM z@vym~wye8%xL@jM2uI-+MY*`DCO$Xz*g|LL)S$H`;f+40%M&slBlG`2oDxk zQ_)X8*)y-w8)`czM%(|(Io=WS2Oly` zu&}GoPwFsmZ#+l$&7D5GFcli`iK5j8NubQy(k0i7#=4?Y&8=gTXD0r&@95&pre)91 zS6jv=nswqKuydy3iSyyEXe8VTc>qMOl)(6q&9^S^@Df1sEkFSjiX*H>V&j7=MyoZd z#1r*IgYI~A*X)G4;ddqS{je*hFFVrMH@5$`bJKG(fk>nCEvj&OOfJ(Nq3UXcVu3K{ z_;4v8oFNFc<{WV(CfHZ^L72pEu$)0_!4?K58^oqk*46cQ&gF6%^ zmB*us;y>)Fxp&(ZG(Y<4QxAUQ(W}2P*k^5atK^kRVVzA{qpTF#>y@rtm?2{;q{GnlBfk?My0FNr$?{eH$2o5jSl((UA?|w?4Lc|vDGKn0%$3b>FXH{db?;p z1j}P=FOfB5PIi-pqp`)vP8y*YsmXz0oE3ghqOFaJd;_7Wg|nyU_8;krjcV#UTC8hh zt<6&tXC|qBk-m9iqIvb_p5;w5i%0h%V|>c(HYI8!(XMcFv@bB3KSN?x!6IacCY?w`6y`5XvgWU4%c9>t7$m8y1M#8FeJ0+L@h{ndc<59I(u0nW@}Xc<(K%>Cje_bEHx}PMl-{XGjXVDK{GRZ_fWkMOjU?aKncXqIPRD;C_Q$wJ+R!>GQo{z zIMf=O83Iy&8<9IjYLQnr+t_cJe4);MV#h5~#S3d$Ii&^sYDv4|TQ+;>(~hieM@PIb zqPBT8T3?=J|AWn1k)TQH^9DM`zcE=XP=^=g^`+DQC@d_ffaBzKW=5_cz>N(sMN9qy zh=;N&2o{0NgBV!EX~X^l1Ttv)2l7W!kx$vwT0eL^J(}L@b@Z4=C#}}W8NI7@fM<@n zdwbpfI&?Z@%&v{A{o=y0K22Gv(i1RSbOJZ8L0;@GmRHwh=4MxPE2SA+wZ>Hn0*KgL z@Fw^Lpc{6@Hs~VO5CB6T-MkWwY%LBK2ld8?%H>j}hv5oBt<@}kq-(6JNhuO3wdRmP z<*pOzC8b3LnS#6`VYM6rIhZzpMBp8`*I>Vn9tls~3irf_Q{xn535l@Jb7?i z@79KJcImO)_R(;&N?K?r@W&7I{BUq-aj17+(YM7>Me*Njc6JQItKNC$9&cYCJyzl) z^fz=rWbA?!m%&&ru)P4U>srlLH>g{h^w)iFl3UM(uqy4QqQ4!R9z9c|b{OG_dj$W& zmGTO?lG~Uw5)8XJEqr76%+qth&~RjOWdVXT8hKd}oY^k|$2LEwxI|DOHQN=+@@iF} zZETB7>nOK3FInnO1=@!h_&%p@2Ke+iLzI>IbdD+xLT12`2S(wgdQ`MCL9l}b)Xj@S z9dlV+gRoA+&yojY;{$!wHCa8`jbp=_!NDy@C2@DV$~oA#DeUmb>s3~l*Z20&mgx># zgHR)OT7`|n`s&g$IO=25z~R%9aMwBKOmkDyj)A~nZS91o8zLBlJ^+{J09NojSWL2_ z`b%OM=-kXy_hLi1A!0jf_G%owFmEQ@HrqD6c{1wtSek4tUqd>$-&A83$+h8lFIb$I z2AMI8c#I89L7(GfvJ!~zma=9zAp@Pe5L>AU*MuF_s!F)h)9I~KXzf~yKP#NI&>fz$ zXub9NkEXl*c8|x=Tr8LS^>TN;u~Dh9x-3FLWqGu>Gh}GZD;Wh_7-*F016hObKGvtK zOeTQ|WG6Oy@ek>`FiXZc@S60^jdicKHUzxgvn|bIPGfg_H1SJ^PHQl!bg0hZ5Bfr0 zpW~g0eGA>2p01C3BSXDm&yCvse;o6K^eRWVY$X>^Vjp1pWL=7GtJ+URL+Yz#Gdf4_ZHxx?;=nvIT;-8)Cd zcX&L@J)YP=OL!35KEkw8c%$NeY)7-U0Cty?C`b3X!Y==w0Q|Ys*T3bh)t=5>zTpw? zj%e?4|E^uhwY(ep0E-;IVM(?xHVQhNno6s9%!l}*2Xwbc)li)$ZFlx=uM5|O+>qs# z&k-o<>jUyeRj?89jg6(HyA);39A#O6!EHyC@Yy9rOc-#0Qkv~6jm&9ZYF z6{Z$?qNCw@xyJ7e`1kyLeA~{Uk-fert~^%E%dd`&k46*!F(496GzN!L#;YOw4Okw6 zW+CPX=pB0FinZ)mCk~JVBKW>7V_~N|9;uir7uHr(Rd1;oa7G6=g?&D+2mH2x{}*FB z^@f9}t7VACYb>Z3L=KRaT47-7?ZSWHQdS_I)(Dee=Adr$%U)&Q|7Dz+3mlJ&yU!2m8C0y1G`` zG1CynFIYlJ>B_|7v6f}sD>{$?1ddHixUTHJ)&8!Pl4f4e>Ivy|DwWKv3x#y)jR^l3 zo_M@>Y_LP$ps%+y#=XWiqZ3Tq@^X{1I6tdcC@rh>>W5{tADRa8>;lXg#{Z(sOnP+d zjs&(!EO;qQ=tBQo&o+>sO^z!X2h4pQS9e(xzg{YmHQ~!#He01)t8k%+Ya%h#JkFNmo{TZUMQ<9lX6 zKxAU`*UDcP=T_=#kKc6WTW!tl*Y4SQtTirc+1J+I-sW<2*|uK!SB#>v!y5+rIbQqkBhp*VbFS1O47^rL5o86LSQ$f}2ql*l;nA|5cg8rc~ST zUN-D^0?ge&AK+^e`q&r%AYp5Eu`V+bQv(&89@fHmTHISWzsgf$VdS zJS;CQWxfg&x!zGs{n%(rDCXwM(y&Hpuu=oE{;m z@wYm#ya4!aC-e*Oeu0AFr32RJE`Tc|h_Ouwh@e%Lip$&gY??n(63FjsxnrLrpwkU! za<<&Fc`3TdVwwzfEZMAy|L|HZjXsad;-1|-JR_Eh>YE!MJOo=3#-A`kG*nMFymLYQtUNm zvx(uTd(2_8*{YS6=eUa$f@-&QbNr}mr-Yl{$8Fv`Y831rb_6yJ)i?5;GcCiPc)CMj zdzV;Xn%wFr%byKwI#wuv8wW}ShQ`{w3|GU6$nbvPtt|{}v|WbJdoUI*YnQ=QeY8qR z7QpEUbZ&B@XN6d1A+I;sI${c&96DKJkvlTAJkgDfGkc`J`90%MYc$f-r4P&Met>lq z9_(qbiKO`an~WI=WCjyjXX%uEgB469YMlbm(=!7jOPhzf%~EkgouSU)Q#Leugo>!w z0fvOn=MVVa8alXZbam#r+B2@zJqhBWMxqJCwq^ws_x3mAVqi zCv|VTh#x+MZ$bHGZLjb{A4~3f>Dz(JR!D zL#wykw0QSdnjCNq+@7`WEgqLI=yKPqIGN?;qCzUnQP^yXS2XVI;;4D^whQ+S{738X zqq9eD@9A+*-n}AsYRuFi`<{4HS7_a{(hC#$9dQ<7s ziIJgJE0&tOhc+*b3{Ba6-C~iqv0*O^>T>vkK5D1Orp=&?76W7qed^pbJi2TD2-+Ly z@%fYqL2zvJ_~;0k7vLMm5M+ej6y$U~$e1K4!!`hGjRR{JlSl>z6IKEY@bcY*OT_;O zIU;V;kSE^jZ}qu%@811*I4IF*+gtq)Cf;A&L36#Mxu*@)v_(C>&L}#NSi3g9vb-{A zmB?*Gx6nQ-wj&CXk#;bfQsWtTP;}qYP;AkCwsU-ROBgb2ZAV`n+PNH~iV`>7H?#ZP z@rkd5Cm5N32I#1R;a4_}K~7CE&c96o`*>t3DM1WxX7U6=>4qoC%?M1S}7!>}XD&kXIr!ncTx#XV*`+ z76euPu*9QPD<$fdD<0zWi>1|N*5X>5&C%ZSjiZRm;bw5T>BVk14In!6QW;-RQ=)K6 z@%dux&p!*efo%j0pafQ6*LB!C9Z@l7?rnh+*}_fY7#CYN6XCKtB7_r$ zHh+^PWEV=jz8V$UXBum23(2tIQ3aJF=+Q5zMnILJ&iACa!mI+`7hWKb!wAdf* z?lbrn2F?sDcuWE7gmu%VjJ&$KJPX{{y*V;86xnR$bG~D8I7~xY93%w&_Gfe@+Jp11 zl6sVWIkAk!49r`BAGXCtBD%7!ep~0bP+F%5Svo6<2c;FFW3M6Ase-&K&D(UI!FGjJ zSgX{T0|s&bEfvCFn?K?(V_Z$WgijAA^%Rre1bE(Hi_>xjGTG?RH*J;!nOr?T&_1RT z6$cF7aNMoY$ObI!?Uv54yTe~2X;+!>-?j&u!lNq#VW+xM3@_UEgj)PIk5z1xsoN}_ z3ju3HR?D}BBPN|!ED0Fq)Or2H-_Jx(fE^(O?*uYhkc5$PZ~_kQzQxx@VOpUt*W{ZN z^vyQl8S&s76Nf=hboGWi$Beq3k&!3#x{gRsS6A2ZnQc;GxU;jVR_d|LpvpbXy#pOx z4fT=RI_l*eP0QxUfi07pyk#YcU+pZb^jlnTUoDP-K+LMBF!S3~QQ9>x;5%&HX%u>i z3KbRR=_n2rCS{#zzen3SX;AM)xC#095T>B;{t2}k&Jl3&%}J(WI7d_jS!`g~(g;Qs zr|!D@Fzq-(E%gj$tWL{`&YiqpF*IZGhak`wE zs>CbQ+beUCS$_3o*a}XxCA0^VHDq)C0brIBnA7lR_`+0V8~qFArmniUm%1tzgL!3K z`j~nd>NMbN6R^7AZW3mNOzd_ih)X6SLi>*pQM6E46#!eHkMyA}e$h~SXJX2~*H;xwpt6)3}aP|dOMC2VX08WBZxYA9Nb3s;Hvea>0I2b364y;`l8VJgDlz$p@X3E|oVkiJ+GV0Nb!_<6pk$yr^~7;(yOQpp2e$?Ioz zeLYR)nrAiss$Z>D3-pTjjm@G0z9F(T^iHs~#2Q~~|Hg-WP2240UZe<(TR+IxpKa|K z-q%Uv1Me$73wSGmpQT0%IbM!a;IR&uD^TugAk%Ns38%-#d~i*^aA83hY!P0Y_>6ix zamQ#OeP+EJ=CL38fW3BnPcoaE=|db-6*3V+ySyN;pt(#A*WI-LZR@w6UP(M6@Adc2 z)M!e0l7@n^s=DjY2Z<}u{)^*X_<#mQXnzy*$;Ia;WFjt{ut1Vr3NDHJ&yH!7z6Yhv z&#vzI)vu_xFDj4{wI`k+^MU)UKSsx(9h~aGX9i&!#2$wTIv65P`SqhK<6}$Xc3ZrI zLKlBCzC1tZ*ZFCFBQnAdZF3=~m=8}V6vO}U?^*Qd#s5N|CT7sJsQt4T^>*xI9QftH zS===0L#R)|%pvv*cghH0PY{mSf%S!14M+&a7fFe^LRbJj_{Kuw#ZhHmyV)I!d5!IP z%2DLG_^MqZsjQKp{hxo1635YgV_@{~NYIG#693Sc#1fNH3T_;Jn=lRi9_R(M98fph zm`>6r31N`UWkRjr9UGH3`sE{yrjGcoiIpo&1JghKDO#H-l(kx>XZpOGcb`5UUU0zM za+ltRb-S1P3&ddX9sqt*9qwTOas$OCVooR~OT3W3jfEW&VM;7WN3Xlui@MS|4VwxQ zzsbm}lzEiyHc}u~73O8tXvc!PH?JoCj_Uk9Rq7gEex|?~R-wY;EY*kh=#UK#DM{$R zx+V`CJ}~LJ@SUGMhpxEwD`i?k6pIm7GK@>|BPff?&dABi&CTaRYWbu+BKw0`PhG9f4dVA*=-4M7^=;Yxiw>X8y#zGY=e}r}{5G2psSj z6~+IHpGB66D*3EUCN!)G$_xi7qm;F=R5$A}q_IY|D!3Ynq4G}xL~TViyU zWt547>fYg=2H9Y}-Cn=CwJy-^kfYmVXH`BiKeN51T&=CJcB{;JB4fR9bkP!wi9(*n zA>+hVxgyJ``#G{MAY&mX;xAY(nCQK7A?)3N^rvlkV2kTUPfRO2BI?x@C0!45S9gCgTb7xf;oX_3%BkAxOf^kV~}2+x}G z*uq^IuWt)LW&=%s)cfojaIj2-1%MyuyHl?Y9Qhw_92uadFWw3GzmnR2Q9(`PHr4RQ zUt!K*`!i?V;fNv5H6~_0K1E6=R#vMc?W*Y$qerTGs(KHW$f{%|gKftnl+e}RP`Y*G z;%{!Ah(VAKRWuKU{6N16px+*Vr2uDr!yATJN6`}}(Il*;!0t`iO0e4KtZxBB&-hRY zKFb8Do#L9hs#0M^p4sF;kE_*1aI(2>0G?6vhJ_BVGTN_EO<8TN-^$Bu%r{-IX4Q*I zB$Z}S#|YY@Fh-Si8eUf8ka*@sp-R>ui#2E^*IPp)nv(foWRop3>fMaS;XxlyOsXwTT#uB>m~bov?8vE#tn)@=t5 zqRGd9{@5*W|BeE+-}}9H&};Wyd)2vnQR%(xI$>P_a+~l!$Xt-S5-K}!VssSkhW|l5 zV3~p2!y19ULT^I-8mNygrsQ5ZW2az~9`CzaP?LUe{@|9e)vP#wOH*e@sG~Nb=re;g zbhzNworiAPGO@OKbZW)j&|G{J#0rKb4`}tP&^ORL52OeYFR6;qgCu!xG^Q%T`W}C; z9Z_-nMlEP=h5k6$mZE+GxXS^J27Ti9#KpA51V@FjWtSlm!U=rpH!s|C7Z^(Sd~Yo4 z)auf;T#9osk$38iYtZDqZ(=LyjWY*ty7@qO=c#LGI0cv15Y}B4z*AuTShR3C4KNU} z5P=$q3*uoPCf>bp?s~s}^x0=i?UBIf(Xg8u-u}<M;Dezd-63bI%<4Ez-LL^Vi?_of2c)q3FSLyz#=VJv**Jo8=vG zpK@)gG?v&ux#Nwm=_fZwE&Eo&-S?5P;4ZU|IazT25l3M-SVrRrIh?n_#;%PAjw>8- z%o6Y<9DHv*+(Uva)|^O#E-1`{^X%T@%5-m8p=OF#S6Nn|O_z?%;>^+;V8h!98tg!xctnZJn-ftuvg-|Z|9c&21N1)s+ z@U$G|NVKCTFa8oenE-l@U;Jq-Mp>|}LF5Wm2XY1cP#%_aG%FL)Lf-`s#ww95K)k=b zV9f3sGJ|xv&NSGWYr3E1#0 z)@}BTb)yhtn7XKWK7fAO z6C2I66r^bmYj=>6z|us!qkW;0>fW}iPqnw2#}$n&%ErYeEsv+02u+0oy<7JP)Ix!@ zq^va9Vp7&>&`A%!sVX#zYEQiAYjXEBl-dS&@AmpO&$-Ozeft%S#>(QB!V0^zc}Q+; zQ_N%9q|%Cj4_*Kqs<1sp&fhUHf6NBS!{KsRA#6#}yDeCS*@&7Z#(&X7q|qJjUfbby zi*423(!xAmQLtO5?T_3WnG)63n1ABW$}7VEKIXX@(1zczO5X~OZES=qQGcW zb7z61KsD?7l4YHU_~WU|YEV=~?DbJ((o~7Ba<_cR${LLuS61BMSzd7ftk_TU0^VSc z14n)VQgRNS?8*@x42wuyT5Nzr5+*iL=p%Gsrl23!?zwF=U~dmj!p$xA(Uy?FNg0*i z;YwAgNgtT=))zK;?1oRjt)rTwa}6!AO?rXW1ot1Qv$}KqCbdV#=ZZ}sPmOO;P;R$e zI7ZW&5n!4E-pRwK`@t$9dI8)W;<1pBvxUkSz3uSPn?}*D#L3y-ff*1&Y0F2CtWaq` z4gaaDD-H^Vg0pTPa~6TGRM=kRVFJLkiAe)CaacD7-<3%VcG?f+vf+b|jQ6)a{@7Qp zncbbMM*TQwVC*b3jB^UBY>L5^llxr2d+?P^}Jvy+Rfqem(%p(D3i@vmBOi_k^;j6|J zD5Jf-vl=ZYepUv*R3*NKs>+~04%i#8R|t1bGsOJn0Jqk3Bi{PV&2 z<#9@K@lr<|uMd6~g>#f{D}uN{6~q|?HWLSA7)QcEqce%mX5O6KKI3&xFE9Lf`r-^w z{>57$NZ|k0w-Vn^{DN8lD-z!yUk5y72EK;5C1XJ#_V7AG@CV0)zC0GR%EW@St%HND z+MWBNTY0uiX-m@ne;*B!dNgptG@_d9AAmis=$FNV@V#aqQ`kPhe!d0sA=YPr5_nx3 ztSLe>aLDzAkyWufq#R#4-;O%WP$|bTO;h-HQ=mL#3YDe&xlAe`u#hQ*pTl?_>EQAT-iF4QrBs9 zW|eL{t3S7`VL;!z%eXq|8c^4Gms|WZUw_tCh&4RaU#H8@+P9PT@^F84FJ?gj;LfcC}4t%W3t7Iy*z& z)*SeY+U~Ax4KGZFV_l~@BVM<)!3zJmz4Tci&>C=O^#^G@3^|-6#9v z(R{*1N8PAf;vI>R7*+m-xEq3iB97nCah|id36RcS2(|(3VE^I<7z3C}rTW%V7@KWdmsp*Z$Ii zpa!cSu&qGs1GY2ZE5y9I`a{`u83iXaRc60(vZmxzrPSq?Ii>Ob@bVqgluWt;f73V8ttqpLqbo zf@+;w9Pt;)6&~aNE&4=#u(_vqZp2n^H~-&5PK^F+1YG3M(O?MAW36i}!|IdlY&32i z{(y+~L>Ik_L2*X6lKqSK=}ij+Z})r*Z&rPPcS@L-dvF{bpD-o}r1c);mlG=1a%u}T zO}pB+9xWHX(O1&jwXp5*QscPL8a}<9UAW0DUFOZp@pveB&*>BALJi`|E?;NYR(b&u zyuqGE{Rm(Nc?Avx7L;HsK&<%rE$!&mW2j>yF-%=K_e?xdLIuJ3$NGclvge^q9f?c9 z>Vm|_ktw)C0-ow5f}s#kJ>!P4G1RA!@l-ltu1TYystO8fc?Ct%vBV`X8ovI+vixc% z9AYsPHlc!?(mY;$HXp8vdg?}Ij6E<0_%`6L0SO^fHj*INkw9DaB;G;|%ZW>{e+AuK zhqfl(N<`5vfDO~fAJCu3d?1n}gTN82JRr?W@xa7mo|nNvBy{FBf2_v`w;L3U9-FF| zI;M+HIyb+0`%u6;QfJarl@}8;Cr-=+#?9pj?qCES`iLWhbpaZeaj{>nrHI56*x+BT zg3W0p>w`t-Eb+&#AUuNA?}w z)pn|9?@GmY_HOqdJa_7va|iv~_kIVACyZ<1rSqKYVO)^=w9`gkf1n`FBomNKvNJ>- zuq{B{r}s5f*^S}8`7HHSz8k)|F-E{QEwuJrjoP2?h?j@!M!Jo*Up%-TCOB>!pK>1^ zGr)}`p8~H9!q^S43kYW;=-al}Whv~6VZ^2wT}l5D4notGE+C&M4V;9DgTUPWE<=@Q zCeqzI_Nv^oFuuFl=HH`EyOG< zv}_Y!D|Qu1I6377$yib1Pe#+p2Rg$t(P7sGmF}wZVXslQl3faBHKtMQ5B&@9s=+c$ zMx+u*FMPs{u~~^8Pwrm9{^+{liq1MmU5X-|P*N8wQyV1RqsrKs@%25d7x4zy$7CbR zrEVIZGEbbfcLWDC#XmUJeRi!abt5Z;H@ZGe?q*RC8~TW90=VecpmD%6d65ZgOetjR z3u_lo+ZtzUcP#I0ZJAL=54HE++JOF4pc6~%Z9fjTY>JDo@1MTn`kQ<1KhZZcc#pSf zcDmo|np($!7{;RCq+TT%N7qe_4>_YQz+s*IJ0#0+^v6jd-tRhypi>|2aftGFt1{6rDekZhqG)`AZ~uZ zY&MzIvUD-_kn3Kimscxe93RS4=9n*ArY&BdKtJfVjk za=+vaD@_9K0N>phL-0^Bw-EV9cWi;<%+i9Kf=$Ll`#joZ?akM;Y_)|2daXS1BrX3h zeFXH2W3=#B68{C!PfV(m9dq!@B!F(%%(Orl_;>p59mdo>a#^omo6$SaWKbP$CE?)Q zxhq>!_QrSIeWT*Jy7`lzh_7bi!gw#F8gK!7cl2=xFf39dg^bOF?g});Y)sVf%BhKC z6ff*;8qu@C!}5`>Tl(<3UZ7_=UC^Hj`U7``k>ZS&6~g|=7hR7sSoV+tSpb+bK z+Xr<&3x`dEIK>DyX%kn*scqN1`|ibWQST&fVA@mnb12e24Glwkhy&8FCChJta_B$p zrOUrl??Cxl+R7#6#&)E9IPDC~iu6b0WgQ-rkKhe+DvEc{;}=g;o$tO&bzYPsoL+v} z*fdOV`h&$6^eqQiaL;5}Q_2BG>J9cwN;z8}VqD(K73*8b9N>BC+UJI*!eyMfMl5v?5z8bXEfsK7oWD_&a(ws5ObjCT-9v z){DviRJAs!Pz1FfepoIRmotBoF`>GO0$+mA0PsxOHxe&m`hu~pW$7I$V2g=|EPcIj zCI0zG(C==(*^D4Hj)6%4^*Hbsj)aE<54j!zUU;2+-uRsd_hTCEkGSw>x-F$bXQ3_F z$6(8lC>u<`g3ivJoeO&hywp1_b8{^XUN0CsWUTf25LpN90a_JI4kKG#m8?#1mG&Md zkJ#SEGQbvWIK!5=k*&hXV_GqDy&mdjV-J=`YU8LUkF>yNAKq)8pKr!3RX(2z;Nj%W zpP7gDi4Orv_z$lw;OkC8D?Mq)39aZYYg5@X%C>Ug3q5;g69JB zH^O3x^{5yBDW-AzT{MP1#khqy4BvOV~C16^Yn7#R){JevX+h_gR2k{BLGVHBp`xhRMKe@t1E z<6-$d3%#=PdqaEdKxHE%T+McVJn@~xcSw8d#UH1@OUv%fM0P_z^!P+p(i+49?Wt`S zPoq~81}wD`Hw+;j;?d(LWi%qPd5-Oul*_sBcfyref`c5w5}a*Eo@GP?MV4cYDY$kUadQGku zSr=9g!xt8>DfKZ{Qp>TVqUAPxVe5n3#`0$i!Q<)|%4z&=Wy>*slknhKvi;EVlSpi! zEBM0VB`GIqtYT~q13x6&k?&9+LqVh^Q-gsoRZlFg>j?q}hC4ycZ^~4YU`v>ux9=i!fYTfndqq|@W zxwYru!5;Kvay_Ugz&=udWn?Az0g1%WBh#meHp?OKL0|o4WV%F8;tmt7=tO(mYE-gz_e`kV3dADv%^ z@yQK+!e$q@eI%~c$j3ydzgG5PCG|Nout$%Ii`{EAIN2K zdk0xRpko;IZfveG^?yw0W0;cCUpAC8_A~d~I^R=tKV*$yHve3&&&+$Cj0@b)^nb?& zoC9^Uv)oPz zV@XD*N{q%7E?@66mB*p)jc}5T54;S?40_{wmoL*jGHeY^88|oc^!JkGU(VC;edCzS z89A1pVG$|eI&xmdxMA6N9XHwyboc!v-D#6_oymO;lnD#tM!tD&LpjR_&tnQ@=7jsf zd~h{cPrwsX&hpb7@PUF$S^%G{>pvDQEJNk+o#Iu9{Cp{R zmvaH{csz95dV6NPb-pK~(reD}J=W87*O|TY@^(D9xS7N_8AdnS zlRS=oU72KXXqG}_*k%V7fjmoL3=%A{`+0SY!4J)2Z)3axkNx`cc06+Yz=-~s*c7AQ ziCx^o;%TF$X*KgP1VCbCYyI}%n)V)?AI^pEBo&WO^xJ!E91E?oajXq};T#{h(V_mI&$!T%6Pc1@ zRlrykSO?)vZk*f+cg+wx3U*syaGAv_3swpo7{Fs zdxN9pfq(88F>h*Xv%3V*^*(O~%?Wlg#I7$8LiPKC7Rl3bu#pL zGj#^&3R^FjpFh8Z-;x5*;Z8BqKa=v0%~s<3(W7|~dWEqU*Ah3=_9B|P%%lWZlVe=X zjsZ0Ni?nw)j$vaAeY`b-ePCKi*Px4xWq%ZHriVCr`3M{O|8JUS&`jF9Uns{E_v5s8 z2~T}?`S|ea05LM~-0&n>#{<2>+U1)QM`{6RUM!C%tIm-YG-85gCIaWApu)Xj7` z4Nq1|KTP>Qp+1IJ&caK0Y!Tf(IQ08ZZH^GJ_UOZ`;|OE zCKGQbSwi!XnTQp*kb37iVOGh$;g zq@QA#rqUhVA7J?}8|V$&q3k4ST89Hq=x4;BWe6R#=ejwU%0rk2jCjqmK+>g*h0AYc z*7Rle`^GuoGd8p{%2N1ejB!fSHu_^KVm9`TX8>asuwxRsR%CIL`#pVh{f%@D-x(N5 zIpB8(ZHx6K%L#w5c%rUJOZLOiHE=SFTe4oCp(JCh#6mG2#mNGMfVO;Zf$+WkENNi!}i{9p}!91~r0y+kb0kni? z*}mY+BWUp)1hL*NY*);hqBj})M-TQ-W)^s}3~hLs@>^-UDD7qT`^K?&#ju4>r*1;_-*I;O zFw!$D0?8p%i_D;Zs0Q0NDoI zwXKf_U(eH++qFI~3=eMi6ATgjyd3vPqmzC1H9dejPL9@y6XC>!b);S&oyJY%qM zSu4`ao*;XrG!(Ffhs@^Mh6Cp6GM)^5B6<0&qtW75s{9I6RGe3`p)YJbCp&>RgfPT7 zix6x(En3~#P-`|1g>8XQ6(!@9aiO;ize?%1G&;_{+~qIH%gxWhxidzDkdhOI{og`t zKeKzl6tfpBNL{DbE2R|`((jNz>*+N^Rk)~<;z}zkrIn@01!U=j^8zOfbngSI;&K-e zj6l;H=f^4KCs1j!+?rDU00Mk5^;65gkIQLU!N~)>*5aHW#sz26r;;Hp#_mNgH<^vi zv9*r&L&;x0b1lWK*Prj)cTE(fum28RU)FbO5;@lJbUcqfX=@8^b!V0v z^8v9mgc+#%561?YmP;!0y$u?lU)R65($hD|tH_PW4AE>siL6)^k7vKN`&2x>=216y zM&ne^p`F_fw2d9Gnxg|kjj%K~BZI-Qlv*P)BarqM$bjY~9$1+0)mAuCSO{08Fnb4l z_D(e)q^1(f67KX(R~5@j1ldu8ERtKno9ydZS?t&OeVPVuer3sW)4;Jm#8E~@ZYhjD z5H(v5jI|xuw)0RA6_0i{t37M+_^I7*Wv9R-&uU@t1duW1Pht6(6~bO~s+{ILP2_Zl zuFqMwYv}q-|E4~(4ypC=`Y>{xZp8)r<_IgdIZxB_54YI3jtqQHp!bq;wi#zkrIdr5 zqwj9*=&@4pKBF$wW3vr+odjE!<~#H{@HG4lj!=QMQ7l4R=05#24yWedNj#TW zK#lC2(Cc{bDQg5{vZxgdr_0*&5I!?x;@pNDi6`QpehTdu63?MqP$P{KXpeaiw}-Wb z#;mQwj4y)r000l}-g^nPLkGAi?t;N7dXJ_72fT^zQFJSF7QY+E|~fUnf~4)^IS;6 z&5lFkc5|{kwg1U~+dtSFEIf4ojQs+Mh)nq!Q%>V|c>{hi{K*(u78!+JJFx$QG;Q)E zXlJ$i;FF_sf5qJu&geQP^pA{GT{FcS>$pyHOXz9fl(b6CO zkhtMRw*E4@3+jU%k(xjCW7loBxo!mm<0jV~chLD$%Mf3Elh_*q{AePai-x3Nw5mFJ zlKqc*ll={fSRDo!2Y;B26@X{ToGH4ZX}$&Bka+&!{d>^Muj75**I_gE@ZqTs>3M*0 zkOyr+z9EQzWrDo-z^wq#8mGol&vfsL#tuUI#0@R;P3Ywhal;#9uj5T!W?q*P(Ef*b zY#floQ3hyDthX9OJp+R$mQVl&r!E^CuMciZLB0z_%f6fVGtkRE8Ya@`OE^1D0PzzX zFN9v@Kf?28(nx#+=J*+`0n8QeS7R+pjvImA zg`SP69Z@GzCr;B6`i!BaTL=vwVDU%#g!#i`)?^0}hgETcof;W8%(;7gB^cZ>@IYIv z=kcCA2r^g!oJ4>=+t8Rgv5rbsF0t_Zg}`%&!QCYS58zG)h9b5upjYC};g}ryEOnOM z8!(yVnIjCZ?uLF@9zT?JRr34I3?A^fnAiV8c%2y^_yY0~Fg>ty!byP4oMd5Rz;6mW zDcF}&Kw-~-y)8J@B!EE!zE|KaRA;G;T@|KGkR=_Dl7r4u03PSOc= zoytiFgoFxRfH-!;a&)04{Ot#CG^Ow&U2CxYyt~?r}x$ z{@};Ejto3@XxI#qTc%%8_6}rnl?Ur_rJMyv*mWkSd zMs0ydRGKeh!hMUFhsk%PecH`uyLCVC<8kv2Cj&`0vYnhFLgl7I(wlkaf3uccyktp- zakl8_`4IVdt2=1lM*OY1ykiNzc~7tV6#=U)ALHlo=>oDf%*k_5nJ`|sp-MMp`1n+f zS6DaMb^ikM(AfqP%@VQykgV$7W9~RI^0%I^!}!oR#(dzppnb{5ptXv4y1`prOE1h| zk&ya~QxwQmDqh3$=#_6U-HIyle9x=-9_06`u2~=^p07*(=4WqIy9k_Dqv~Zu(V4jD zi)0^yGH(y(htq`AIf)~ldKQL_pApqlDxR;ZVB&A+m3QUUFnMv8NS5l=&&N<-RFfw~ z3FUc7kf-c>#sSDewst+vFT0~J39Of?G2XadeGe%ivnsEDgBQJMUbao#Xtle*dX5wt zM(K9cSxE_RF!%mzaJtLmaphD*&iQrn;N;}N;twNUI5)x5;VI7cOdtR}hiY3ozvkpu zCDo}oX-haHEj?#az@q4s9BaO87|zO>h037Rk-0clkaL?nH>d0>oCi+y$t7TN&pa`f zO!3|YxebqpPT>tJV^ZLzmj`$d*=P|?D>Rpdqc?3_U6=qA7NArU92xZdq zGBc3}^b`vbXJaAzKtNB{Nxy)3@@Rp~wpJZN)Fh58>U<3F8=I2M@lr|BE<(=(Mq^c@ zPx#fn>su|42$l#M2Bdr9{G2*#w64Y@7Lf9CrScx!cK6-eE@$2O?tl4yrR!JB7hci# zu%vdrh0)h4`^AZv@V1nv{~EDy%}TDpl{q>>K6+JZva@g1ZwZh*?}W_(<;e-G&3Q zCs9UvL^rs`hJXsgk&LMddO`H&x-CPt;D7aDo)h}Je*FBliq^J@w)64X)+#^kzk{u< zy%X&IL3ZKVBwVqkhL@`f6k=JYXjfVX1TlXJJ5DQX2MNRJBR(aMAlFaffE{5cYCpHg zK4u-QwGsP!?{l__zC5dnHs?r*f*INjLYU+ZJ7HTLLN4sIt@zU7ej;$}R{Dhi{qWPU zXdl@d@kt${_vu)>HmsAfS6h70&}=`Sq1~}^X02Z!*u#5glm`z~;h}A(ALng0-wHnf z`SN`8P1_mBFq+o37%1V2wKI6yQCzI{G|jg*&+C2S(KTO`ho4FO41KdO`cAh0x#D7L zZmL`IlNKm&gQXxXMj-FH?c}4#3-GcXetdJj`EuX9?pC~TDle>FG9-rjVWlpd_GYeh zCQe+ec8lk27I~JgtW%EV^M%Vg=m_&y{ZZD7ZXwXT@(IZczT_~Eo5?goWBuT0SC{!n zSC<&e;aZz{1U=~p$s>49h55x9mV8D7$86+B9FF~BNDxkbCtAX9vcuVjGKAw0IgbUN zs_$#IayM&_2H+>8@6}t`w@SJ`F6A}4Ny=V1}6OtvJP8C@F(Q2p%JDwa9H{i4_R2K=TahvR9IDumx$@noPJ&LqJhc;2E`}E`!;#TrIk#qnsLUyP3v#+iKCtCd=n;4*p{4`S$O5N()_lO1?Md7 zKIg`DCbkyC_@&rA3g_0W!csx9jHmYM%V1#`2Wa_?ElVlR zI=e$0^}Rhe=u6Dyy$-bLNPT)T^gLELUAhtKkRvte%{sxu9>b$A>2-z;B)c96KV%jr zE77E#UKMzdsDTq}plL1-Kea|g%`M?nt(ZHY1EOp6a}teY?R6GS(hXAp3>SwWz7yrN`|Qqs=*V zPS4}v(@~#p-)uffaaR{PX3MAPpaEa^3db;WwMTI3QrexO?R6r_D=UYs*eWR1d6D~4V?tggX3yyd$m#Me!p+R=3_ z!;jFLk{EsTiO?UFLD&$yjSS1DJ*4g1eOtH6eWbtQC*PT&Wn!?FjDeGuB`Nu^f!ny) zI0D}G?Q-+zOe*wOY(OcwCvuGbhSKx)K-{ck!2Xe>B&n)>Bt=hLBdKA>C(v$0kJhr} zo(InThRTpXI66j#xlh4_^DK<}|9xh(mJZZ{spRc}i+D1Kf+S+>a4E?yb zj?T2m`dj6^BQBNV4Vmq+Pa4Z8^QA+aKIIXkZ=Nmp{ z(&j%;-cpAfKjsn<3Uv|)vZ?E*?+hyUnoJz+uG$ADox6~zPXp=edpb0vB4@`x5MHIT$VhL8#;q@PbYQbJ|I z3L^@_-K*6KCYmPlzv}9QI9-Y!-7Q#6!aNqB8AgZhHzVy@U=@WcTKi)!GPr3GPDt7e z?E#>DFt;M5Adjc;zjTwscfqDjQ2do511~rne-5Fg#aH2TCVudCJ3I;<$L9Zq2OkO< zIfQmDu(-M@!oOhCrVD(Io1Vk5{GJ_rq($jP(M_RDqEscrqfm)GE{dFI{>zd<$Dt&8 z|5xUrK%fp)vb&_i#gveus?6t`KEG~aort01z#Z%KJw1ijZotLvKs#78giK?>n_tyQ zG(ez5^fn&~&!6t|l~sY9h@p}jurb+#MChQXbYan;yD(gmx2$LYgOPbcNxURUpdxz| z31#=HE;0uPCRfx5G=bwC$F`8lyd*2rvt2)KRfb~-&e0Rat(cpFBn{QrfJJ7Ju?H4# zs)v_1Z${dlL6qykyb`U`tBirH4lcv((6^h999Y2V9jMG8^JDH(-BuaS`9ayEyLKNgKw5p|?G7u5p>HdqdAhmEsT=S?m+P2$w4bIV@0lXHo&zeTq+%=)31|-7CeP ztIQi72(2TkLi50hbZ=0Np;9Mvwg1C6QS^N{j{@YSK;_*@k+SYneC9vq%;Cycn!~Ha z67Z1r!*!45+#VFl2hw{C?Gi&}rOhPqIsFaAr(7Q7L#=ck?{}H+b89oMi5*L2pVS_p zPc2>mcPlH6B>h|HuWIv8x;_cPPekEdE2Kz6+GrFON6a4@$BsoTgJP5cq^-NVtGoLX zsW}v(VoshCg=f8M)2TG?n?I|ho3>$Vmu}aI^R?#c-v$ zT~3uk<@$5F&bj{iXHs!)L4_tov!0D zZ^Qzk64Z&3MOq(6M9#Eohw6ZL-E~*jrI%i6+2PXjy3VWeb@_a@@{}DQRA? zD4=FzPw3`m{315?aU%P8*Y@q(&4;qev+#dPTwIxGO)X8`x4K6Mo zJZRXk(bT4vF4;De9%K*UIL=+`@>)(pDMIy?pdO^pi-T>^nNQsIV*i@t#oRXs^UXa- zf#IV?dE_*EjMGlE`plJ_hvFLLF9T%@umlDlpG12LIao>8AK}83r9!lFUX90m;u=o0 zu`;}@7gG@U_*`q>U{9|Sl#GKVvDRw9m;L9<Ksjzkn@V^%FQGDOII)sK z88-AsdR0xA^@iwBv8{YGpPq>X(eW{4CtnLqgu*t$Sur|OaiVS6Ulxf#ydp$3R7)iwZ&N4p`38@p) zDZnZP?KKowdshgaL}Txw0ZW8@A^O@SRk;r?vSV^g`%IC_7HMvx8@=ls zG)Q013nV*yx5~AJvys?+tECC92Pw3~K~AA1eLJm5fUBJM&@?Hy@(s7mE4hH^`&W#c z?Db9_x5DQwEb#ig1%+PU1LIdTHLV!07xf&Y2rc-@yipNFTh5PoaRv??)<-TN_=Bep z(t44k-E&MYBHF=EJMA3&!j4j<;=~xs%M`&Yi+GvlvoWh(Lx#9kk1^ZCk^K7l{NSg4 zeD}oS(=swnE1tO9H+fjmWZ&eXVUvAQcS`;u;=zkaM4h~HFJ^(!T6|{F@5S?n#_ii1 z#oj4IKa}Yd9woq2j#s2J2gc4yEpWD84g$8S^&v%xz#wuDkLz_9;e#~|m*j9jVFyxeyd5Bl6PhZb5%POf3y?D?F6l#Ao7Gaq{nx{Uo zHxr+Dg?QlYB=zYFT4!$_&=rkTv`QN^M;fzima|8!U_-gq`t*q-mio*#n`6DN0F`wPr)aC}WrG2e!+XCAWofaSNpgYvba~2kfF*hDk>G1+4H3 z^vNms6m3EA!rK)376Bu)exPyNX0G}~^IA5^71pQEY_k-O7ex02`@W4)sO{u|4|d4d zKm&&ApkY2>ppkfWY}BIx1A0^pwCq$2^ogg>HCM5%CYzt}=iY*cgU0&s!(p~c{IJ8v z#)@G}8m*VYfq=2%T&B3v#?SoP;%9#C6Y1xQy==FiiDdpgvI+QJ|*M?oWc7J*pe?;bmqL`Gse?PbHt9Dxwt%&Q)m7fRn3v;s7GY;okO2Jn# zVarYFLkP>3ov>xmsrZd(Jkx4IvyCO$Jwi%w;jl*0$~@Ps5!VD;R7&$0`FJwyVEfXU zB+Q>QYqk{N2fGf)R#zi8hb{Ln^|O#odx=AGrWuvgh9fRAOgiOs!)#m32$Rn)mui<# z--~r>Truz}Q+HZR=QjUK$}m5;(0n!6ETTBb#(d02w;Dnkg<^$naSXm5Q7Eq?8J_k_ zFKz$3e*C-d%q!L08|#PIMSa?eT{!;*GSmcqM}7jVQy|(<`22hDE@^=^qZI+ebViPd!1Gv^#J0B3q~v>^L$W=}k8$ zwExIsPH>NbA21vQ`_6giQQOFW%{F_Nv3dUxeV~69Ao5GIY%?Sn2{6GCn^ldC=dv{- z+_6khGCCJ8H>}|ZCuj`J&T21=^@)WsO^8GtXr+B2{82x<9R@aS0zcSe0DJYskuYvn zkj3#Q-^U{#zz&;N@AwrmoudG{$k`M@gABHEaD*#y_L>dzR$i1)(Ya@C%eM8czJlSC z#ukj6H?kA^s~)y`b!YADI(I^RVdJ8vAAekUS!aGm?SxIO>-U|$VCL+T)lJ*l z=a#olX>k^eoix0_*SdaNOX0jFU9}gjoVS67an%PDU+j@_)hL@vA50r@oC;H$s+N`g za$PjPr4cz=PQi7x%o{4#CW)^DuPy|#m3w|MJk6)xvj(@}4%oTtP~Q{spTF|+mNHL>}UA^B$aY*~MK`7tfvQDXc55oU_QAnO&AkQzBl+viPYk zY8}R^W+f`VsR>xlgzLMgzsiX#dfpVnPE|Rp4dE+Xq)X)M#uR}M-^=zQR&>HjMrYKa z;tetP6crG&Pg(h(e{gBT`sPRHr?9Pf3YP7o8XGHZN(<*%KXt&wZ>9~X3FhfM+bRRTQP!Qb z$#SGw-iUP$?+7R9$)e|#^hYLF467iMoHu3aFSpHX+UT1wHrv;-dfdp`n)agFaUx^f z+RAJ;>87REZrZwk-nr+@Gh1|5b=T>OyQ(+Z^^Nu|;Eg$l>>6yms9^BjZEEEvL%eUV zVwizGFJ{B2uIR_MEj{B6h~ruTn5W@>vaKbos%~#n>B51OU`wR{$lGd;D_5a)?03hYiN(b)mbD9 z@rc>|urohjB=l1-v+BqFh4`h=8-wb)wWZb2{u1R7p1=HM(RDd3Yp2axwqdf><;zA5 z_l#_>HBFH$l8%7U=j>bk;W?gYV zTpOo3#(y&-B4=n;RgkltH^$RGcn5CjsHbO?3+}~zN=7+#lKhOQekE8_=td72>?pEJ zV8s$Hwj~4CH}U#tVC<&e5^B43USY(YLfJxxU;fPeydQOo*}?V|Yx$&BJkC?0Q^-Af z=Iq7Z{$L|FE<4^iAZGmVn|v3pUbsEQd{3;^)1sXTgPmE4#S{1K+M&yLGg@hQFe8Fo10)_MLlvcFmU3(6hr!+5BdAr(%A;9C-YkW|Hv9b0xn6;9t* zebh2wV}f%>cqtCg?L+CVZbU@)_9F29K~dV>7c-{ozmoNigPjEkxoZ1TezpEmW1~5( zH{mDDSNbL_$7kAi0bSurQ(lyVOQn811dC%%3s(2h2zs|D)o*-1ycrB}Z)0H2MtdlQ zF$-i{2&dH+x($xDc;0FYf|D$CqRy4nM}yS9(~pw$8~d)i@~IVw35KGMG#+zu7apeg zvNd}fUZWCoU)epp{py#mZXf=OzkA0ny>RJRvG)>R?#8y|mtVfTZ9|^#lK5HmZ3`E+ z)z1v2i!~N{{|^y{T$i9xpPe@kiXy5P-Ano-tLRP_J^U6V$fgAb??SpvRGmeMJ9xZ( zq8}n+STBCo+zoWm9!pev)cdbib8v#wocjy^6_|75`%pP>cga=D?ux@iC#kWV4%Txl zC7$g^kXL%kq3HfjzZ9#4XpdZ)LDZhAO~jDK#=rD#7EBwu`)(PQ-M?4=9Wq&iM*&Vc z@szm#_Br4Dus4rOFIf#+>yL%1$CLUmxE=^|$YlF(D^c7(IlSB3M;!xw2t3ecNCZIs zOx*3iO0^lm(Pm-+w;8?(yeI>;T@s z|3c~hFX&(&DjtX#e$8uv_Jz&hK2TtVo*P%+y>Q$ZuXoJ2g}#cy{7PSCeqqI}aDjg_ z- z7p-sFS8)2~_fBKuJHZ-+@uLP*T9*5SI@QfVtEg5croL(!SRX>Ynd?(LxsDI7>wWhH zIg13IT#H5hRalNOO1DDN4eke7OYt&UrF^(jM;^V>HQ^><{#xzWbWUw-yft7*K8tTa zx3HJv9Pg05Q2YuTg|{a=p;Sk(P0U5s&KsRwa`zW^mt>EgxBaf|B2T2Zp5`mdF;8s0 z>#nWBnN#LFt=0Tw`nGMo=wex4#%iE1>46K=&x?97jO-)kCrnm2iL7~o$%=F$%X$gO zN;?s>=71d$P$#X>)E}$rcn$lLeu?NKLis^f=^KbHe8VnnFYhDc&}#@B*@@vzqGISU zY=|7RW6f&-kVo=|R4fl33B_hXKRVhMCI)C?op>AD9QqU1qI2;!mKgK;>*k{`<5;)( zT%Ev;6k1ysZn4eC!OmW)%884^Gw@azZgAuTqg_(11E*acuDck2>dwO-=Om|*)A8Ke zx{i)#HrAQX<>m^JmuIhEA<|XS+T;T5SV+AKV{jiY(GioUy=vX>Wjz&=9&o>R5-skB z=xLX@jP+543z-EQYgZ$hZ|8gZ$JmzHd{Od(}(w^LcX_(V~+ItNqt z3rwcrr)BriFY8x0_xtX5pynCg=20y zn%^cD+QAEkHPXA$PMPXcG#v}>jjNvbfof#S1(7I1n12409dLaA+EDvK>{oKIDg~47 zZF@rnpYpKQ!*Ft#!?;>3*2o`1ZSYp#tz><^TdC4N+)5@HYKdu!7pJimtTNwcF^9@e zxp!ulrMEqf#Iyr_-J1X6WU^dJ!s3qnA;d2G5GBkygR+RB+=}nZPqmLncB1ss+g7lg z4UfY&@5mS9^dCl38{! zsV|X(@~U?2-Pa&54Jp?8Hcm6b0iuC1z{np$`&>Y0t8C30(&zeWRhC2i6K(2(2du&R zh^w~HjoF&Bwj6s?b+ojFUtE~PrSqb@!@!IRVmL8r;HCDw#`~gXMY^jT>BGzN=T2&z z>=Uz$aWgWvGtTrwoCwY3@ZNq9D_aKE(*6_m7zUUd#qo$4Nh&zy$STMC? zX0+(MDr#8PpuBbaB1>};GvWtET5Zbxkj~K5!QQN%j#P27%k$bIzqo0QP~;^z3WPbT zu}Pf44FMm3h6y#GIU;%vy9o;Gsg;Ft0?M7qF)MAc&!>Dvz}7G0;GxvZZRL?x6Qmr;*new$NtqEfa&k_Q>D01uF3oSp=+p+8k3g8SA?cp$wa>8oc zkp36uPXg_!WGvO%5r2d!q)#F1e$K)4FY59>9gAoUSYwF9Nr98=VV)&acB{=T@8Gn4 z;JuBIQJg%BT)+r;7je1GYbfKFW4X=9#5F%}un;O3o6|mz?5MU`O@ARJ_ge9s6{Fa7 zK!Z0a=K=1bGG;WlDKSIh%2#lVoHP36k1nYf zkpQL)9>uSe0fq#ar4Yc<0oxRGAni#VHnPo`!YrRAP84jyaKsX3WKF|DEM26t7T8+) z6V?{T!EajjY;`Nl)C#S6Ti-Hp$AcW(8|9?=6oTA`^GMV-a(t$cE4<~_U{NGE-Z?PJ zzz~D*R(JEv*+_<|LO0H z9#!t=j_F~T>znt_p4F3mr@!-hRN0?9ve%1uI#$$atw}aH9r4Gw891L--RtZgtabU} z;He-Sn_Coicu(4?Xbm3OQ77s6(2ixJr1LmLLpTeHC9PVQ#Yov+xF7|}cIo(Dns}gb zm||*P+e;oHq|-*$x=t*!-V+kN77JRQSBxBi;J#DQ25BJ*VV`e(CbW}K9Lk;KdOob3q95+ zxSN=d1slwK%yzO*`uPaxXE3do=aq{JoSqQwave)%St47cR10U8Fd_;{Mh$u5r?tZK zbaGK9a(lGVZ{`b653ca}qH=RSFp;zNleF{*Uu0g+2cpEh@{?@b?vj2$G>iCNd1iBR zR;K!}V3bFO2>tsN<}hc-oRj z#~Dh%)g6BwvvgT6{TS#J#@r+EHQfDI@bek}Ek)xixRgMUzH&YZ?p{zr?DciXV$NB89tXw}bKCX6J3J}Hk@ zuws|#^at&^8})bu8tc%&VeE&Nr=+?8W)O3CC3j$`LE6M#10?cDSzHh^bha8t9RmJ zes|zb9^`gtbVJUG*>S*+NRm7fhw>8V@)G)8iu&0hJoOiN?R(N1MSep5o4?e>uqq~^)S1n-fr(*pNEXy&{eXQr|coj0^q;x&u@#m(Ds-d{u;MYY`4IZ zzqN7>2K1Mu>WDKmX#KE06Fi<6Tw12%#b4U1x-2ZEO{iAQy}dJ*S$*qy@OHp124M~w zh&+4ixj!kSX^L^D62`L7YwT+1TPB0{$nlml>7Q-24}D;PJvVKrona=@UW6+d_lxnw zq_oey*xQVOSHn3WA*ZHr9$w3PMByl`QhIPPn@)s_t7OCGXGxEe@`qmOgt`XhyK3_D z2gfIqCo@aJnxQv;te5hJkexqn6v(9!NJOj0@~BFB+LK}I|I<6|P&oha3`AD_DPKi0 z?S=N?U680ut(sZP6=UT{V?rJ$)6ccH;!C!d%9t0wBSmeO)0Zt%nhHK^&#yvVZEwSS zf-gjca2RTPE=u{EQ}b|#yasi`&f}`U(@1;DNHQtxaq_Fh_PhQEz zt>DQiu`sOh#s{903H)GWgji3{KZ0+|gugSxy8Stsa9xP(n1v{$Cgr_+l_?e@WiOec z1JBR|e&{7rzwgt?vDtVSebs@CbX8hI(0@e!jCSy9P?(ofLtJ)1Ie{Nm*jrG!l7_xD zB}(nK3HK`767P3NABR}jdaHxSjWEA%J>Oxz73$E{YaXFK)lQr2eNbQaZm5?#Uboj_ zgM7v#lpF>=`K*UU_ebb83A^5uc^GXOn%h6Wm;S=C{hM#wIofmoPYF?xyyG7wenJ~! zd}Z%|(KJ$OhWuh+JBu8cu@mjo!&)X+gOAqu3J_8gJ3JM(h6Q>#y>NZT|g# zWgz=S6y7K%`Q2!7we;xhrv}g*XT}g`FsEC>8JXi`tX0Pq3eP_`hM|^S8RP#y_(t~4 zSIqyP_{uvKdo6uh?d9xe1e5J`XZWxsWOMcOYA)4Y0ei5tiI+M093k~9SZZ_J|H{D{ zj{@!Wb2Ug*?bT0Bn0-Ih5%C*`AafCTqi*!>E%M&siEsV*a1)7~WSxR<9YYcs{9-{7rcCF$@Va#}r|uRB^3h>E zH~i6IsTW%7iUSWUR9J5vyH?bVMuX4j5Z#Bpl@pp~Oi?;~5V=n2G85A8@X{%`RtS!m zQnMne!(P-AXV+H_A5mQD88C1_c}79>fYjIwV^@1wK|{A-Y(xCWg-S9-LZyHlpGAb(>12~WA$lW^-ZA@z<12t`kULhQoH7@zbEA!7h^D=3G z-PGQ7FT8MpWpuFbKFV6Y!^34oOy7mk-}KY8d!ZYO|NDymJt479Xmro*16|#Q@{XWi zkex@DJss0E9^-F=Pon-87=hir{hc98UT5!HLXtV%-W7>vE|}weBG8nP6_47Og~E8@ zEs$7>03{-q>zx$R*^GQvUC-pu_mZUViB*0gAZH3}jb>cdD@O=j#WhT|#V%8TsNLtO zxxy^yM~yAW`yj%(Dn6z`vV8N|v8 zcB&Ubd@R5#qK|h%%n-g*X9II;tmD#KzgE5J$T00CS_6fcfpftN)XNddi@%O_$FlGz zDgy3M>QsM-+bNdlTROwpa!N>>o`~~{bb1$)=3FtH1vX#h)y%NhBUGE2ox_KV3j^;* z$nk>cTk?Z$QrMzSfairE`~+vUYB8VSd`&HCG!j#W4>#|(7IX9$t^O+Q>}lvHgJ!`< zVAgjg{Rk@*?IWYUyad~KV*OafNb<=tI?+eK$C5Zjx=!>IUN54MgNAWr$Jbd^mxSlY z*H1D*v%8N}`I5)Cs0-yB|6enETaACJ4Buz7FsI7%tvrJobC;sMqzrVx(yA3*+NNK4 z%a*pA0+qKOrae^_?gS~rsd91aORQ#9aGxvTH8;lRFuO8rS&oB_2aR#QIxoMVh+p=ARXB#rFXV$?DFbp<2YPAA=Q|fv;`!wvFTh%fChuh(5Xs_t+9yMJOw;bJlr@BtfG8nh< zU1~ag^1s}+4Yc{GZrzH-toc)4zI`Xq_8hNiAE6D9#*<<~K1NV|Ys-TzEt|xR9*>B@ zq5;PqxHm9R-$J>dQz$&6h_gBkQxfOLPFIerzCP1kU!+$gxH7L4(E}6cIvB^&Rr+T2 zMzzdRL5n9cT%h0(k#mX2^OR=aaYt-?!hr6f#l=Gp9*l{Li|NkR9ivM;Ny(`dqsu%g zF#}Q|2KL>O{Dyvs{(7QI->%(p^5sOGR#E{k2HdF+VfY$`w=sM&8ho9x9`J42LG2dc z7cjiee?pICI@`2Mw1I%*L>1^v_RrJTDfp!)zqjGH2k>{FeAkA*OX6!AwDWo#HvHuh zAMmqJei6X0^cU;58v7Dm+7@AGhXB8T`DXiz#hd!S39enL5uH03J{$7?#@NL2|6RKs zaLk$^=V1Q{@j2wo)3+@k>Bmqr0X`e@|3=Aw5zBAkw=+KJVJ6Fu5{$n~;zQ2sSbhtC zxx@#2Hp@>ObkMINe9TR;g6~wXyyFpbH%`oPJWwJW*7`)ATRk;XBJPaIO&UDVnO&Zc z80UUS47zCFjTeqg9hgu!Y;;3KXWl())~{c4&v_Avj;O&Y1<{V_`s+`b_x!0!cjc6L zaR1=43oqh%myUW5Cb@9>x)vsei(&C1fgdj9vB&MTOC)#ok$&9Z8H}_y@%i|ymXZML zG`nESH}6=sruND;wU9WQ9!yGj%#M zbXl%+zf8OM~)8?FfR<;&&KL-k3YWxdrzCk;p?Mloe-=ApUox?*S0^b+G zMg`d}APcmMQSKkiC$!w|K)Eg2|Jll|VOzRcJ3m;?U#>4@+gPR@Vfnz1`8ajKeP@}r zk>wjJ`M{PW{!Z=jliz`kh2O65cWRqYz5}?0UxoVI0bAXw{Z2cYsEhX%{lUP03%0s- zqYmf?%2uf!t;)9VVB5y78|1<4NazY4&+u^!FNHpyF_yEwKGg04U!492{!o9RIHCU* zdf2d$q#3X1PXqmPjSbv)p4M)~H?UdYcYyv!Rv+QMKY`)XP~USE{Aunx3g163fWMC6 z3ZLn(gFLIWXSJI{=^G0ezDK(vS=WHC3ICVqJD^WdMOe?lHX1@H^q?e{t@lLPZFA6k zapwH_<^@>+(+%k^<};$P$1NtB4_ci@_}}(dk=%TDL+)yYkPqoA@a9P}Jpm>VSGEpo z?i>_g6w*ghrxi@7pE!G(SnaJ`G{tk{g1>eAM3xAiyM<0KR{i}t)OX35*iQy7|3h1XPIu|n? z#QG$Uf1Y+g!u@|?I3x$0@l~I=g8IaON`m`81par%T*$w{|D3iDaO^2F{w_%$d@p6b zOdt5WwC{*M;WON#U#{d?ru~|IhQxo%U#|7AJj?vgGhE`M74;vC>q&2-NP7r+V|l30 z=|9TxO%(9>HihMp_&mOeXzuHFd>ZGsi8$_~3LpCULFwlw)`P+a{73d-+q54TF7aU{ z`W`j@KgHv})C2i|k3k3H=MEY_rz)Q@5p?z_`cE+(g^%|ASkYh4aFl>PC;E3ueCYFO z)|-XDOX35*k>M78xuU-e{ei{^3%^{^U#4whxWq4n&-=*u5qj9E{ad>lc8q{5(a=}n zZeKe1=OYdr{i#chSSwT<6X1*T|FV_eqJ4OZ@>{g?RQb7Rua(k%w7c1U zu->d?r(}F|KidzyJKz#u#z*_ve(d;cKiWBLKN5dF=-;l!mOn8*;t0?|^e0-R zJ!FzSOjq_WANFv&vWI_iyG#5=*h7o72miASM+wkjeAOQhaeu^NRlo^<3XM_v%Di`y z^#MWpyCi++>rJ*3rtkmAzf00be|(I z;*-y!zgzex^z&%^1f3VPOVDn>r}0xHbAN4tUA@OK=oamAia|w*l8ee6Wqtfv+Ziag zN_$?A+_Ky#z*nu?gi@4sj^J5nzw?Z>%OY4>qIQ~2mlACbObhhrIz5}=cg1^%0i-$Jfd(X2fRN*Kujj{@JP*?+X+&19Ni zA^Hs9-wgaMqCtD24}9te;rJZ$iF%It?DUUw`#q(_htcmQIYkZE*N!j!)8p))lsx`< z#!b>*MIF~m;X@BktNK31aD|V0U7-5IUECiUxn4=o=j*cnOd)>&KWWuh;=}&reAteE zoZ8Dr(p&i0AJMN4p+AD@q$1{iOVaNm`slR`$7-BD#<&UfU8em;JA!XUGMsYYJjeLU zeBS_S_2*2~YmBU~b|KeG;iG+@Q}vz1aFjrMWukvFKKkLs>=!NkT@oMg$qbkH9q^+Z z>jS=l;T&gz)(J7h7)|y4cnjn~?_~OHCq@M1->yB5o?zJt*Viy$pWD0qfLiq}hCg=d zUjcuC!0ZLz$aM!fhuKZ-j&<_~(F0nTeiG^{*DtnV{espPto4g_wSKWp>t=r>>7X6; zON{40=T58^y@Gyg;e)S{OmOjqHWct6{`JNm0AHrvfw(n~@VP&CYcD~6B=2Iw!S-IK zxxoJxmJ789p9g!DYxRGky@+`7FH}!sAn3LJZkQ}3>%-*^hL_XtG$OP|6~8JYk>u1L z)P_J#$xqgc{0_-^sU;`8&_OXom2(=4@%>J1qqa97C+pAn6_-1x9l*%2m*psipLFW~ zLHjIQ9}Va=sy%~zwrYp%`p{lv|HkcS>?D0)-Q`;FdB#>Rl8@%HG=GqKY}M|vl{*{d zTD7GVU)#$?4CZo&0axWv`({xPsMl5a{!TrT<24(<2(%0M9Y(#Zayzv@iQ$2AG?yiP z&^neXNA^VWquf2({xE&;oO>Vk{`*r)c6mVyO-@qmfNWv7CEY%FcxvWcfwu*R9&j1YzeIfX#o8O-YvI$p zBbw#;L`wnOjxYVlJFF+*b9>%Fegu3@=v(yn+5e35lP7)1#;13=RzwWse{QFF4$7fD zFIS~(_@O;L+@8d*!iZw|AJCE@r=8#DfG@*5hx{bViQe^r$dhuSehcyaPHnw* zrAyQHug3i8NErSx;IE$XO)q@eKbMoe*y-~)cBlACOOPdGdqSSgT(5s?w};~Ee+2!V zyF%%=13we^+cemV4Zj`opUH68OMrebUfrfW!**oFpH{rOO>1GeJ^uU?=-jE-YcHUE zEPTYBI@_xMSp8yP+w`j0ja0KQuL zi}rXgeCV@VVcYQUCBC{_dn63sBsgvw#e~t9e)*_&OBntGz~8Bz?f=k*-wt^&?}k31 z9~*u<^iJGYdJ=lJR=+k~ho4E_z^_ckRa_XR)H(Kr0yguda2d($yigZ_ORL^xlD zAK3u^5|D@E2lz|K|GI!Ybn}Ju7LW1ZLWUoEnc+PQ_kRWWG5v$Y!q|KFQ@yegZUWyA zZ>_(N`A1&tq5CkKFtTSz_~(G%%ybUkOY&r=OZa~Pzl-6AZ(#UP3I7uC%M2gM|G_7O zk8z9We+c-6#!SGE9Q!xHr97J3|E+jKe~;v!VFErH=p?^{!=J_;TS)Z{g|q%kNuRyp zhidwUAFS^ie%MZj^>7R7<%-?!|Aj_1bB!YTKZE>NGW?i-tAv*m{0q$II$00*?h}cI z;nGfUeW3?q1j7$OZv=mh;n1g1#&FUn!JiG_H!%G0ehJ4dM(82KKVE#Le@Xh;hq=#dh6Z?eUJCf?#8~@PczTpRV_6wD~%M5h35mEf>XV==?;Wjz#VZ!`RRz?U-o(1WC(0_|OfWBuG% z#PEX;Ncfup_!5R6zFETGVK}}u9MV2t{DkS8V}nnJK99V3A_&(?{ojjto%Fo_5z;f( zWeH!a55SK-WrO>_0lbj$?>#_zQ~3Vx0`Nn>x5Iw|JeTngK5B>m0C*9@58q*j{}u3f zssG1GZx;O^{K(^^e+v%%Yo9?6LH)Z+NzeZU{67portI8ZqVz8=WxYxLyS1aNAJ7q( zGhEuU8>1WH6Z`^(AH0wB?8YcYaQG8(8N&}Bknk56{tn=E#ti85zQ2D8Io+FCpZ>Q1 z_ZV|X|1W(;@bwI*cnonB`?uv(Uqp#S#|A&Pu{WIk!*J4DC_cdtjqV$Ma7^Fu!*)9U z&oPd_uVdZ?d)}c%K%%l9s_!>|e@g2&vB$7eK_0X$ir`;id_TnU-@D(0e#$iN*Z!{o zf0*Hi?)!=1FG+m@K8@iA?<0R$)-Clz`12V~`ULz;sRxfA>5%34wUEZIE~Os{XaBi^ z>>(7+`l+J&_J$wg`u2t&Z0;NXF#FpOd}9^0@98wYgu-cDJ94^B9{ANL{X^7?^d|kP zXA0@S)qIx zendMOl!wQo7gM+~p~j`Vjqlw4ggTEs!)Gd|vM)*r9{*OJp?>N)BnDODa4WIO%pV0VTw?pC+9Uu4W zBOlq|Sg)t}iu%P-Z7=r=L|D+j1<#9pZ3^`kEAEoxzQjL=@iD>!-+}{wB;i}*z8nW7 z{sG3v$OC)}4*b&z-x{Yh@}C^%9DN6~XUk72e@^kwYaiL+(*H>MxQQY?3fm9)CB~nj zpv+hHJBfcT%Yz;OdpW**UaMUv#{vyE>`hh3*hQCDk&|{E})IZZn4!|44R|*b0iA|Ak z@*Bu|LH_ne9b+!ONhLZIj~Q1fI3g>+v6ChBAJHP=#-$8TXE<6dLh0FHJ;yp34tt59 zxEJ(|3m88m03W5`@Fbu=h~X5Ey(jf=RA^Cv4-UXTG^R5h591FZIL7@3>CcU1?Md=` zv9iBQIQ)44-fqK(KM%kW83pLr;bZ!NkL?FOE(j;T9iWfXJr?~CIIrtt-1i&Tus^?1 z|A5A$*olOXvo{2n?IPimBpmvj%kjpI#vQDOPKJN(_eacD@Y|TqWQL<(L_|sY#x%yC zBJlw)r1b~1%O=*_REB>CI!>kkB}}JF(gA!h{5jz-XE>;#Uea#|)@=iRTf%9bYQwsB z;H@lwF8vbxr1TH5K4qU0o@~MU#h)I)r*VY$-!@`>HVhwdMgJOwkN$ym=X0TvCi4& z%u+hZ@DGRYN+DhSjbcS>Ow91ZSMXSdJxain|0-BlatwWk)=aunLh#840qNH@bHj73h+vaujYF9FdPtpR#lmFQ-@Veck( z|A6ly=l^kRz_$H3=?9*I@csW}INSCUWZM?}eZY(L9?*aOk6+v1p95Y;Yx}W({Xd$^ zSonWoI&8yFkquk$FNlt@25T}0-v5^kju8rQw6DGuaq=CAJ=`om?L}uAuwi{A;CESY zT4NDqQlHO|p53dZ{ODZQP|dOP+4>1Qh7yQSXdlirT~Q{oTQ zNpEYE-mn)Hd(42|RBXd~ThMzB!g^akdV^tOq z`xBU-=1HC0$n#b#(~?d;3BX^w7Q4wtnSx`Lz{uwL#nIdU3wRxM2H+ouujpa;Yv;d7 z@O*|-PF>?#IezIMYGh?~gs*k!Q-q7_zvWx{eGB~W3;5m89~2mg@kijqF`+v=Gh;g<_)<13Jjsg@n$yZT{QJ%K7^1E21Vj3Zr){Wx2sylpv3oJN8T5 zL!e&s<>yqND)FT#hc9-=euZ;41pn$wf>-!=i&AX`;9q0En&4l57K;Ck!vE$=s&k=# zvM%&zI5!+!`NfHO$|k0Zr)K@}kF&(LT|IZ})4TrmH#=?$e&KwED%)7F%u`fKmNWma z>%|wlM71jG(cTcH;#Imwl5Ab%t=X|+-1zF6apKkSwVrX~RuGR4g$G+nNl$ZheDslc zb*DIsbukmI^aSb_MWZ?Dx(T-Grn+iL0)+|AeR4Bwb+d%)e*oO}{ZJ}5Q+r=~LQDWY zW)|r8G5$}CclGyh#wZOpSo2|%4O%Ps2jr}Csw>X8k5W)AT)3ek69m-IH++i{U-Sjs zH)`grkxjE^jV!3G8(&*1ibk7fj234Hp|#`dYQ^Z#-}Pg&nn%u>y>r%x+JeGb`rFYn zK$HZ4C<54su;0msW2i2XG(X z>0bTlnU^MQ-O`7gNCxSs&>2z2)RW1-5_1?E3ut>Gh(BKg|31L$Q{G z6gdH#nvSyu+en|0csUPGTdy6yb?fj4?tcDxkx%+Y-1{7K9!2>&ylD<+TGh3yR=q!a zyBagq_lXH{$=Z*4&XXXcovyX%apF^0Yzp#-718*@7xU<9t(xe;C}`jgeJ*b2(U^v}fH}j1*PVpK^783ecbb=Ou!-?=#K3}@+JZST zF(t0)>((sV{QLL`l`B@P5Ra9QuPSTEsqp5eO%u`a?Jb+mT#@b{*xFJ&9An=n`WJes zQ5YEeN_!qR@K!ct5I8T~pwIGuKz=*Y<4xn|!Q8d!V(i1S8+K2hvAbdR8MB)kJf4PT z%qa+8Z_;P!C)m&DIq*IjF6Cp)5fcLV`Zd7ODUf-azf`2+JLuR8CnVnn94Ts$jurnR3jn2_ zpoyFl_5btWf`sy#hOYAbhMMw(g28#ErFk=Mb7!`+H$AkqFu9}sp{DkhO!sXajWO*p z6a)z^+h3|3QuJ#I-B1e1;=&>2A_3Vb2mh-cX6hz_l1F}dm*g>{eFTU#b|^OO9m$1T zB^%Za>?C3s#hi#5OJPB}mS@5BlYqOmh!8mJ%}4=U+8bh1wl~C2{%`bXaRZ-$MNJ*9 zCcG_Qt4B{AKjifEjz#7##SP<^U$xk`<7^rs1=a{A>jO|PtZ7j#Xi%2}yC+>A(0zJy zS98OU3(giN7Mv4lPBg}!e8?Ezd=Y$Nwl-d%e_|~#85&0-TBLpxxZ_JVISt(Z`E2yU zva*GvMQlUEU%SS)t!x^(qNCZot6A(d?-Db>8Z>h3GzyT4oZe1w%l_LhZR_bvp%%@i*qsJAVvlV3;wKUlL3$S^tjTP8>NlHi$co02i#&qafX@obmJhU+JIgk7<})2se3FidGUtx>LQ; z9Qcv0=vRm+hkBdZ_9IG-5`}K{=x^Xh$~%-T>by)9JqJIF4LL?$d0s?zY)p4nt~00j zx`>Fw$io8D}?-~I+`-|R2?Ioi9+458Sf#SjsWAHu3dSi@!G_f!aUKXtz%R5H+6xY#s5ErY< z7#-e3->W}>e!K0%$xP)njX$+F{X@wLv^NFT@Q9y&o&Jop55@1e{Di%n$t91A?Oft* z4J&nA#?WrTIZC!Ee-3>IT+H6+JB$H)jU4(;d()gDKgB;-jtsWG*RWnre23{d`anrT zdlKKr52#iY$I_=*8mzbc-y#1M$?tn9tc||IWmle%yiK+FV z4-Url+cwNE9OR8sYH~PkPR6_PblY~YD4sa(>MtIeQ&A>Pyz%zRwc=Oz9-Kax>Q*c= zwbS))6B9J7&x*`p*MU|lW|31ti!uPy3=Oy9;Rw=PBZcF|BS*_yTbq6HFsoetx(E6?Hbit@*k3(H4$&1x@b$V`tg>eI$m z)Yg?(xoYzCXKKzIJb6^>^z@9pT6K(np_OvA-Kp6g*@)q;5CXE<5ame_wB_(4^@@Lf46qnYB zpYp~IA2)vZn7mYXR#o#TPj=z2^0TuF3WjE1QeIG4US3#0I&ms}vrZ@~LQWH6 zZ{l$T85W8Tsg(BU22#qfQB9rD$#2}%l|{vvFa5WEMnESMMl?+=uPrL^RJ(_HNhe8| zQBKlVa7+`(e2w(=6Ze$w*;6jwrGNMAfl7cID}FDgiFX4r$Tag2Ae6H$$0B#ZG<^X2 z`54>?iNe3bxXe1-y6!P@iGE5oJ-UQY6rS_-{Mobfs~Q@NoL?U}a9Q)MlP2B@bl7Ys z@ZT_U5$BE*6O1>XBv_dkEJo_vV8>G-#^7Ps0XEoQBHFZf6OA~m(wnkBwfpO}j|isi z2*6UX*VVx=%xD!}BJu!?X4n}4SSs+QGQH*iEE#xQHm)TA%K&T)k_q zd2&lm`R2UID<@2MHn&D4&)r#f|Lls>mQAjYEJE6V5%U^%mF4vO5VQ0&^W%wnV|ql- z^Ml6e5sAOubphFK4$ijVY#Ldm^fJ=Pp!?#DY<~5Y0^p$-gE_J&H*yk+nwGWvEw?M< z*K<~ms-KkKS`?e+^IhefHt_5X&C5m$Z7caX!TTDK!vD%ofk6*rA z{C@YI>duu5i7#SSJqvLpb|O%q9h>5_X5ZZra5gg{)n5+`%Q7tXs`L1NcN8Q z3TM|d=%GXdc_?u2;&rU3Xep_9f(vBQ=^yDLt36&PxdpgjcO5+lUFgO?%1dP#vYuBa z6h`eoKVF=*Cv|q?sN5A9MJ2@z<4g9qYU?YPChz>Ek-BzjUdjbaht@WgW{X)7=QdB$ zV>3&e26~GI*Lmi+v$ICmmluql*;JRC>uspYox39@t7>M$^)Omp>+s)>d%+vELiUtO zn@xfm9YHHYqg~DYA20$Jl@s1oUUrOE7Ii@)o%UD>iOq9-dTn}b1r;z za&`6OE2}@h*0W4ZM#`(-H8%@y$CvoiF~5Vlr{CW(AAfFMBc{WDp#F3HCn9hU4C8Yr zc{!Q0EfQ@_X@SuV2y)94SqC1UUdy*?&aCS)K`QUd%9(k&D z!i3hR^u04uhQz05=(D0~+r6#%Wi_)$&7OTXLi55(ch$7IDQ#yg-tK7{SXI-Sv~t3S z^F`UJ&Blmn;#X~3+jg{>*JY+e7LBa%mK6*cnv{|=qH)6Xn@WpH^2>*&WH!}LoYPbt zTT&!0Zkuf4KIp2&mtBT_P4{e1L~PY*UOGd+7tvZ2H~&rEf~P@>l8e)|RD--DQJbZOpPa1-C{AH^}^(X*pmj z);ZB8h$oF9`YgTAZ&qIjtJ&CH2$2>8Sib9nPqAXX{$CJE~4wyLR4bp3cq*hB;F& zU)nWo$>Of*OP(FobF8V(E2iuk-*O7|{VR9XKnj9vHg?MpG)AHtuw1{cxUSUj5A7!LeG_Pr1ydbN3LTTHk z4AJg1pVNiN&hV#iZ5!6!FveNdGIivj#>B+Pp^a$`Q(G!p#}y7#t!vt%jH~Ohuo|!rmBuabxAnmEy!$R36Rk zgNRN&DkM&?9hy40C@x`$UNmOKhDP_Q^ID?|5{$u7=}`%h(Z-w!!>7z`8*^5dxP4y7 z;H;t{2?bfzJ+GJNZNBQ0O`F7&GZLG#Bg^B85^__9IAbTw9bdonmc_R%nlzu}iXc1D zuSXptuqsoim9fw8=3)tqB!J443m|KuzvK#r39P9M6}cq$BTr2&FrO9g)fmDvB5hg6 zhx2RjN0d!nlWxuz)ddru5|gke|EsE7DpS+q2Ud>kF#jqZscfq}t9fL}+_r?oR4lrZ ze&+aZ)~_^ju%d#7M7~~n-LV|6OVJt*HKNNMMJ+%+tI44CG18q=oHk5uBOpz z&UnI;I(+Mh&6o3_-L){OV7$l384CYT>jTHIOh z%RS@r`CI2*ur}BH{lBvB$lT}^!#e+oKb`YBMU?qt=e&8H2f#y+f7V+u_7A5O40^nl zBI_T){0rtCHSsykjWe3PK2J{UkdhH2aw`g}vl23@hcwi;j;TFu z^{YkM)me$o>fDj(#l?fs2D$#T^*M%)x?}!>{Kol7HBFJ$Q=76eC?aw2l4znhz0v$J zGTvEK*IC)PW<}a*3H7ZLMEF+PQ2$jI{+L6NT}bqN zub2Bj(?6wkOd~C~4&jC)*&Hxufpc<>J}rOJdgtk&7>Xxy3*FvyXKv5;VsFl5=V`Oe z0s6F@)1B)lAp)(#iQ;bk7Vy^`@D$H`b zPJZ_GH8JP8N=7z@(G#*b3mrvql=PuJmsH<6Y0PhGV$!oy^LHY6e#0YsVt!nhVEE?$3ya1oH4l)|q08qZ?KD|SW z)9=F??<(_{|2@p#R`u+q6F1mK_u#xwypaw|bwZ;aEiF}Z~Ft$_L(34`|O{;Gt$kk-g(VDAu?WlLnNEYfBWpmKRxsPwQm%o-P$K@M%XqW=PZszwi5b-_PfD;-NdwJ@?#m&pqedbAKkykYW0KS(g_0?=`|)pE>O3s;dqtCuhWEx}|$LVWM*=kMK2&sie1Ck{gu zId{o7&)-e*UpcZYvV9Xhm^hfD57Tot-}S41v%W}VBP|q&xSi?vi3>a<1TJl$Y9F>X z7kIkbPkr#(f*C0C6#2R^&z0`ZX>hw6a@^^zyh16Nr#Kqj?nVbop?@nb@>>htO*uJD z?m}xxF}_MBKKt3GPk%Tyx(42U!{8=LtYR%uy2u4mqg1a*`e6g@?4i*J=@LJd;cJUN z0}tvi*qTOkSQ6Po7xzW3qhB0-Q!Hfk^IMr8nAG|v=^R!CC)@$Vj_86{8d|r2HMxRa zUD5zOEAlRRw~N&&h|UAI__a(|(l(i{@SD?>w2ik>#`p!joAWJjIOdSjDLvUme%DEt zt$X-kR_17{kQ)6R%{^|tmL2`5VvBq6{{4&HTPhIoyL`WU(`A=!a_@&GiP6tp(d&gC z+Aq_O1*2mBdZflq@~eLSllDiZGPXv4!D;-5s1E*-zrp(682N;Jdx+8fzoUlek?4y^ zJ3aC-`JSgeD19KPq92+%leY@SNOv<6@>toQN`J=vn-5rerv$BldM7l<9n;SyJVfvY5(+(EzU&hS}k(;FJnYc0MECWjP6KNkbs23Lu9 zvLQ4v>k;(&T%QgWVPph~6AaT<2U86iS@#rTCp)%Z+TzhXLrSIySG(m+)F5)I#;&En zE=wU=(a&llyK8q(wbmz%_EvW&{3J`I(q<-ybV|L}tWQl%*O!H+&gu3mC@IdcG*sGy1Y00`$ouoCnGi@0auA#=_6unBDljkn4FESOD&$ieq92waq z#nuh`V>oF9PRbBdqlNi4kpB<(;8r-sYdKmfW3t7>VUJ1cOc{p7-v|Wx)#W}vA?p7= zf?i{YC1=m+3AQNebDaf&hEQq#f`O(^MKj6wI*L=Zq7vvxQX~bdi|C#IZDbKKVj;sCcWjAM}s+C%`N(qUR8jK#S4cN{;q5lOO+8IZR zYg^ccsy1W9(6CS!#4no}7$`HBb#Cc9QZ&yrcV<;lY3=BI^L&@|P4A}8QuEKI#562N zrcO9{;4Lbz3Mc?wzpSC9e0pD?d9c{CV#1 zAX$^w*&R?14Cn^ij2639DLtUduz8b>{R?$1ZRe>1ot@{Be%(m8Z6@fbEc!Woz?gkI zA9813Y;FDcI^ixOT-(b8Zn2^fA}Y3KzM$yO*;K#!V+(>j-_)0!Q#x4D(5uTS9k98p z*{aEx7Y|=8|86YSrk#ZLrGvfoSuK4H1-7`a;lqD=6Rw*&NNY%s6?*kGtXq^<8S4T=p7HPoH$59>=B;$r|U zo_PI6>;<)j9zzmwOW)`;nT~Mno8XPxO>|eRCqI~{}sR80zx#Y^TSl{{J%PiI{X!LSMqXjVRm^=!e$|A4Ic_G;9kzxR-z$XqZxki`?WR}c|0?$4f!_al8z_Qt~Ed*@K z69C@K#)u~ba^=IW2cMu8306|KE7dpVy;@W$h)6#?XXP^sI?F5XI<0$AjeB}NRq8bL zbMtCz`kL$gwk<8s4Ak_Nxm|gw7M-@Ka`C>Rt{cZhokB}zyxJ4+I|@7*nU#48QKwnq zb9w2?z`lj=4wTVmYe;Phc&-vfQB9Ph^v0gso2$azP3onWb_9B>MNLw;y{c?@)hu$` z?41Q(XLGJ0!)P%&a^7m3Wm%;_6)J8?orzbD3^ggXs(?akT$Mfj>I+iVwHGlV6n2d0 z<+LAm>J|6^g(yx;SUJE4CN#v2N~lWJDt20kvt#fgS#!#dw|EJoLeAkz0JaQ$APB~= zkc=VH2GNn#sE=;wRlx0m>l3JNxTm{Kc?M`$;PC?`Mu7mT3t$Zenp<%lijXTlo<^fLwH?7Ya>NIdS6y@#!ORIu}f#O>m8)T znwD$2VqHN;XK`_rO07xKS+mOA_FS7aqb%QE>CDq7EA2@ss;6eJX-YM>%nV*(Go_O#phEDwX&~Q!ZaCK9cVqmyiRqAbD zY;G7voYJp~^V;fC&C*UXGb`C!I)6xdAML@?L8qd<9L$%Ip0GWOx`_tVWRG!r&T;LY zF~d01JglS7bY)*T(Y{?Lw@;fKU5+6reGr)}`gieRtTPk$I7+o)8VyRd3a&4F(eO2c zDTXB;s|8vPB->Kiwrx=0NC|CAC0}+>2Jpp3o@z|%&2R6oG|lr(DGa34OIu2@8uGQ8 zjZHT+nCAw)n^)f)BveIlZTGa!f_zQadTO9amky@Xy*E}nl}xX*y0+9#?{F&}24_}r z#;|mUqlr@EHDQJm_k5$Tr88k~NyxY_;&*@CkKz6eB?&4M<|H#hJoa;|||TZe<$RjD<(8Cj#w z6yL1&^m4P^zI*=s@}B%0m!(WK+~4SJ_0{Fra^04hO{0}(TNh`x^tg+fI@1@}M$f6t z@KEjUtv092*5p6MUEtQadH@QexdPyP9{eZUf%BPs2Udb7+2Vp>Y_hQ&F%wu{$bqEj zWBBE)$p-!fzGh*|7r9=Ni`C5L!uw`gR>;wsY*&jIajmVR+u&%Q)7>&PvvKQ8(WEgO zQj@F7o2z;?7GGhrdq$gmQ`z0iMw%Df3zD*CZ&l>@+Kby8$#Z5;FmuNIH1e0+#^RE+ z9A%P7Ix=(om9D}7{oN&@%CeEsR((=UW_ga+l(Rm|k{9q~RoJo?77x^UE+mVjce9f1 zZYR}x*N>RbD9?l}4Zol0H+ZM&hWpKwM~tZP7rePuB6o9F3WSvW@xO z%KVMakv^+gv3&Ek<*Vv?M~2(mhexJef%x35?bD~xgB7>W*n9T5*N?W*HIXamnu;2H zy|(t@wQFb1U57p)-B84H#mwt5b~g!%7RF@=m<+MaC!4@<1#Dp4AjWjNTpIC035ac^A`NdMaVo2# z4r^gw#cEpNaQUjUlFM72O~qyD=KSKa(xUwQ{0h^CeLd5qeKl5Bwn_4j4h639*ZW%A zJ>4UDB~wcCLSuolwodx}tHUdR8aIU$!1#Ii)Kw*d!r^>8`Nb$4xvQ zyz9eW_@U+iU9o=l#SfE`Q%;wDwv5?)Zs_Tu;+*x&BC|F-D!`Bvxs$c0fUWgcEWQ-C zZMc|(p;Y_Wioq+rTpTMUA)6Uv=Hhn9!{lsYwlPLc-z!})W5o?mKYhdX&n&yN$!{*N zYYtX6R|loTGs&&y{t8k%Gw>Rj@!G3D`}z9RV6}lfZp(_imuV{`Z%o_2pIju>7-n5E zl^w4IF)Cr5Zvt=C3OkrTJgI;(9UN1o2L45+W8$(4qp+Cp!hmG5OI1+ihG=sl;RT!+ z+^UMJq|_>_jn{6(DUi9*arq}+5!*3%bqHxjyzQ=0=Cal?=qkE6Bei`^`kHm5Ft@C+ zC^b2^H_McfJ*QMu=(M-yI{S@-mASb+jW15G8vyfmr<%0N#z5WfhS_T6p566ZSN^Rz zMAWV6VUN1Wt4StFIhomx)#cvW>V_XSUeHsaQ{*WW3Jw0LL@Iqw6hvVVlW00wos_wy z*_So_!9$*o()?7lF|(*_MShk=)7dU+(l4lRr=_m%%2KZxImefmU7u@6*XXrb*_)=H zqtHFEw0P5Ke@0PdMbU+hQ2q zTcZD_cY+pNEZUoVfFNr2tQVL)!!Xp`?1<@gEBR5J69`)zSOE^;uTjDB7^h9Mk=eU1 zDJXVRMUpAqWY7&5D=YGA+^K4p*V8{+Iz*Io!IZw4roz6Ol3CMfx-kPDW@_s7=9DH8 z`q9*I!IYvbf5$+m%%&@^@^x&yV19Z|WxCIKO^PYAplRUrSvwxPva`KdqqjGOPhHsS z?{Q^W8}(QpFpIGGytwPZEy&z|)C#ImGijWIW_9Cc2Y(5Rzkq;L#$0G&U)#=|Jsl~| zB8!ToWUf!GZQTDL8CbQUO4`vywOv&|)Xz6~%L=o#xtfCN6q~=hrL9SN4%bZPHV#R5 z(P?Z&Ax>uWH@K_!4$g~^mXz>WP{-FNIs)5Zjte&YvNG$4$iQIGQS-b@sTB;{mYQk! zat`md!R1LGn|pb#zAJORvDQ@I*Y=mc^mK$?Q4|_I=1g5uyl;o0x^~AKomqowo3Y1D zo@J2AYkLl~IX@N8!akA@9Rx%e3v@c%MtlNni2Ox}kQj1XA*HYd?!(`IuzsC2Z*f&a z0#>#hsCML%V#Cg{d#~#2>1eP2vbtLAsGilQT0GJ?A59#fB02^ai>j;@kDLm4wJQ(jIaE?NBbWB91Be6Wf>YmKHO-x`Ij^Txo}N z8yStfK?Y$P+bG@H&m5?SBQFgN(csWf_X^@{aE7nmYVi5olPYsB_%n_M{BaegQ01&&1F@d?81Oo@2WQI&4%>U z41acxuc*jp)KzKHTrO>f!Pkw@ zx0x&2tMje?v4+-D>t zs+<-?jnrcGn<{2^>OCc%Oil+T;O=AG(KU);;-I=iY>&syZe}Bf|2EbbKAZ9RQt>%_ z-hsJ-pLX;s@gRLxSS@TuEO8-}D4)mnfcT!kP{q8=!TMuDE)(7PW>CeXcSwsYo&T7$ z#l!?qd6R;CAnzm)#rUR$x@ycImq@+2rMX_4^)6hM1bzjq#wSTRt>a9J!#h|5k z&JPxc>i@Oz!tP2UsukL_q~LI<`p~Ge^wbfJTIp-?WNKaZ;jce9_$OYtl5&SQK~d4+SS(w z-Stz4w->sIiJ`i1G75Q2H zcZq3AWr~tyLxIlLf*Bh45zy&U;fxq|8IHIx#5gQas)~CyLjH!YmJQ}{6fuxoJlj|a z>6{-aV)y~B*m)X?Xd8CrO?7ze>E=|MIZ3B>Sc4SjreraNmj7bGWe;^|byZ~wt81gm zVM)oeXf(b;qqZck=&}+=le>uKv?M2sNh%GQrP8a_&|s$LsFXT`PSZlyU$AQKZRKK? zF2klTy2;-(s4nAl%ioJZ3{Mr0t}4s@kCM+|p>sm+bjp>zvSl|>`7&#r?ky*Cs|CMX<569PU&m7@(&vuR+<#~XS`x_i&MMSul&cx1v8x>XSq>>~r7`1-M`M zC;GN94f?Y4C-?)##s>|YVA;pCTOrUgP{KI@1koza957Opga!%If?7CgLQBSFP-uw3 zJTUlJo>xX6$0SE?%tgzq1gAh|K}`Rp*;}-5Ms0fY8EH&OcI!}5p~ahB46#boP-~M{ zZ%ei)^L*~MG}md#L>YoknkcjKvrB(i7M}mkS&t33KHH?FcB*K5rn&QinZcH^t(s)f zoO%5^cP05Gr$p2k>l|DWW->O{&Fl55JT6gVZ%~?ga_U@uuZ5V@rk0?kIHy8SG{Jy9 zNLg0uT$XpjN>U8>k>aG`9u?*i8qf zB4IcN;wCFALzo?v8g|$Tm*6zSdf8;jG#X&TcZJo{DC=O4=nFiBX@O zn^9;j*QipIw^M~qNj8>TS=wnXS?eS!ou=~?Uv^PRPE&W<#<29YqeL`ShAwDrZd;I> zHd;S4l~Eme|cQ%-J%*HWZWT9x~$C@K}? z%I0Xx(opK6B84WYug6o|+*Gu1qifZ4>Dd~Cx1zt}=c8qT8NQ6wZBxCDER)xoXUr7Y zepUCx%^cpPL0W5dF0%f z{8ez6%U|dLumDze4~Xjo*(-CbNB$2+QWw(;e$dqwdT`N$#WY_!4~oI(q;=#nsTRNS z9S%$D7|hV7V~h-D*!(T1C8Dy~{rj%2vvJIS^+9?8&iFSEN4BEG0Lq?&vMfRXyHgeG z56-vzStfeUgU><(Nh-RayHwEO8-+sp5Bl;Umd4s-@Aw#n zQWkF;cp&jKW;ez=t#~(;JUmCLLkJBtJA^ur1bOUMqfk%r)(`4X_>26Zo0vMl7%hE$P0ir?b7Uw|clKx3Iw7-bQnzLGsn&#RIL4vk%__ zRtg(A`f}jT*)sY&z^BEVWsjgQ1?KN_#pN7lI-K7-7?iN0z#ozXEN;A!?2!!s%$6!2 z%VZBxE*QkkBuyw}97cpHz>*lbD_>OooTGJ1PH| zcGF_{xyj%Rz=quV#CXv!WCCVa0$vl~Su6;`(@3Yx_6dCAGkKfAClnLto)XjP5jmaT zpFBZ6V(_tgHIwQw-of4qiN7g=&xq;B+o#v^_93&NU!*HG$m!y}Yy?8_vH8l2a!b)tUr7{29ELclfWV8$9V{4@BN~knC%+vfg^V?)N#?wy%hn(LId>ughl${7Mo*cwReGl?9Wv`dvbNtOs$~^k<8L9lu zG0HeQ_`5Uu5AiO-?#SRopWt67-ZjZ#Cv~#J4q;k(T8HRwsE7THyZCYEJTj0_Qp}q0 z`9WXh=<7+juTW5SXyg@fESMq$iXUHzxwi$CV!a zhXM{w++*TLeYh?WX-jp5r>b;rRn^?mDo;gq%Tei=6q3^37IrpQEhsBnP}S@Vx3wSh z8C_z}Q$m)o04FZ&dhmmQ!x&|*V{olxKEN=`Q06)oauD*>G4+paZw`Ip7!X<_t;eMB zKC#E9iw4mGO}OAu<4noDhI|md;hb$G;4Vh9m!q4{qAYX=6t$aIqmN4>vKo& zxE_lOW!L?-uU|MMG_#f&t;E_k8TC3bS1dZj(h|y}v|>VD!d#U_kBCoF z%Jodx^(UM^;V4#CO+TEN*CN43*QWaQ1&zxv2a!&V*Ve)aH z$UQjGT6=pP77u}q@Jl*MPiHZ7m@H)Vg{&^>4oS0by_Kw?r$=5HUbl7_<(#;2$JUe@ zgYl; zhIrpQ^cK9dWSTTb?&v(+!90SzRH0flOv-Z#?~8X)iup?wUnWQR{FOw%79S-xq*=s2 zl7I5F>geTU40mhM2I-2PIx(l{+ZnxrwB!CD`lim~@~%SrBPJZpgc*opl*-=!#rPeV z$2%x=d3^k88>Cpi2-q4>i+4oQ2M6ilNY|8t*0I^M$65=fkh6jV1Hpx^!38sBEEsex zL>oSV(vY}^wP9h7m(1_d2RYKmLI-q>mt^(m>hXpmUG(taU?iQw8Ikdh&&6MoqpS_3 z577x+As>FQ1qgoz`c%P`iQ+L>Qe6uZAYpA3N57!;;u(A_%nO3KgEAr87QzpjH3<-6 z90!Cx93Lfhptx=mt1(M*poSr7EVY_CTm+`dJ^dfyjn%cM$4C=xT|rk+NS* z5nD&bnSuD&e8;A2TW!7B+)!glsVFE;Ho~XMZf|K!x7E~HQtE3gY3&V0eZIRgecAZR z{Ohu*i}cA02O7H@vvac%g`j_tUcYc)(IUIsKE6_c1I#shs|st1?erlW21vlBM0l7# z^e&GIo28?RrU=o)n~C&C9E;xh<5cN>HYUn_m{`oI3|K9|ePAgu#dV!FsNyG7%&gwt+ zlIpZf~6?<8c%n!=r=U8h{#||KlgDZ>2@#dTBBFPEwKUN#D>XLpW>U z%$ElHU?%K??B2SY`TokFXbF@k&=asbp|W}k*F9t{mW^I4^~^YJ`$Lg;$U`&NZ-0oc z39lG?>%b*Tr}UgU>#YMjm(xNi-1E@()1_y~L){N;Ur%0Mxop>gw`Nb>u=Jt>Z$TCU zZkUYpI6q^lU_~YYEfHNw#JiXjNVmRDU}*v>mq$K5zO2PX+#!oAiQXr@wK(va1jm_( zZ#_)|4Z%JE{m63W{{rVl=+SuS6qOph!XYAx3OTD|!&u~yK|2plNEx$C-yF0_b58q`AXU{%u%H6xKPm)ruSa{ou znZH2O+!NtD@;W=GL2JmMWSXsUkf8oKGFcnt$wSfDSq>>s>$`@a(@5%c# zG_%~PtI}n+mR41?WofHcR)D{TqEW!V%%sy7&~Ccy5Yx?tqR%4jUViryJF+~lOglV& ziwBn=;b?~t7wUi)z7Jvuqw?&k7+v3P30Y>ZZ+z(G`il0wmkl&!R_@VW-&oq!>{HTv zPn-Jq;O1~HsjmO8a={rXki=m^x!L&~<7uP|o*hn^Sd`7(P=xGd)pV`oAyZ&L`e)>HvP`;-zB6CCLAqdG54jX)T>{J9uc(vgfEl)*2B}lh5M4OT zWt58OH;4nd)}#|QAl}Jhz)TVAk)>@%d8QeG-bdv31VI@1n~W@f;+60#uY~FL<;$fu z_7{sJhw(>`;tZ&PER9nk;%l=n^o>|R^Qn{dokiT@hA(=*pw7sP6c;97XWfqXZ=HIe1NwZ7!E6q`OnYgaiP)S2W+v1jT_ipmP?4SA%<>vTK4sS3Tu zrgbQ+ok~>_$<6b6a`QR|tKkmr65&9eqO>XP9%@G!y|OVQx5mMaxmdH?=)D+2xzNMT z)s_l}+SaIwnfbtd-F}77pyX`0k*Yb=Y8aC-1f{G!$~C|msQsxvD>Drq3EFf*9Y$AX zuFLGJ&o)f0p<0?9EVO5fsv>i~z0g`S)sS5mC@D`$wHmFuG<60gX-OHTENh0Ypq#v3 zUQ%A5%d}>i5fFxosTxa?CD{V)?p~!%Ye`DeKnNhuKIO|nfL$XDif;t+r#-K`4h?wt8Oymdj zd9GXI)>QgIU$%@?80D7h6}o33t07XMIH|^00p}eIw`vx3NRk zJ3}KQq3L9cw1o_eOdTPq?@pJ`hVgilUVXzV+&vHjMvML{vBzbvvUNl45q4_ za8|%?zT45gT`x)>zS#BirHk((pWlDpbI+Z3{}T)MA6S5KERH6@XAH59A@9i^OU&RK zG&6e+Umf87b)Nc0*lnrBICpWE#bwOayUJj_UJ|g0Gc@PZX`>s|)3mL!jsfk#J{>jX z>Y-OOiTL>?=Q&76jN*8@8|lx>`Q$R-QxxXK;7~$4%48&2yT~kl5Q=cyOwDY4*ew`z z4Fnz~*q)g7J`N-%|vs+tSRb;MTVp<&=)tC`V15vmc^YS?P6PF{f|5mZUOR!z$#eUP+@0-0< zUT+mSmH+yR|CE2oKgqc)+lx8u6<#Js$!6H_5UYpLto)hHgQWuANznT8ICS7o+*rhd zuRM@yTUh8Ts|luOrP)u<$|?^jf^b4HG-Y^Oo(gpG_Rc`W(Tllc7L-LC zuC3*~4AHh^SqDL$80+J**{TcMYKkij25qJ_%h_1d)DrSnm<^gtt39`X3|5QhHuV%& z1e^|^vxQbS)z*ef>&orvMQ&LS>wzTk3V9W0o*r_2^i2ULV$db~BJdzlkPpenIO7Sp zAnwDE;^DHGQwt`viqk6iY$>_5YN;xy2$g4L6|QeSJ0shgl^(1q^A%<&J}?@l zhI>sJzxmi`c6pSh+Kx;RJX;fmLLSW}r(qu+pgrU-hxj@XR$~u*9A~WxL?c$|dzh{p z@Z=+2n-lOrP5?X*3XX*-5hNdzRc`I5JMG%x&;(#THO*Za77mv?zlCH-hZHNqSLJc& zikF|= zEHx>P8D+400@^u^&3$?uhc?p@Y#c{gL-EZThAMGhDTg_<_F{z$vwnVF9DP23i22JB z0@Ora#hw(z-B=uVAlSMgMl?bbV}lZlxoY|06UA(g0cLW9AA=9tESP6)X{2rTXqLrn zLe%99rz3N8_GqTVnL%=CdREp0qqBKdE@4@-M|l=?lXQF5l_|+uU1n-gFvE~+HYXc0 zf<@Ws`s9C{I2mAa`diE9nbRM?G^bKa2>0Qy?L(q82SAnh6m^}5NO+p z2)@{xnJa)y4sgy$AQN{k3~dNkSzxDX9BVS(K*Rgfa@{<0B zyU@_=H7)Yo`~tB20%u@If|g0JfKSUb%wclW_7<+&-~HzwM#wbjGJCJx-@C|Oa)7Mr z*mBXr(*DMu&FNqHavQ!rXDf59C%<5uYu13ZGbcY&%8)6|Us^g~JioMTp=mF(cFZ}U#Ei$#Apk0df z0@_b(_D}Iziid!?xoVdpM%PwzpvSv z*51=UiW3>*3$eOb1IuU|TLVaAGOLr$Hu)HTh}MEnEQ2O|J1;NijV0tQhn#h8Y)<}w z`8L3|1}*|fSU@KhNX7`k1<-I+1yfO^m0Y}kN^e!Le5}qD7z)hah#6UXNm6ER)^i=b z51->M=pW7=NUg8zpB}pXnSzWAwOV<6`%G&9pGc-OP^p7hf?(i5$VlkXO9pypuV1q3 z>bBmZfPb{wT`^cO_w>Bv?7VDhc&D&q%8g50zWzbSwAA`Q|FqB?yGEm8Yab^P=p{yA z7f96EC|DE|uCWQ9Iu^Kh-`>4a)Ym;yvn!{4)6o8_!s_>1$12joz+0?7;B_+|=RF#I##ChU_D2cbC-f+SO5G3uPa;cc1dcoqwml7!6BJ zy0Eclto_&fuac6vF`Wj&#;K+>Li}FWc!_792NmU{G5aiTAe5#^H)i%` z_N^*DM}OJyFpiHqkpVz5nmqnPz0I9Jxx`B5O6Q^1vVQBLb02S5vuoFue%sBzqDL<4 z-Fewns?spzWPh04k{>QPP1>9N>aw^Cg497=Cny0k5Q z$VJvA9OQbvuBGXN3lgaMw3vL)^ddMIfRUM9v=};|e@j!yeH!vr zr*u7^7rcc)yU0JWRyWdZ^p4Wl4LgYJ~0X7N^6q>O^I0djTv>DGc>d!zw-ydRUs-oyW=zH{LoW(6{b>qA$ ztDAu9JQmWj(wj?7Rn9b%%1KsKz5jmId+$l#-tpBPcYO8d7l`A97o-np%eyRnE=#)u zBjbrLB(}}s%Rs(iy5eKoq-RM6@>S%6NiCAn<6D#4`#WI0DGn=q!ex~eG+2rlj5G%G zQ@-o2i~pBijzM}A?}dEmyZ$=wb@+e1@47uPaLKD2e1@nAoW$VP5+6|@v@aAP@dWE!x;5$t74u;o-ufqf7_@Y9ipu(-tqrf0oIb=qUXjalj z2{~QT8>)Y#{zE#Gq+EQ0vLQ2^`AVQ+6eKuAp)C2=KT^-yc`@+ND7X;8eK%h}8PPGU zpB-r63cf}f1rPGB%l-I2-%#T0`_b`Xt_VH|lpIUik}$SbGi8yXcdMhr(okexV!p1%OvsVT7At zPfpo4Huu1kq5ZQKTsm~P4|g(m_fci!+mTByn?~Vk$J&@l{K9MG4kn3PCTMDJjD*M? zF`D6Jn}yY6ANd9M(hG!a5CDDZQ1iJ31?R5JU$G*eRBhYVcjlBSXR$eV(lvF8uG7~UzU136(5#7048|p*B?gB^6jH;z)xi!}GRJ!x6ypHxKS!X-F{{FHmOIvDVsDHG2Rtmh) z`B+<{4}%vUfh^3qC*KoUuM<7P_8`IpK@Rr@YUkdM07NhN$Q8|o zU-ZaQYzAFZ!#zFWspKnZ25y&PZvZYQwLj?uX8}89o3PoXCL&g2t#npiZ(dQq|IC~2 zlYUONl=PNVO26|H<$b>nhr7DMW1VDC*XXEZ7^5obda{Vkl?dDGVNnm?-jmtp?(V}I*(_s4kND{c}wNI0!T~n zVqGfz^)0ZeE7_Qd@Nu+~JSU#RPL{R=C9Bo^aa=)J{-StxO!s({Rbo2YDpCi}5y;}i zJfQ{+niDm%qBo+5D=|gT1M1b`6{Hc;&DM}7_k?dnd^-_a9(s_hm%6GPxYW<>5}g5ryhLh!^8! z@)5^(82%Q3ho~r1ZTZek`hiXN`1=99+|MgFzdSc;)5PVtxs3V*qIzcTg zZh$*~Xh?J(#Su!*>p^=?)}E5-TD)fH-&0e_u)lUFzh`LcgP{u-K0#Ff{MWnEcE$&b z(f^2O!1!*)yKIo9F;^;{hIs7ypD0P+rRxWtRgVv|#m#YxI75>1> z6;W`S@p6CRKyp71lo5yYj^7gzWC05Rl z7s2FlG@!jVcsUQ=<&ewelWgH_K3+V^6D#+cFrTiW>lj|hHNtY9>k%F%o2*asd3#h? zg8SxckzXX-NH+5P5WFgv#PZ)079&3DdgPZ1Pm?V?zku8-ERN+rgZvA5`>YmHfyEl( z5wba!{|WLJ@caV27$WBv2)`Zg|8Zd{J(u_I749OZ^7=t?t*|s!|7~F*-OT&15}qfg z@%$=si?A{QKFaG?2`|O!7n4Kd@WJ{;-=uc}euQ6PIAJ5f%>RkE5%E6rnwtbnt1IN*~hx|J> zUbg<;qW54NUeM!xyx%;MEWFF{S5AJ2m3v+|g>ItD8J>lok+nRxjGQK%5}T)X-j2LJ zD`WVr2K~$H*h6WI{%1$OgS^M+KVN8w(RCFmkI}Uk9)>bL-WL`?xMp-+AUwsWiLG98 zyRahG-{YYBGwEvNvs9Vx3x&JMx>){UVP33$5N}0I)L$0Me;IUlCfyLL4{AgE)xy1G zYb^hd$X`R(uzXPSdY&Hug)fZd&%$_LIA&h+iAQ*!mn@~wqo5>39J)`a4*P5p_h6X_ zBH^<_sTOnT0k>sQdznp^WW@qWygeRaqN!OsXe}%S_ zd>}l`&mCw5kKkCzwVhH~R~I7pt&{mO#7=rI^csxMhRGBsiwOZMmOz}y2WNKU&f{0~ zX-KlEvabynC}0yvxH)Ibd4bVW53*xUGJGR2ecV@&nZY zmli<_NRHcH;w zeBx2DJ2mlnW^bBgU=3oqG0z$PxQS045PuBcz16S0QeC}&zxo7VWmjz6SV1bK7eD%l z{MQM)pTMaDR?r&s%(N)us{l@flkg{pOFQw@6aBw_lhfQXZM360ES8WmFD~I!7P?E- zCFdOv8ttyQpmyjvZkOaROl@&bsP^jIc#tyJLeASliH`X zbd33OYSt{Q&o6(o!5?U=FNZ;*BUOoKmfRzLnM;ItiKD~G&b=s_ycEjo^ z(oc>DhISQh`Sps0e;xbz2|HDe(^VSuk|mhkE?|x=UAA&VP)o;GwOZv%K$(m_ZrA@2 z?2#9yPd|5BsnOmwwZ5*qz%Yo{Up(G&e^EhY)j(yr_jqv0n(UGKseKJ?coE9g6YS^+ z)!VfXmioM7j=Fx$X#3&LD9gG*SPd+*P zlFXRAzLTSvXv&Q>mG)H8)nD5)t$8>1z zlXvHKR|c!=NpWSlt>x+6cm^{4d6@X4`NbsSI}$LEdL`~28E zMh~36b^1@l!?80r<~f%3=|mdJF^v+vpX)(Ws?^N$cs|t zfat^zOd7so^LEm5V{GzxIX-_V2Q@3Z7aeag{~);qt>Lk(uj7rz<}y|`Ueql2K6Y@t zD7&UNQ5JA2W9@=6SgT{ti-*x>LK)U~{1UR6XQKOU0FiK7ITlX#q=^hDY+Y>VAhvea zusoqY-AIXzW zo(F~EaqD}0O?`L#x*16J`xo2y*c@TK zKxb$UGD{L)uCWz^#ifwftyBrlgC&qy9E^E^Z5@$)0YZ#oa{Pa4~#df2@a_w582pm&znAJcpDn=|q% z%m76-GlP3~fO~!hhv2k`JP)x%8SjX&b5XR9VIVoe(6PKWF85lSS=>U7v zHt>;CI6MWD;feElw88i&NR0hsy8_$C`Nlxd%z$)0=c8zc@7J-iOl(BiZS)lBd=!F2 zBG*A#%KGH6DY+J1ZWS%Vx^G9j=Yx799}dt{K*!SgJZ#4)<1~d5w*Ys=lkp?t4mH4I z3`Hl&WA#do&BF=-p7{8onNFlPhMV}hHWVG7H(syg*gS@Nc^^i-@x2-QFvGLXP&|=_ za&lTpoW^9iNM7498joR}uW62U5IDmrLwpREC@)K&v1JK!mK$;s*@l9c=hz0$W*)GK zGX7DA;U9Ks!dEliuE89Lm zV4(cn`8a%VtAJKB-XDB#66(>Lk6tyAckH-0{mXN*Dj{#x(W_zxIXN#YAusDF&OH<8-M|O})@Lv51Y42ECJQ?l%-*P8j zlmCD4f;F`7xPK>3bRJi3U&a51B@@@_376^rd5Me{6pqUf9@s8QVCM@$56@m^>JYkN z!x|K(!wNnJ_xP6J<&V|Edfctqf(Vh@g$sm>gi8^X{3_vU;d=PU{ug3>+$r2EJRm$G zJT5#X{7U!@mmFkeBsUku6q6vV;G}O0KI1LkN#CCT@R^nWUs*;xJVDU$sRomNKH-0) z{bV0d>VHxu+x+9;j4z}}%6QWMs6Rj|Otz;t^D~iX=)`dW)?vI*w`yGOn9fr0#bp%o zHT)@J@)whNWSK55r;uXEDPyvn!qQ|}Q%>Wlvb@FQPw0UO6Y!v?gN7d^AwM1F@*y3k zUHL4FGOQ%L{0t~zfW!3}VbN7VAB(iJZzLz=;XG~u{LG_$F&)99gRIoWk=y79s0Vmu zWeIP`$X<0}u}7Fos|%JeJOJ)i;=-^C))+HP-!53t?sDLzO7aZ*8F{L!k~~w{-Bl?y zRCd#gOB_-o&wbia+{=?2*-t*k7_4{$;#t9JQW=)V`{Rvn(UhmgjC`1Gcdp+TOv>c@D=apJi|(QB>J)-#O*LR$xPtuKgq4QB^L;a z;04(v5LDxD4{RScx0P9m`FH4;eA_Xf*?iCu=4*{FsZjnM4s&1=etgU(Y+pD`E(`DD zDv~c_Wmtvr#DfWcOD|x;A$Lz6ivfNYR@l(twr17RAS53^>$6%&&=;@;IWX5oenTFV z*3e36*34^f$@4Q=iK3n`H}59uuFvHeLb$m0I{Pw7{0#h1W+0 zgkkp13|n1z&pib9X8tn-H)r-q8GyU9&&GeMeKv#?3bCiik;ASL@KOl8iJL|?b*v1E zuyQ#hgr_uo^a#ebY*YQ*y1Kue(Xgnwsd;6%IXn^!Mqb?7u&}A=+s*aMJHj1{nmd}8 zwYT4NX5)%*N7#)bFExjo9hiWp>*}uAf{M+}c}V$fM{`F${(hmcQC?^j_30?kkd1~{ zpq4op{I)T>x%sAgSFBZMd;8xS-3g8U42|~H)#c%(w&rFx+I+F2spB^MJ*BY``290c zk;}*fCZl1g@H$bM*xHPx@v|1R0s%~@)lEzT=iGA-xp3OF(!0S277Kr&k5Tp_17ACA zmET77((A1LL>}V*D&uSy<8Xufk5YIl32=iX;^@)ekn8XfUo;^PoZG|SEu|6ZY3UICBP$l5 zIg!5vSYg0>j&KjSgBf_-jML^lPFA0#Wz!V=#p?UiN|%K^yHWNNB`yIu#}E*zOieUbSt?Q{0%V2@W#d~ zo=KlRG&ya{c-nU1PT&B(yoSxVw`KTq99O^#(zep;SzXM7j01L;0Be(o&PXFYdh`W2 zoFQc*4|vp4iI^}xfc`=*--tF?Z0B;`m7ki4)pi)c8CG1gpvP{o@ zNLK^qiG0wZ2To0wkSysV=|f_dOE%$@=#V~;KcEK4a8e!Uz&(h@CbF8lcVBwxt1iuV1zAwKwU&-Uah7zv_uA8y@-m(FeZz@{PS$z5d4jtA5YsBMt4oP7i~s znI;@g%qp#I#Hkhp? z)|8#;nYK(^IAKNmttllbR);}TtJRY&Mx#DCS#KO~r7*>sYtRI>$reJZ35l$#Lx2@x z&={)qn)NAZ#b_&owY9@wFzE5GCo?@GBWu8#;%9AYt2KJMSZk*=yrJ2~Y8{hon5#s!FmiMo^m^4##Lt zwqw+ll_lMWA2VIFA)7uMC#=XyI!BQdc`}KPMsCIvNv%oV$iFOh@-w@nqncE^G-6*v zlufPehopw{K|atK$LSymRKR@dggA-A1##RB>12d|W%v3u-F>T0={(s2NLzQ=scU+A z*43V5As~)pjGmdjDsfH4hdePj2JZy@s~GR`aIY^ne_Sx;<4N{xeB{9`(t$Wi{F7EB zng9=r^$A|I5B%yu&UfQ!I}H2iXVKpZiF_>~PYBY_CiZ~@cyxS4$K6cfmg^aJQFGDn z;?PJ3PXFaY8^I#pAk$-Wdd>Z3Z2iUkTN1~n;E|0`-=$1wkX*j;5h%l!$J?SiAK0vl zHNtSiaY^=pZ>jLX%-vndzWr~%NuQ1QWwwK})x|QtG4|`^v11H^&`aiW{W!CjLaIv} z_c6wm-=F+-d3SeZpoiYf&K@sy<5LB0Ab?NCWk>ebeJ)aP!Jj=~BEQE|72=-0%pa3^ z=K2Xc$dI0W=S}Uqupj@Yy}sZlbLSkKJNMw6IoC@qTr@jxXlGyF1%tyodU|&37`tKa z{DZ6n{wr|e!Fh+w=I5OxoC%o3$lWyGo z%5SeA`M=nB+WnY!4lh}Nu^+_PA3MZxM&@vwVTZA}ab!Xq*hTekUcLEIGH2iKLys_e zAy<&;Y(K!B_mj!<&+v(f`;II_n?FID&&srfhIf;-tUPGx9buf7*c_2Ld~acx#tgGA z5kLhuddO9q9!1BOy$UXNFTM1UP5XZT`juNA;`BP+$E|W7XlEZLUUB~HU{9MjS;WAQu?4dS3NAxk^ z^Ul~DP1L81vP1HbcmbU)*Y?vfejc7w_wHET2^y7c9{fZN^BO-@FCx}bVoii${BR9F zS35#u=8-3_`t+~+uKm-}pU=PR zsC3``5hBnp4oh!;`r-aX_pYjl3isY83DF1d`yPulVcoKKBtVDkn8`E^(5c`DKe1Qf z5cx%g^aZi-!+MAG2_2Ijh0y&8qZe84@HprT)}-hw6ZA4^4jz=}U~+k!KmR^Kj|sAt z4m^+D?2MBY_C*#>*QI0(1j2{cXCB`M&suqlme{0EboZ>^cJEDVC$@-c-7PEq>u!5s z%ZB@tB))dXdHoK$e|Bs|B^l&!Wjvg?Fgu`+!FU#ledS0TRWl}_&+lIHN*n1<4tHr4OUvR9y0dI<| z!%5^}(v`=a6hS)^WqCW#vl28JnH*LQ57y!nz|SLx811x1n?z`|Ksmb@pTQF}Z~P$30+eF-m!1^J6%{8|Pw)baN<*uz5X8EMFg zK|CHUKaz!?c-AT8P(irl%^`R(qX`H|WM}8Jp+5I|b+X2+GMLSz%vPNn%*{_TrDr?q zre^2O@G53|ODe*tn#?47qs?kHq+0{Nq>LoX=7NIR3hxZJLz_`o?DtjGZpg1ti@APH z()4+Ahw(a%-J>@u)H;JEMV+oxsfOn-STtq&a907{oU*2+b)9v7-#qC}Tbe>clZ?gz zlBsuRmE>1fwYi-Qg@v|LXO(O%J+-1>Sd*I?%rY7>ll6An9IHW>ZLu1xb4+f1a;7=C ztkRJ@Tv&c;+1BEW%FYIJZBI$l=I)ucECn5KS&feLbNhO>r>l+H)ZCOzrQVW~WK^Xn z^eO3Q_f6TZwytY!USm0H)-apPTugpH-W?W%Cf&;X z;bEdV@npDhCQ3S_Mf>HD*_D9Owy_^fa`tYHMBD z+Sua{_AnZALyowT9zuj4+`v&{de|F$>?8nUV2?pDaZIfe`G#S0DDe(7zte({Pdps7 zmyD$juC6bd-Z&kB_l)+6aKp^1jvJmWZ}0_En$o>yi_*~E6ZThEHkE3Oc(%%tEY=u$ zFWTKdtF&oGZ$@!dZuM|o^}3nQ(9&?Fr#GBFT(n+04iX` zTX(b!c+v9c7>K0<#==Mo1ZacHI`-cD^oOg%H@SKqd#a;u|NgqH?bRh$(x=M4YaDpD z{`?O=sapBKgDcDLX)1#a19-;XKtDoz@D?W^Nnjc8GQ}RZ;z&Rj?6Lwwg1Qk;gUYfg zxuEICx+&MmVMzSSES2t~}c@6P6JT)G_ z!>&n9)nq$L^J?9W;*{L{d2KCYIy0@VXc`@Ds;Cx|RVs0;rEMNtpK%&cK_+Vh9bl*d z%ua0AK)h6t0Q+G3Q37ema#g%votxfQ;cvDVz1#$ur*F1tgVT8$2`SnJz=gBW*GCz_k2FDD)>S`aEakglyQfnu1d`| zB7Vgz&Bk7il<(~{DsBHADmY)pZQ7#wp3eF_+s2H(*2>D3iVW&6sw@& zg@#d9X&Oc;tCTWY3bdtcXrMq_3LTVHzLcWZzt3~`p7hFg9P|DD|4yWP-&fMzb9c`@ z_v`~B{mrmN3_MG|qu1-M&y8DO=j`e!%wAQ%Qj(L}-M&fjS!pG<;@)qHQW!@c1~Wx@ z0NP>X&j9_v0fi*;yID#{c|}J@g*!ieW>IBje`Pi$!V%y96yGO~1?Gpq_ell76Medz z%+@gv0ns`nkWFs?H<}EVTtX!ns z%(lxqwVMO&{HS?vvm&c~bFcPa*%s>W82&rkq`V1^IS)|tBnDoK&*E!|06z2c$jMZL zMaVWa%~|5K7n@9Ri7B?s_@1eAid^pM%P|$UrU~!ter}ButJ~q2ecC(man}Lz6yLoBF2E?U#EoK7504C zzrZil!+&Et`zc0-6hoCt8P4Y>%rN1sIw$f`n{$w?nsyXy_2D=pz?uu!k1A#&iV7tZ zg-)7lTg!Ke*@0DtIi{!O-BxplzE<|+} z@$Cd3QXi0Ml{$!A4Ltds0*f4YBLzDp@^ItCKsqB*fK3#JLr(Msr^KVO9QeQByG|E2 zE1nk^A!0N*APd=)*B@zfn|Z6~4jM(8MKp#;TkP^Q0z9xRA0ee8Ld(};!iqIVrr>3B zlG2V&J1fJ%-~iNz7m-nmlt0WQC>CK-nYS)VYUt&PLEFsp92F&R7PakvX<`fa&w~V;uy<3_vYHn z*|TDkBH65HR$NpNeQ-}qf+faY4A_(ebNcJ)3l?=nSkmXG#{9V5RcNaAEGUmoiY}=f zEG~(Ttf)mg))poAz>1}%ajOs1yD~D86xX_vy11+~dqwUPR$Y@*m~V>6&&bS-GnupO z$@THf+>lxp8IzfkpIu-=k7D!Uwrx5mHqu_uKF<`M)VCmRV?p`X&a)C6j?A2Ov#YyO z8q$-KT-BxF?a>i2_Et&-ZdPMehbL-M zMwLCn+TdnWdos*%bMjbfWK42PVydmDH!3wVL5amFm=WwYlPM}9HX<%O?vm2Cl5EZ$tVXF{ z5<6vwE3>RNyKW$PAU!fQB37N0>)3Ybz>mv{QthS;OIBo()r(lzr06`Yr>Jpmxi#L# zwnr2ecEmi4)z!<4uX-k+~+wI8wLgLZ;Y%4}S^^_jgF=6L^kHG#fUHrz4(Uw`rT{nx@!kI{q*;6V=|^>TkQPepEgxEuS9Wb{o-i zk#{zW{fTw~oPc9D!;%VXtDXJ5=2yR}{nazIzkasnS@v%2Gr0M6&9l$dJc~V`c=$_D z;VA4KiOBA)XIzUUeifVb_Wa8H{L0OPn+69rT}zkwo9S{8{89bz$2hnB1N<(YIO#e) z7n}*_XCdXjBM0e!>)&ST+iz=6U9QYXxa+;UlrH}XDt{}UzRhmk_}%aR9528gVW=+- z8aj)4l%Re=mBAGq=!z@8SxYGY55xAjR)DLRpTp@7d zMn1mK65_}b3tmv8DQmTVX&)=IahO5!?b=Ojvi1|;*1g*OO20OT=C^nF3!Eh)<`;aj zoL^bW9Q$mmagN2*vMGFywP9W;7xQ8iEYS*-ig2m5C^r%i{<~Nbvux3BQm)tT*MJ+^ zPuOJt4t6JjbNaPyO<-VytXO>>r(A#AH(qni#=(t8j>t8q+?IIfpYKdmX8KPg-ud30 zA@xzVOU$K}iwyApAdUy@4P`mgk0k<)CjQ6ksek*%gX^m6tA|jot*Wn@rMRcBzVKuV zdrMm|W95Y>+4>vbo`uiX9=!4GA$-1$ZEZPu;p*vZgSMdgkWqYz){{Mu9lzKd;~nY^;=IB&<2ce9 zh8@rX2yr(JDzp7xDM)Fk&G{pU$E6n9H|kiv@)&zShb;h^q-C;HN;wePAB=^L>;~}4 z_?SZL1bXp0$)pT9(alAa=)4G=>OZxo*oG{v9truMWY1)2SF>woZP`Eh*4bOO%)WIp zte%1<>T@UZ)*-%TlmBs=4N&wQypJmOIu(1J)Vo7zf`cTI>fG4mpabyMB2#ODNxkso z$qR3M`|TV3Ve(2jdh*MYgR~9$=khDgL&F5nPdd!|O;1$yU0I$qP2M15#Kd^Agsi*zL?50x&ydqBu z#3+GwgKmRfw`ob(IEb>LN_>xMz6*7l1g_piAJTIPKha6dH8LIO|Da^VKT`szqV^~u zGV9_rlC`1-9R9)i=)ZF~FYIAd#pTsheNFnX8k~G;Ck+n%gyY#e)EwGt#aW7H;Tod_ z-3^FF9+z*(x6l?5Od$m6g&mxG>5<{EBhyr7(Kg^v;3p>ctzNw7EN81HlRawNw`A$I zoy+=mm;ZWj@UL}?I@$)B`^vjqHmLB4USQv0J<2=5b#ta&=YVmSF~xVAXn>W1L-v4bTKV#1~;N1n6ym z+DhswOVzl5`SodbF~JvpfwQ`TG~5*y7N8M2=E!M@h-Mb2gfm;j_U+& z6Olp$XR3Sc>UUEBW6!*&%d0=9NGgrqLUw4#rH*_SMkdrsWP&OY|8nA~IUz4h(;E;wr%P3?W>?>Qm%apf`4Ef=&dKCE>bFL9g@ ztsnjDES^vYY5*N;oKgmm92PqPhQDs++>+y`-aS?{Yfb}h3u98wzwgBEl$gS49P3Fk z$gjMyesHk9yvJpG_t^1M)}r1@y7!c@6T8p9kCja3tAJg=3xQvtBaHYhu@`b4i+HZD z2e)m*f1P$1cr)VJiQm-sSnP;arC8r*X(J5owVa23OXp?y7|>qWfo5e+X}vU$KPF~L zj6tM%HYq3b8+uHV(dePs_`}3y)P-eMlQT}5rs`PQT7aMZ1^7?uH ze;U>~_5)a-vBE9xqwM&g|8WrfOXzF(jv5xh-o+KZgOIFv##}`z+g_>t6=wilTFKJc z@0q#d>8G{-bUe-Br#&JP-v__Pys!tk!8&4NgQ?CM3oJBoH7(-1#pEpQzjT=L0MqD@CW!{-tXa0-wkM}k4y)ksiq+_cvb0uRZ6L71-4 z-egYpd?;M?gY_Yh#nwx_WshaPJnUvsK6H$2Id)7tbc}7HZ|VP4cTu6+Q&`}U(Vlo>CX2u|p zrdL((KUDiqRo%KPA|l>wiA?_0@*MJ&lJ!SW)?3CaD)PEz^>$1W_soiYgBASf21gN|1Zf@Y?Mjcmyg>!ivb$yls@*;EU^jczwq~kp^8fyn) zzZW}D+c<+?R#&&o*gB)7x|$xPR&`WWb+A3W(7xh@lFL69-_m{?{3WZcZut>?U;pp_ zl3#(c5X=h!GwmS+b2nvhlrog$M#6R2IkbA8EZh*zQQmA3J;d1#a2u{I)XOlvWXV~@ zSy{zQ5k(U3%Rhp^&DFa#H`pz$M)a;y6f>OJ+4BERLl;?XuomsNpL>Fm200%Dv z4rTyD1S>#?(+OOJ<_$AICIyyteV?c6kh)8Ic2~)Ho+<0MFHvr2U0Tw3!z$Ik0&DL! zb<(1a-i?JA9}}g&L+YOK znyCD>*VK^uKTz3+AYgWN2Lw(r7ov?YNM{1ZdE%Ek9DGf)SAmljvW7wikVr_RRCno7ulPR{IO)D>HWUetHVWz+jzbqC-+H(K#gS z*`dUtlI`R59TF|vMQz-LR+KrszAN-rZV~JMme|c0EWK~P#GH@~muRd`atbU&geB!= z1BcX;Cr|z(v%EVmuN(ALdE@T8wMFVnLUc5wu57(79YP{uW7apa#ye4ANR>1O zSnHnyzQ(XF)N0qEg8h-}s%Q;(jgazv!cvF5B1a*MAeFFK282@6b0ygg&3Spvz1c-w z)21D|d{v-N*fnOVrnt;f7@erJIke2lXB8Kh*RgdaO)V|G4RM`|x1MNS5b=!YGlpPe z=H&&o4LLatwFOi*N3@q$)UBGL(^Z0-XjDI9vPMZsx!gj?VgFzDMY*3Z5V7k1`@iVd zVZNl;p`H+Z-YIB4&YjWKyQEH;rSw75kyY8bYGZr@Fu5^E^YLx@^Qn zArY|xE|i;H`6Pne6^+xviKOHxMP2K7&MGeQf6dZHw%HY(X0u(nPP})Gf=*dZR6SU4=kZYZW zg8=z~0Tn}6sDnfG>Y(z5b{7tDnRNN|?b`>ZZ)fSv+BtYWZDzfs+sUY3 z_mjmoP(ay%=*3=D)o1vBel7%^=8hNPA37BL4fGn&^4sLEsO(|SgA|D0qEBydV*(iz zZopa=e5CRBkb8=317Muz;Mj%HfX0 zt?Wd1&4_iO?NMBVTT{HI?@U*xwzPb&rDbaKbTzuzQCHF3u&$xIV!dA0r57Yde%8Ol zjlZS+$z?V9i;kSVbLZJd7Uc)8GK+J_bF(K*!qGr7>^Fsldnyq^1TH29-CMOe#X0ZO z+eF~Z>A#?F*|NS1`t_3IM2m8}vQOWCAqmQzUutTk?vJuE+DI0|KXzw;jmdWI<=0vc zCh1!^q8cxqh8*EE-j0^dxZ z0^cZBW&u_q_d(^WE+TjdNeD~;7AXH$3kMe+OJK?b&V<}z;fn9^-*{;^#D65=KAe@B zU7DTBJfhUj5j$#3T}4Kk)pw51nw9~q3SQU6=wHzBFNP(R)RpwKxA&k3Txq{LZ~%+& z10~J>K|YT1Em^&2(dv@+;)49pJNg_i*MS2E2vsr0oKG-$(Dwx5-x>E^A)8I5f{edd zY|s)`f&#%~M<+_~Lvey4(fQz{0f6^O9s60NBQBw|vNR#iaj@jQ(0FL;lfet zU0b@$sj;qzin_{ktg4!Mb_sgIejQz&T5Rj;?Ci1?r~kqWVBP)boYLzS zbhYwtH9c|p{0lCafB6$t3vWMv%H+Oj7wI$`^ijaohFC!`ks~34KbMZl6Qi2}5*4^m zdIjju^FryK2we?QF6A0SkF@Fu(A!aTEXa3&nn)%JTL38tI0MVK8C`B3&3lljG-CIE zj1wy^pO_SV{HjJ%D%xuTEb$m^DXj)dxzEUdoK)45)b10!^GtkgWq^ykj(8vrL$GhI zGxv>X8EvIw_i+q93;leo`>9S~1=i2-Cu})%(WD~^^YLYaB?Mg{mn^ws9rOU)-3}76 z9t&klN#sf2@f}_MzsDI}*;U&x)Yvqb=ycC$OiC%jgDO>jFtgFx%*ElqbS2vIs%sqT zjG_9XjINUI#u*Wv$;tAOBd4pRqj9DX_jUMw$mgOP5wC$+rkx(=G0OLBoX0Npa_xOMs-lDdm}4je>m#hLo5H0r=!CGarV3zhe@BtNFPC||vJ zTYOv9>3jSV2b$vvZ+)X-QLWO-Xf}qq^FX)Ek-NDb7o3nm)ZLDYv{lF{#&Vt1l~v zt1hYOZ7NyHZm-Nu&CiSTDb0(^QmuLJ#_sOM-TgIXlWg@}6`PjLN>7Wt91uim@%nzgm>s_J`gTvR$;6)JzM%-r4Izq|j^nOnBZoL+xOyX|n} zAYFUsW@OI&1OJTL7yNv%{aT6)`35k^jZHdej0+P>GSI;Z0C)+fif{3E9o7oSf zE1k~(iBS5UNtk_PCV-8Vc73?sl0uj(#7yMq<|9_E=Mfh3$RpYpo~o{@sxJ5^My;{$ zzj66~`XU`*FI-=^wsc$R2jW|guod*Rs*~Ger_`pUsWpu&ua1qqdSzpcnwC~O zC02X2s;;gIkwbDUrOt``Ij~oZ+-FDLyD+~-J(LnBcG3B~VCNX`vJ6_Oi#V6dKh4q} zG~7I;GN{0`73xz@$@%3xl{mw;fVd*aiQuQfR-s`zadIL@!pDxN#9pbyY(34VkM#?f zb{X#=rwUF?{fl8AXBQg)({)OZ0oTEeT4~8jMT{r|l+I#Q(u91rFFvE9u_7a0mF2vl zMYXkyhUNtxgnrP@KK*s&jINTBt{IiGy!f{B&%f=jS2(?!U?EEGGi3GGu^u;xH?52AC%Zxh`8N3jupF>2`4PBlZ`;ZxEMZ zM%ti&X2;{~QMFCAjg8*g#vR{M*$-{GSt+U6nOHODe4u)28&z*a-(_F0&$6tk^a<+I z^)ysJ&0jt&k70HC*hrb&HGZ34@zD@Ez!%1B|7+fHHiH*Wo*ow3tAEaJRx$xgz*nSa z_2Jd453?eAUoH5T8A>X?W25+-vGjBj?$J8Ac3xMA9*(UQ6%+6MbLC^+cBo&6J{nRp zp&aJ@^hXQf}5i=9Qs2b@Jqy1rP* zmcR$n_DSoSuKOR4TTp%v!^l13vJC0Sa&+X(Yy<3U7(XK{b;vXJP2rInj$GnrhA)(T zm>94lSO~#W;@rzOfy>EZSwUV$oPorrJYF$ZnCub4{vNB_u|LtCXL&i=MpmQ!j(sOb zdx!1drs{yneeTWIdY-%a=I1=u2Ini1x04849ogBWE{5Q#ZSuJlrUViOXPt zg6|_zJa(OH$!Mr=uCJ%J24{L%S?i*jij^xWY8KTx{~WVwfRKM+mA$NZ3I5XgT%m5I zk<-92cqu9Q1e*gz?eMZDt~T9fp6{8m@+PLAJp6`vA8`(W!M{R>G*wd9!%noUv>m+y%b zk7eo`!AiIS`?2y%XkA8`_(~1)v#);*H}Cb5+|&cxUi+$F1e7ux`#E55^Y_D(E4f`y z%*ihRBlkTn5^l%HOOujXV7OL(fuk|MyZgk6@9L$hzRD_JQSbfwzQBbp8hN zdQ0+Jv#0Es5`Dn|?GMIVv5$YwZB`bdj^tQC>Q^a!Ho*rhFplhcHDIzD+gzneQx*AU zpf<9D6F)<;Q3X6S0y=-Wn!+WG)JuDaV@AN!alKeY!Vf@q#n8P14)!e*c5ZI-{=mQh z>@{3husN}t`=x#TPTdp^T%&pHS1y1pDG#}nk*kWc2b?hwJirKhl8fX_8WHvnM{%?| zy%`$t5r(AMWSBWvQ~sb_FjUJ_C>#AHh4-05`FtF$#wUNN&=w5?nx)U_l%cK4EKy@@v&uL+U`6 z$D!uex*e*++clsL%~syHXUfWZ?m6pVIV=}em&^Z8C9VA6S@+z7c7)EgMtOvfhbM?B zfzg;y+eV_>b~-rTd+qsFiF8!7v=nrwvE0(j|JOBQ-S%WK6*Jf$yqV( z`s_v=G*bN`Cx$Lz!5mkRU?Pdz$2VLu@VKbo#J01Xm0K51FK%>a)W^?0dv!ti)-{&) zz@xZ1c+~T7`n~S9&C@3To4>PZn

YoY{Tps(}N873!pmd$-^|tLKtcQ|SKo^_N|G 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 )r+_%USi1dhK+UkOZ?7=*O+WA-{?*j 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 Imagine\Image\Box(320,240), new Color('#E9730F')); + + $white = new Color('#FFF'); + + $font = $imagine->font(__DIR__.'/faker-assets/FreeSans.ttf', 14, $white); + + $tbox = $font->box("THELIA"); + $image->draw()->text("THELIA", $font, new Point((320 - $tbox->getWidth()) / 2, 30)); + + $str = sprintf("%s sample image", ucfirst($typeobj)); + $tbox = $font->box($str); + $image->draw()->text($str, $font, new Point((320 - $tbox->getWidth()) / 2, 80)); + + $font = $imagine->font(__DIR__.'/faker-assets/FreeSans.ttf', 18, $white); + + $str = sprintf("%s ID %d", strtoupper($typeobj), $id); + $tbox = $font->box($str); + $image->draw()->text($str, $font, new Point((320 - $tbox->getWidth()) / 2, 180)); + + $image->draw() + ->line(new Point(0, 0), new Point(319, 0), $white) + ->line(new Point(319, 0), new Point(319, 239), $white) + ->line(new Point(319, 239), new Point(0,239), $white) + ->line(new Point(0, 239), new Point(0, 0), $white) + ; + $image_file = sprintf("%s/../local/media/images/%s/sample-image-%s.png", __DIR__, $typeobj, $id); if (! is_dir(dirname($image_file))) mkdir(dirname($image_file), 0777, true); - if ($fh = fopen($image_file, "w")) { - fwrite($fh, $image_data); - fclose($fh); - } + $image->save($image_file); } try {