Skip to content

Commit

Permalink
Merge pull request #47 from jarjar123/master
Browse files Browse the repository at this point in the history
Serviços por Produto, Validação por Serviço, Grandes Formatos, Carta Registrada, Cache
  • Loading branch information
pedro-teixeira committed Mar 30, 2015
2 parents e9f5605 + a383848 commit 03ed7c5
Show file tree
Hide file tree
Showing 10 changed files with 1,327 additions and 59 deletions.
266 changes: 266 additions & 0 deletions app/code/community/PedroTeixeira/Correios/Model/Cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
<?php

/**
* This source file is subject to the MIT License.
* It is also available through http://opensource.org/licenses/MIT
*
* @category PedroTeixeira
* @package PedroTeixeira_Correios
* @author Pedro Teixeira <hello@pedroteixeira.io>
* @copyright 2014 Pedro Teixeira (http://pedroteixeira.io)
* @license http://opensource.org/licenses/MIT MIT
* @link https://github.com/pedro-teixeira/correios
*/
class PedroTeixeira_Correios_Model_Cache
extends Varien_Object
{
/**
* Code property
*
* @var string
*/
protected $_code = 'pedroteixeira_correios';

/**
* Core cache instance
*
* @var Zend_Cache_Core
*/
private $_cache = null;

/**
* Retrieve cache instance.
*
* @return Zend_Cache_Core
*/
private function getCache()
{
if ($this->_cache == null) {
$this->_cache = Mage::app()->getCache();
}
return $this->_cache;
}

/**
* Retrieve Zip Tags
*
* @return array
*/
protected function getZipTags()
{
$padLength = $this->getConfigData('cache_accuracy/zip');
$zipLength = $padLength - 1;
$tags = array();
$tags[] = "ZIP_".str_pad(substr($this->getData('sCepDestino'), 0, $zipLength--), $padLength, '0');
$tags[] = "ZIP_".str_pad(substr($this->getData('sCepDestino'), 0, $zipLength--), $padLength, '0');
$tags[] = "ZIP_".str_pad(substr($this->getData('sCepDestino'), 0, $zipLength--), $padLength, '0');
$tags[] = "ZIP_".str_pad(substr($this->getData('sCepDestino'), 0, $zipLength--), $padLength, '0');
return $tags;
}

/**
* Retrieve Weight Tags
*
* @return array
*/
protected function getWeightTags()
{
$tags = array();
$tags[] = "WEIGHT_".floor($this->getData('nVlPeso'));
$tags[] = "WEIGHT_".ceil($this->getData('nVlPeso'));
return $tags;
}

/**
* Retrieve Size Tags
*
* @return array
*/
protected function getSizeTags()
{
$tags = array();
$type = ($this->getData('nVlAltura') < 40) ? 'REAL' : 'UNDEFINED';
$tags[] = "SIZE_{$type}";
return $tags;
}

/**
* Retrieve Post Methods Tags
*
* @return array
*/
protected function getPostMethodsTags()
{
$tags = explode(',', $this->getData('nCdServico'));
return $tags;
}

/**
* When
* ZIP: 51038245
* WEIGHT: 1.3kg
* SIZE: 22cm
*
* Return example:
* array(
* 41068,
* 81019,
* ZIP_51038240,
* ZIP_51038200,
* ZIP_51038000,
* WEIGHT_1,
* WEIGHT_2,
* SIZE_REAL,
* PEDROTEIXEIRA_CORREIOS
* )
*
* @return array
*/
protected function getCacheTags()
{
$tags = array();
$tags = array_merge($tags, $this->getPostMethodsTags());
$tags = array_merge($tags, $this->getZipTags());
$tags = array_merge($tags, $this->getWeightTags());
$tags = array_merge($tags, $this->getSizeTags());
$tags[] = 'PEDROTEIXEIRA_CORREIOS';
return $tags;
}

/**
* Return example:
* 41068x40096x81019_10_16_51030240
*
* @return string
*/
protected function _getId()
{
$weight = round($this->getData('nVlPeso'), $this->getConfigData('cache_accuracy/weight'));
$zip = substr($this->getData('sCepDestino'), 0, $this->getConfigData('cache_accuracy/zip'));
$size = round($this->getData('nVlAltura'), $this->getConfigData('cache_accuracy/size'));
$methods = str_replace(',', 'x', $this->getData('nCdServico'));
$cacheId = "{$methods}_{$weight}_{$size}_{$zip}";
$cacheId = preg_replace("/[^[:alnum:]^_]/", "", $cacheId);
return $cacheId;
}

/**
* Retrieve the cache content.
*
* @return string
*/
public function load()
{
$data = $this->loadById();
if ( !$data ) {
$data = $this->loadByTags();
}
return $data;
}

/**
* Retrieve the cache content by key.
*
* @return string
*/
public function loadById()
{
$id = $this->_getId();
$data = $this->getCache()->load($id);
if ( $data ) {
Mage::log("{$this->_code} [cache]: mode={$this->getConfigData('cache_mode')} status=hit");
}
return $data;
}

/**
* Iterates over the ZIP codes, and returns the closest match.
*
* @return string
*/
public function loadByTags()
{
$data = false;
$padLength = $this->getConfigData('cache_accuracy/zip');
for ($i=1; $i<5; $i++) {
$zipTag = str_pad(substr($this->getData('sCepDestino'), 0, $padLength-$i), $padLength, '0');
$tags = array();
$tags = array_merge($tags, $this->getPostMethodsTags());
$tags = array_merge($tags, $this->getWeightTags());
$tags = array_merge($tags, $this->getSizeTags());
$tags[] = 'PEDROTEIXEIRA_CORREIOS';
$tags[] = "ZIP_{$zipTag}";
$keys = $this->getCache()->getIdsMatchingTags($tags);
if (count($keys)) {
Mage::log("{$this->_code} [cache]: mode={$this->getConfigData('cache_mode')} status=hit tag=zip");
$data = $this->getCache()->load($keys[0]);
break;
}
}
return $data;
}

/**
* Validate the response data from Correios.
*
* @param string $data XML Content
*
* @return boolean
*/
protected function _isValidCache($data)
{
$response = Zend_Http_Response::fromString($data);
$content = $response->getBody();
$pattern = $this->getConfigData('pattern_nocache');
if ($pattern != '' && preg_match($pattern, $content, $matches)) {
return false;
}
if (empty($content)) {
return false;
}
libxml_use_internal_errors(true);
$xml = simplexml_load_string($content);
if (!$xml || !isset($xml->cServico)) {
return false;
}
return true;
}

/**
* Save Correios content, tags and expiration period.
*
* @param string $data XML Content
*
* @throws Exception
*
* @return PedroTeixeira_Correios_Model_Cache
*/
public function save($data)
{
if (!$this->_isValidCache($data)) {
return false; // Invalid for the Cache only
}
$id = $this->_getId();
$tags = $this->getCacheTags();
if ($this->getCache()->save($data, $id, $tags)) {
Mage::log("{$this->_code} [cache]: mode={$this->getConfigData('cache_mode')} status=write key={$id}");
}
return $this;
}

/**
* Retrieve information from carrier configuration
*
* @param string $field Field
*
* @return mixed
*/
public function getConfigData($field)
{
if (empty($this->_code)) {
return false;
}
$path = 'carriers/'.$this->_code.'/'.$field;
return Mage::getStoreConfig($path);
}
}
Loading

0 comments on commit 03ed7c5

Please sign in to comment.