Balance
  • Namespace
  • Class
  • Tree

Namespaces

  • Balance
    • Db
      • TableGateway
    • Form
      • Element
      • Search
    • InputFilter
      • Search
    • Model
      • Persistence
        • Db
    • Mvc
      • Controller
    • Posting
    • Stdlib
      • Hydrator
        • Strategy
    • View
      • Table

Classes

  • Balance\Db\TableGateway\AbstractTableGatewayFactory
  • Balance\Form\Accounts
  • Balance\Form\Element\Boolean
  • Balance\Form\Element\Currency
  • Balance\Form\Element\DateTime
  • Balance\Form\Element\Select
  • Balance\Form\Postings
  • Balance\Form\Search\Accounts
  • Balance\Form\Search\Balance
  • Balance\Form\Search\Postings
  • Balance\InputFilter\Accounts
  • Balance\InputFilter\Postings
  • Balance\InputFilter\Search\Accounts
  • Balance\InputFilter\Search\Balance
  • Balance\InputFilter\Search\Postings
  • Balance\Model\AbstractModelFactory
  • Balance\Model\AccountType
  • Balance\Model\Balance
  • Balance\Model\BooleanType
  • Balance\Model\EntryType
  • Balance\Model\Model
  • Balance\Model\Persistence\Db\Accounts
  • Balance\Model\Persistence\Db\Balance
  • Balance\Model\Persistence\Db\Postings
  • Balance\Mvc\Controller\AbstractControllerFactory
  • Balance\Mvc\Controller\Accounts
  • Balance\Mvc\Controller\Configs
  • Balance\Mvc\Controller\Home
  • Balance\Mvc\Controller\Postings
  • Balance\Posting\Checker
  • Balance\Stdlib\Hydrator\Strategy\Datetime
  • Balance\View\Table\Table

Interfaces

  • Balance\Model\Persistence\PersistenceInterface
  • Balance\Model\Persistence\ValueOptionsInterface
  • Balance\Mvc\Controller\ModelAwareInterface
  • Balance\Mvc\Controller\RedirectRouteNameAwareInterface

Traits

  • Balance\Mvc\Controller\EditActionTrait
  • Balance\Mvc\Controller\IndexActionTrait
  • Balance\Mvc\Controller\ModelAwareTrait
  • Balance\Mvc\Controller\RedirectRouteNameAwareTrait
  • Balance\Mvc\Controller\RemoveActionTrait

Exceptions

  • Balance\Form\FormException
  • Balance\InputFilter\InputFilterException
  • Balance\Model\ModelException
  1 <?php
  2 
  3 namespace Balance\Model\Persistence\Db;
  4 
  5 use Balance\Model\AccountType;
  6 use Balance\Model\BooleanType;
  7 use Balance\Model\ModelException;
  8 use Balance\Model\Persistence\PersistenceInterface;
  9 use Balance\Model\Persistence\ValueOptionsInterface;
 10 use Exception;
 11 use Zend\Db\Sql\Expression;
 12 use Zend\Db\Sql\Select;
 13 use Zend\ServiceManager\ServiceLocatorAwareInterface;
 14 use Zend\ServiceManager\ServiceLocatorAwareTrait;
 15 use Zend\Stdlib\Parameters;
 16 
 17 /**
 18  * Persistência de Dados para Contas
 19  */
 20 class Accounts implements PersistenceInterface, ServiceLocatorAwareInterface, ValueOptionsInterface
 21 {
 22     use ServiceLocatorAwareTrait;
 23 
 24     /**
 25      * {@inheritdoc}
 26      */
 27     public function fetch(Parameters $params)
 28     {
 29         // Resultado Inicial
 30         $result = array();
 31         // Adaptador de Banco de Dados
 32         $db = $this->getServiceLocator()->get('db');
 33         // Expressão: Tipo
 34         $expression = 'CASE "a"."type"';
 35         $definition = (new AccountType())->getDefinition();
 36         foreach ($definition as $identifier => $value) {
 37             $expression = $expression . sprintf(" WHEN '%s' THEN '%s'", $identifier, $value);
 38         }
 39         $expression = $expression . ' END';
 40         // Construtor
 41         $eType = new Expression($expression);
 42         // Seletor
 43         $select = (new Select())
 44             ->from(array('a' => 'accounts'))
 45             ->columns(array('id', 'name', 'type' => $eType));
 46         // Pesquisa: Tipo
 47         if ($params['type']) {
 48             $select->where(function ($where) use ($params) {
 49                 $where->equalTo('a.type', $params['type']);
 50             });
 51         }
 52         // Pesquisa: Palavras-Chave
 53         if ($params['keywords']) {
 54             // Filtro
 55             $select->where(function ($where) use ($params) {
 56                 // Idioma
 57                 $language = locale_get_display_language(null, 'en');
 58                 // Documento
 59                 $document = new Expression(
 60                     'TO_TSVECTOR(\'' . $language . '\', "a"."name")'
 61                     . ' || TO_TSVECTOR(\'' . $language . '\', "a"."description")'
 62                 );
 63                 // Construção do Documento
 64                 $search = (new Select())
 65                     ->from(array('a' => 'accounts'))
 66                     ->columns(array('account_id' => 'id', 'document' => $document));
 67                 // Pesquisa Interna
 68                 $subselect = (new Select())
 69                     ->from(array('search' => $search))
 70                     ->columns(array('account_id'))
 71                     ->where(function ($where) use ($params, $language) {
 72                         $where->expression(
 73                             '"search"."document" @@ TO_TSQUERY(\'' . $language . '\', ?)',
 74                             sprintf("'%s'", addslashes($params['keywords']))
 75                         );
 76                     });
 77                 // Aplicação do Filtro
 78                 $where->in('a.id', $subselect);
 79             });
 80         }
 81         // Ordenação
 82         $select->order(array('a.position'));
 83         // Consulta
 84         $rowset = $db->query($select->getSqlString($db->getPlatform()))->execute();
 85         // Captura
 86         foreach ($rowset as $row) {
 87             $result[] = array(
 88                 'id'   => (int) $row['id'],
 89                 'name' => $row['name'],
 90                 'type' => $row['type'],
 91             );
 92         }
 93         // Apresentação
 94         return $result;
 95     }
 96 
 97     /**
 98      * {@inheritdoc}
 99      */
100     public function find(Parameters $params)
101     {
102         // Chave Primária?
103         if (! $params['id']) {
104             throw new ModelException('Unknown Primary Key');
105         }
106         // Adaptador de Banco de Dados
107         $db = $this->getServiceLocator()->get('db');
108         // Seletor
109         $select = (new Select())
110             ->from(array('a' => 'accounts'))
111             ->columns(array('id', 'name', 'type', 'description', 'accumulate'))
112             ->where(function ($where) use ($params) {
113                 $where->equalTo('a.id', (int) $params['id']);
114             });
115         // Consulta
116         $row = $db->query($select->getSqlString($db->getPlatform()))->execute()->current();
117         // Encontrado?
118         if (! $row) {
119             throw new ModelException('Unknown Element');
120         }
121         // Configurações
122         $element = array(
123             'id'          => (int) $row['id'],
124             'type'        => $row['type'],
125             'name'        => $row['name'],
126             'description' => $row['description'],
127             'accumulate'  => $row['accumulate'] === 't' ? BooleanType::YES : BooleanType::NO,
128         );
129         // Apresentação
130         return $element;
131     }
132 
133     /**
134      * {@inheritdoc}
135      */
136     public function save(Parameters $data)
137     {
138         // Inicialização
139         $tbAccounts = $this->getServiceLocator()->get('Balance\Db\TableGateway\Accounts');
140         $db         = $this->getServiceLocator()->get('db');
141         $connection = $db->getDriver()->getConnection();
142         // Tratamento
143         try {
144             // Inicializar Transação
145             $connection->beginTransaction();
146             // Chave Primária?
147             if ($data['id']) {
148                 // Atualizar Elemento
149                 $tbAccounts->update(array(
150                     'type'        => $data['type'],
151                     'name'        => $data['name'],
152                     'description' => $data['description'],
153                     'accumulate'  => $data['accumulate'] === BooleanType::YES ? 't' : 'f',
154                 ), function ($where) use ($data) {
155                     $where->equalTo('id', $data['id']);
156                 });
157             } else {
158                 // Consultar Última Posição
159                 $select = (new Select())
160                     ->from(array('a' => 'accounts'))
161                     ->columns(array('position' => new Expression('MAX("a"."position") + 1')));
162                 // Consulta
163                 $position = (int) $db->query($select->getSqlString($db->getPlatform()))->execute()
164                     ->current()['position'];
165                 // Inserir Elemento
166                 $tbAccounts->insert(array(
167                     'type'        => $data['type'],
168                     'name'        => $data['name'],
169                     'description' => $data['description'],
170                     'position'    => $position,
171                     'accumulate'  => $data['accumulate'] === BooleanType::YES ? 't' : 'f',
172                 ));
173                 // Chave Primária
174                 $data['id'] = (int) $tbAccounts->getLastInsertValue();
175             }
176             // Finalização
177             $connection->commit();
178         } catch (Exception $e) {
179             // Erro Encontrado
180             $connection->rollback();
181             // Apresentar Erro
182             throw new ModelException('Database Error', null, $e);
183         }
184         // Encadeamento
185         return $this;
186     }
187 
188     /**
189      * {@inheritdoc}
190      */
191     public function remove(Parameters $params)
192     {
193         // Chave Primária?
194         if (! $params['id']) {
195             throw new ModelException('Unknown Primary Key');
196         }
197         // Inicialização
198         $db         = $this->getServiceLocator()->get('db');
199         $tbAccounts = $this->getServiceLocator()->get('Balance\Db\TableGateway\Accounts');
200         $connection = $db->getDriver()->getConnection();
201         // Tratamento
202         try {
203             // Transação
204             $connection->beginTransaction();
205             // Seletor
206             $select = (new Select())
207                 ->from(array('a' => 'accounts'))
208                 ->columns(array('position'))
209                 ->where(function ($where) use ($params) {
210                     $where->equalTo('a.id', $params['id']);
211                 });
212             // Consultar Posição
213             $row = $db->query($select->getSqlString($db->getPlatform()))->execute()->current();
214             // Encontrado?
215             if (! $row) {
216                 throw new ModelException('Unknown Element');
217             }
218             // Remover Elemento
219             $tbAccounts->delete(function ($delete) use ($params) {
220                 $delete->where(function ($where) use ($params) {
221                     $where->equalTo('id', $params['id']);
222                 });
223             });
224             // Reordenar Contas
225             $tbAccounts->update(array(
226                 'position' => new Expression('"position" - 1'),
227             ), function ($where) use ($row) {
228                 $where->greaterThan('position', $row['position']);
229             });
230             // Confirmação
231             $connection->commit();
232         } catch (Exception $e) {
233             // Retorno
234             $connection->rollback();
235             // Apresentar Erro
236             throw new ModelException('Database Error', null, $e);
237         }
238         // Encadeamento
239         return $this;
240     }
241 
242     /**
243      * {@inheritdoc}
244      */
245     public function getValueOptions()
246     {
247         // Definições de Nomeclatura
248         $definition = (new AccountType())->getDefinition();
249         // Resultado Inicial
250         $result = array(
251             AccountType::ACTIVE  => array(
252                 'label'   => $definition[AccountType::ACTIVE],
253                 'options' => array(),
254             ),
255             AccountType::PASSIVE => array(
256                 'label'   => $definition[AccountType::PASSIVE],
257                 'options' => array(),
258             ),
259         );
260         // Adaptador de Banco de Dados
261         $db = $this->getServiceLocator()->get('db');
262         // Seletor
263         $select = (new Select())
264             ->from(array('a' => 'accounts'))
265             ->columns(array('id', 'type', 'name'))
266             ->order(array('a.type', 'a.name'));
267         // Consulta
268         $rowset = $db->query($select->getSqlString($db->getPlatform()))->execute();
269         // Captura
270         foreach ($rowset as $row) {
271             $result[$row['type']]['options'][$row['id']] = $row['name'];
272         }
273         // Remover Conjuntos Vazios
274         foreach ($result as $identifier => $container) {
275             if (! $container['options']) {
276                 unset($result[$identifier]);
277             }
278         }
279         // Limpeza de Chaves no Primeiro Nível
280         $result = array_values($result);
281         // Apresentação
282         return $result;
283     }
284 
285     /**
286      * Captura de Posição
287      *
288      * @param  int            $id Chave Primária
289      * @throws ModelException Elemento não Encontrado
290      * @return int            Posição Encontrada
291      */
292     private function getPosition($id)
293     {
294         // Inicialização
295         $db = $this->getServiceLocator()->get('db');
296         // Capturador de Posições
297         $select = (new Select())
298             ->from(array('a' => 'accounts'))
299             ->columns(array('position'))
300             ->where(function ($where) use ($id) {
301                 $where->equalTo('a.id', $id);
302             });
303         // Consulta
304         $row = $db->query($select->getSqlString($db->getPlatform()))->execute()->current();
305         // Encontrado?
306         if (! $row) {
307             throw new ModelException('Unknown Element');
308         }
309         // Apresentar Posição
310         return (int) $row['position'];
311     }
312 
313     /**
314      * Ordenar Elementos
315      *
316      * @param  Parameters $params Parâmetros de Execução
317      * @return Accounts   Próprio Objeto para Encadeamento
318      */
319     public function order(Parameters $params)
320     {
321         // Inicialização
322         $id       = (int) $params['id'];
323         $previous = (int) $params['previous'];
324 
325         // Inicialização
326         $tbAccounts = $this->getServiceLocator()->get('Balance\Db\TableGateway\Accounts');
327         $db         = $this->getServiceLocator()->get('db');
328         $connection = $db->getDriver()->getConnection();
329 
330         // Capturar Posição do Elemento
331         $positionBefore = $this->getPosition($id);
332         $positionAfter  = -1;
333 
334         // Elemento Anterior Enviado?
335         if ($previous) {
336             // Capturar Elemento
337             $positionAfter = $this->getPosition($previous);
338         }
339 
340         // Mesma Posição?
341         if ($positionBefore === $positionAfter) {
342             // Encadeamento
343             return $this;
344         }
345 
346         // Posição Anterior Maior que Posição Posterior?
347         if ($positionBefore > $positionAfter) {
348             // Posição Posterior é de Elemento que não Participa do Intervalo que Modifica Posição
349             $positionAfter = $positionAfter + 1;
350         }
351 
352         // Tratamento
353         try {
354             // Transação
355             $connection->beginTransaction();
356 
357             // Parâmetros (Antes === Depois) Não Existe Aqui!
358             $parameters = array($positionBefore, $positionAfter, ($positionBefore < $positionAfter ? '-1' : '+1'));
359             // Expressão
360             $expression = new Expression('(CASE WHEN "position" = ? THEN ? ELSE "position" + ? END)', $parameters);
361 
362             // Atualização para Frente
363             $tbAccounts->update(array(
364                 'position' => $expression,
365             ), function ($where) use ($positionBefore, $positionAfter) {
366                 $where->between(
367                     'position',
368                     min($positionBefore, $positionAfter),
369                     max($positionBefore, $positionAfter)
370                 );
371             });
372 
373             // Finalização
374             $connection->commit();
375         } catch (Exception $e) {
376             // Erro Encontrado
377             $connection->rollback();
378             // Apresentar Erro
379             throw new ModelException('Database Error', null, $e);
380         }
381 
382         // Encadeamento
383         return $this;
384     }
385 }
386 
Balance API documentation generated by ApiGen