Hej,
Wyodrębniliśmy z frameworka http://ouzoframework.org najciekawsze funkcjonalności. Dla tych, którzy nie chcą migrować całego projektu (MVC i ORM-a) na Ouzo, teraz wystarczy tylko dodać zależność do Ouzo Goodies i używać m.in. płynnych asercji, mockowania, extractora i wielu innych przydatnych utili.
Więcej na:
https://github.com/letsdrink/ouzo-goodies
Kilka przykładów:
http://ouzo.readthedocs.org/en/latest/utils/fluent_array.html:
$result = FluentArray::from($users) ->map(Functions::extractField('name')) ->filter(Functions::notEmpty()) ->unique() ->toArray();
$product = new Product(['name' => 'super phone']); $function = FluentFunctions::extractField('name') ->removePrefix('super') ->prepend(' extra') ->append('! ') ->surroundWith("***"); $result = Functions::call($function, $product); //=> '*** extra phone! ***'
$cities = Arrays::map($users, Functions::http://www.php.net/extract()->getAddress('home')->city);
$string = Clock::now() ->plusYears(1) ->plusMonths(2) ->minusDays(3) ->format();
$product1 = new Product(['name' => 'b']); $product2 = new Product(['name' => 'c']); $product3 = new Product(['name' => 'a']); $result = Arrays::http://www.php.net/sort([$product1, $product2, $product3], Comparator::compareBy('name'));
$animals = ['cat', 'dog', 'pig']; http://www.php.net/assert::thatArray($animals)->hasSize(3)->contains('cat');
http://www.php.net/assert::thatString("Frodo") ->startsWith("Fro") ->endsWith("do") ->contains("rod") ->doesNotContain("fro") ->hasSize(5);
$mock = Mock::mock(); Mock::when($mock)->someMethod('arg')->thenReturn('result'); $result = $mock->someMethod('arg'); $this->assertEquals("result", $result);
Cały czas dodajemy nowe funkcjonalności. Oprócz mocków mamy również asercje wzorowane na https://code.google.com/p/fest/.
http://ouzo.readthedocs.org/en/latest/documentation/tests.html#array-assertions:
$animals = ['cat', 'dog', 'pig']; http://www.php.net/assert::thatArray($animals)->hasSize(3)->contains('cat');
http://www.php.net/assert::thatString("Frodo") ->startsWith("Fro")->endsWith("do") ->hasSize(5);
$foo = new Foo(); CatchException::when($foo)->method(); CatchException::assertThat()->isInstanceOf("FooException");
Mam pytanie - jakie to ma praktyczne zastosowanie? Na podstawie przykładów nie widzę, gdzie by mi się to mogło przydać. Może dlatego, że na codzień korzystam z ZF1 i ZF2.
@b4rt3kk wydawało mi się, że przykłady są self-explanatory
Natomiast bardzo chętnie mogę Ci pokazać, gdzie mógłbyś tego użyć, jeśli wkleisz jakiś swój kod np. test jednostkowy gdzie testujesz coś na arrayach. ZF1/2 nie powinien być przeszkodą.
<?php namespace Extensions; /** * Klasa słownika. * * Mapowanie słownikowe dla wiersza * source - źródło * idField - szukany klucz * where - warunki początkowe * nameFields - wartości, które chcemy pobrać * separator - separator pobranych wartości */ class Dictionary { protected $serviceMenager; /** * Warunek where dla zapytania * * @var \Zend\Db\Sql\Where */ protected $where; protected $model; /** * Zapytanie * * @var \Zend\Db\Sql\Select */ protected $select; protected $nameFields; protected $separator; protected $idField; /** * Potraktuj zmienną source jako id słownika * * @var boolean */ protected $sourceAsId; public function __construct($serviceMenager, $sourceAsId = false) { $this->serviceMenager = $serviceMenager; $this->where = new \Zend\Db\Sql\Where(); $this->select = new \Zend\Db\Sql\Select(); $this->sourceAsId = $sourceAsId; } public function setSource($source, $id = 'order', $where = http://www.php.net/array('ghost IS NOT TRUE'), $nameFields = http://www.php.net/array(), $separator = ' ') { // ustaw separator dla pobranych wartości $this->separator = $separator; $this->idField = $id; if (class_exists($source)) { // źródłem wyszukiwania jest tabela $this->model = $this->serviceMenager->get($source); $this->nameFields = $nameFields; } else { // źródłem wyszukiwania jest słownik $this->model = $this->serviceMenager->get('Application\Model\DictionaryEntryTable'); // znajdź id słownika dla podanego klucza $modelDictionary = $this->serviceMenager->get('Application\Model\DictionaryTable'); // pobierz włączony język $locale = $this->serviceMenager->get('translator'); $lang = $locale->getTranslator()->getLocale(); $key = ($this->sourceAsId === true ? 'id' : 'symbol'); $rowDictionary = $modelDictionary->fetchAll(http://www.php.net/array($key => $source, 'ghost IS NOT TRUE', 'language' => $lang))->current(); if ($rowDictionary !== false) { $this->where->equalTo('id_dictionary', $rowDictionary->id); } else { // klucz słownika nie istnieje $this->where->literal('false'); } $this->nameFields = http://www.php.net/array('entry'); } // uwzględnienie warunków where if (http://www.php.net/sizeof($where) > 0) { foreach ($where as $key => $condition) { if (!http://www.php.net/is_numeric($key)) { $this->where->equalTo($key, $condition); } else { $this->where->literal($condition); } } } $tableIdentifier = $this->model->getTableGateway()->getTable(); $this->select->from($tableIdentifier); $this->select->where($this->where); return $this; } public function getDictionary() { $data = $this->model->fetchSelect($this->select); $dictionary = http://www.php.net/array(); if (http://www.php.net/sizeof($data) > 0) { foreach ($data as $row) { $field = ''; foreach ($this->nameFields as $name) { $field .= $row->{$name} . $this->separator; } $dictionary[$row->{$this->idField}] = http://www.php.net/rtrim($field, $this->separator); } } return $dictionary; } }
Mógłbyś jeszcze wkleić klasy DictionaryTable i DictionaryEntryTable?
<?php namespace Application\Model; use Zend\Db\TableGateway\TableGateway; class DictionaryEntryTable extends \Extensions\Model implements \Extensions\Interfaces\Model { protected $sequence = "public.dictionary_entry_id_seq"; public function __construct(TableGateway $tableGateway) { parent::__construct($tableGateway); } public function getTable() { return new DictionaryEntry(); } public function addRow(DictionaryEntry $table) { return parent::addRow($table); } }
Hmm, zajrzałem i musze przyznać, ze całkiem fajne i chyba wykorzystam, podobaja mi sie fluent i assercje.
<?php namespace Extensions; use Zend\Db\TableGateway\TableGateway; class Model { protected $tableGateway; /** * Sekwencja dla danego modelu (musi być określona w klasie dziedziczącej) * * @var string */ protected $sequence = null; /** * Nazwa klucza głównego tabeli (domyślnie id) * * @var string */ protected $primary_key = 'id'; public function __construct(TableGateway $tableGateway) { $this->tableGateway = $tableGateway; } public function getConnection() { return $this->tableGateway->getAdapter()->getDriver()->getConnection(); } public function fetchAll($where = null) { $resultSet = $this->tableGateway->select($where); return $resultSet; } public function fetchSelect($select) { $resultSet = $this->tableGateway->selectWith($select); return $resultSet; } public function addRow($table, $skipNull = true) { $cols = http://www.php.net/array_keys(get_object_vars($table)); $data = http://www.php.net/array(); foreach ($cols as $col) { if ($skipNull AND $table->{$col} === null AND $col !== 'id') { continue; } $data[$col] = $table->{$col}; } if (http://www.php.net/empty($data['id'])) { // pobranie kolejnej wartości dla sekwencji if ($this->sequence === null) { throw new Exception('Nie podano nazwy sekwencji dla tej tabeli, mimo iż zawiera klucz główny.'); } $connection = $this->getConnection(); $sql = "SELECT nextval('{$this->sequence}') nextval"; $seq = $connection->execute($sql)->current(); $data['id'] = $seq['nextval']; } $this->tableGateway->insert($data); return (http://www.php.net/empty($data['id']) ? null : $data['id']); } public function update($data, $where) { $this->tableGateway->update($data, $where); } public function findOne($primary_key) { if (http://www.php.net/empty($this->primary_key)) { throw new Exception('Tabela nie posiada określonego klucza głównego.'); } $row = false; if (!http://www.php.net/empty($primary_key)) { $resultSet = $this->tableGateway->select(http://www.php.net/array($this->primary_key => $primary_key)); $row = $resultSet->current(); } return $row; } public function getTableGateway() { return $this->tableGateway; } }
To tak na szybko przerobiłem metodę getDictionary (nie uruchamiałem, więc mogą być błędy):
public function getDictionary() { $data = $this->model->fetchSelect($this->select); return Arrays::toMap($data, Functions::extractField($this->idField), $this->joinFilteredValues()); } private function joinFilteredValues() { return function($row) { $values = Arrays::filterByAllowedKeys(get_object_vars($row), $this->nameFields); return http://www.php.net/implode($this->separator, $values); }; }
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)