Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Ouzo Goodies
askalon
post 30.12.2014, 14:08:30
Post #1





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 30.12.2014

Ostrzeżenie: (0%)
-----


Hej,

Wyodrębniliśmy z frameworka Ouzo 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:

Fluent arrays:
  1. $result = FluentArray::from($users)
  2. ->map(Functions::extractField('name'))
  3. ->filter(Functions::notEmpty())
  4. ->unique()
  5. ->toArray();


Fluent functions:
  1. $product = new Product(['name' => 'super phone']);
  2.  
  3. $function = FluentFunctions::extractField('name')
  4. ->removePrefix('super')
  5. ->prepend(' extra')
  6. ->append('! ')
  7. ->surroundWith("***");
  8.  
  9. $result = Functions::call($function, $product); //=> '*** extra phone! ***'


Extract (from Functions):
  1. $cities = Arrays::map($users, Functions::extract()->getAddress('home')->city);


Clock:
  1. $string = Clock::now()
  2. ->plusYears(1)
  3. ->plusMonths(2)
  4. ->minusDays(3)
  5. ->format();


Comparators:
  1. $product1 = new Product(['name' => 'b']);
  2. $product2 = new Product(['name' => 'c']);
  3. $product3 = new Product(['name' => 'a']);
  4.  
  5. $result = Arrays::sort([$product1, $product2, $product3], Comparator::compareBy('name'));


Fluent assertions for arrays:
  1. $animals = ['cat', 'dog', 'pig'];
  2. Assert::thatArray($animals)->hasSize(3)->contains('cat');


Fluent assertions for strings:
  1. Assert::thatString("Frodo")
  2. ->startsWith("Fro")
  3. ->endsWith("do")
  4. ->contains("rod")
  5. ->doesNotContain("fro")
  6. ->hasSize(5);


Mocking:
  1. $mock = Mock::mock();
  2. Mock::when($mock)->someMethod('arg')->thenReturn('result');
  3.  
  4. $result = $mock->someMethod('arg');
  5.  
  6. $this->assertEquals("result", $result);


Zapraszamy do korzystania i czekamy na konstruktywny feedback smile.gif

Ten post edytował askalon 30.12.2014, 14:09:55
Go to the top of the page
+Quote Post
piotrooo89
post 9.01.2015, 20:13:00
Post #2


Newsman


Grupa: Moderatorzy
Postów: 4 005
Pomógł: 548
Dołączył: 7.04.2008
Skąd: Trzebinia/Kraków




Cały czas dodajemy nowe funkcjonalności. Oprócz mocków mamy również asercje wzorowane na fest asserts.

Array assertions:

  1. $animals = ['cat', 'dog', 'pig'];
  2. Assert::thatArray($animals)->hasSize(3)->contains('cat');


String assertions:

  1. Assert::thatString("Frodo")
  2. ->startsWith("Fro")->endsWith("do")
  3. ->hasSize(5);


Exception assertions:

  1. $foo = new Foo();
  2. CatchException::when($foo)->method();
  3. CatchException::assertThat()->isInstanceOf("FooException");


Zapraszamy smile.gif


--------------------
Go to the top of the page
+Quote Post
b4rt3kk
post 15.01.2015, 10:05:10
Post #3





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


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.


--------------------
Jeśli pomogłem, kliknij proszę 'pomógł'. Dzięki.
Go to the top of the page
+Quote Post
askalon
post 15.01.2015, 10:19:56
Post #4





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 30.12.2014

Ostrzeżenie: (0%)
-----


@b4rt3kk wydawało mi się, że przykłady są self-explanatory smile.gif

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ą.
Go to the top of the page
+Quote Post
b4rt3kk
post 15.01.2015, 10:37:10
Post #5





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Cytat(askalon @ 15.01.2015, 10:19:56 ) *
@b4rt3kk wydawało mi się, że przykłady są self-explanatory smile.gif

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ą.


Hmm, może lepiej przedstawie coś nad czym ostatnio pracuję i mi powiesz, czy można to tutaj jakoś zastosować? smile.gif

  1. <?php
  2. namespace Extensions;
  3.  
  4. /**
  5.  * Klasa słownika.
  6.  *
  7.  * Mapowanie słownikowe dla wiersza
  8.  * source - źródło
  9.  * idField - szukany klucz
  10.  * where - warunki początkowe
  11.  * nameFields - wartości, które chcemy pobrać
  12.  * separator - separator pobranych wartości
  13.  */
  14. class Dictionary {
  15.  
  16. protected $serviceMenager;
  17. /**
  18.   * Warunek where dla zapytania
  19.   *
  20.   * @var \Zend\Db\Sql\Where
  21.   */
  22. protected $where;
  23. protected $model;
  24. /**
  25.   * Zapytanie
  26.   *
  27.   * @var \Zend\Db\Sql\Select
  28.   */
  29. protected $select;
  30.  
  31. protected $nameFields;
  32. protected $separator;
  33. protected $idField;
  34. /**
  35.   * Potraktuj zmienną source jako id słownika
  36.   *
  37.   * @var boolean
  38.   */
  39. protected $sourceAsId;
  40.  
  41. public function __construct($serviceMenager, $sourceAsId = false)
  42. {
  43. $this->serviceMenager = $serviceMenager;
  44. $this->where = new \Zend\Db\Sql\Where();
  45. $this->select = new \Zend\Db\Sql\Select();
  46. $this->sourceAsId = $sourceAsId;
  47. }
  48.  
  49. public function setSource($source, $id = 'order', $where = array('ghost IS NOT TRUE'), $nameFields = array(), $separator = ' ')
  50. {
  51. // ustaw separator dla pobranych wartości
  52. $this->separator = $separator;
  53. $this->idField = $id;
  54.  
  55. if (class_exists($source)) {
  56. // źródłem wyszukiwania jest tabela
  57. $this->model = $this->serviceMenager->get($source);
  58. $this->nameFields = $nameFields;
  59. } else {
  60. // źródłem wyszukiwania jest słownik
  61. $this->model = $this->serviceMenager->get('Application\Model\DictionaryEntryTable');
  62. // znajdź id słownika dla podanego klucza
  63. $modelDictionary = $this->serviceMenager->get('Application\Model\DictionaryTable');
  64. // pobierz włączony język
  65. $locale = $this->serviceMenager->get('translator');
  66. $lang = $locale->getTranslator()->getLocale();
  67. $key = ($this->sourceAsId === true ? 'id' : 'symbol');
  68. $rowDictionary = $modelDictionary->fetchAll(array($key => $source, 'ghost IS NOT TRUE', 'language' => $lang))->current();
  69.  
  70. if ($rowDictionary !== false) {
  71. $this->where->equalTo('id_dictionary', $rowDictionary->id);
  72. } else {
  73. // klucz słownika nie istnieje
  74. $this->where->literal('false');
  75. }
  76.  
  77. $this->nameFields = array('entry');
  78. }
  79.  
  80. // uwzględnienie warunków where
  81. if (sizeof($where) > 0) {
  82. foreach ($where as $key => $condition) {
  83. if (!is_numeric($key)) {
  84. $this->where->equalTo($key, $condition);
  85. } else {
  86. $this->where->literal($condition);
  87. }
  88. }
  89. }
  90.  
  91. $tableIdentifier = $this->model->getTableGateway()->getTable();
  92. $this->select->from($tableIdentifier);
  93. $this->select->where($this->where);
  94.  
  95. return $this;
  96. }
  97.  
  98. public function getDictionary()
  99. {
  100. $data = $this->model->fetchSelect($this->select);
  101. $dictionary = array();
  102.  
  103. if (sizeof($data) > 0) {
  104. foreach ($data as $row) {
  105. $field = '';
  106. foreach ($this->nameFields as $name) {
  107. $field .= $row->{$name} . $this->separator;
  108. }
  109.  
  110. $dictionary[$row->{$this->idField}] = rtrim($field, $this->separator);
  111. }
  112. }
  113.  
  114. return $dictionary;
  115. }
  116.  
  117. }


--------------------
Jeśli pomogłem, kliknij proszę 'pomógł'. Dzięki.
Go to the top of the page
+Quote Post
askalon
post 15.01.2015, 10:53:19
Post #6





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 30.12.2014

Ostrzeżenie: (0%)
-----


Mógłbyś jeszcze wkleić klasy DictionaryTable i DictionaryEntryTable?
Go to the top of the page
+Quote Post
b4rt3kk
post 15.01.2015, 11:07:43
Post #7





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Cytat(askalon @ 15.01.2015, 10:53:19 ) *
Mógłbyś jeszcze wkleić klasy DictionaryTable i DictionaryEntryTable?


W zasadzie są to tylko zwykłe modele, oba wyglądają niemal identycznie, różnią się tylko sekwencją i nazwą:

  1. <?php
  2. namespace Application\Model;
  3.  
  4. use Zend\Db\TableGateway\TableGateway;
  5.  
  6. class DictionaryEntryTable extends \Extensions\Model implements \Extensions\Interfaces\Model
  7. {
  8. protected $sequence = "public.dictionary_entry_id_seq";
  9.  
  10. public function __construct(TableGateway $tableGateway)
  11. {
  12. parent::__construct($tableGateway);
  13. }
  14.  
  15. public function getTable()
  16. {
  17. return new DictionaryEntry();
  18. }
  19.  
  20. public function addRow(DictionaryEntry $table)
  21. {
  22. return parent::addRow($table);
  23. }
  24.  
  25. }


--------------------
Jeśli pomogłem, kliknij proszę 'pomógł'. Dzięki.
Go to the top of the page
+Quote Post
cepa
post 15.01.2015, 11:13:15
Post #8





Grupa: Zarejestrowani
Postów: 125
Pomógł: 7
Dołączył: 27.01.2010

Ostrzeżenie: (0%)
-----


Hmm, zajrzałem i musze przyznać, ze całkiem fajne i chyba wykorzystam, podobaja mi sie fluent i assercje.


--------------------
Go to the top of the page
+Quote Post
askalon
post 15.01.2015, 12:00:45
Post #9





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 30.12.2014

Ostrzeżenie: (0%)
-----


Cytat(b4rt3kk @ 15.01.2015, 11:07:43 ) *
W zasadzie są to tylko zwykłe modele, oba wyglądają niemal identycznie, różnią się tylko sekwencją i nazwą (...)


No to w takim razie bardziej potrzebowałbym zobaczyć klasę Model, bo w tych rzeczywiście nie ma "mięsa" smile.gif
Go to the top of the page
+Quote Post
b4rt3kk
post 15.01.2015, 12:23:10
Post #10





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


Cytat(askalon @ 15.01.2015, 12:00:45 ) *
No to w takim razie bardziej potrzebowałbym zobaczyć klasę Model, bo w tych rzeczywiście nie ma "mięsa" smile.gif


Proszę, klasa modelu. smile.gif

  1. <?php
  2.  
  3. namespace Extensions;
  4. use Zend\Db\TableGateway\TableGateway;
  5.  
  6. class Model {
  7.  
  8. protected $tableGateway;
  9.  
  10. /**
  11.   * Sekwencja dla danego modelu (musi być określona w klasie dziedziczącej)
  12.   *
  13.   * @var string
  14.   */
  15. protected $sequence = null;
  16.  
  17. /**
  18.   * Nazwa klucza głównego tabeli (domyślnie id)
  19.   *
  20.   * @var string
  21.   */
  22. protected $primary_key = 'id';
  23.  
  24. public function __construct(TableGateway $tableGateway)
  25. {
  26. $this->tableGateway = $tableGateway;
  27. }
  28.  
  29. public function getConnection()
  30. {
  31. return $this->tableGateway->getAdapter()->getDriver()->getConnection();
  32. }
  33.  
  34. public function fetchAll($where = null)
  35. {
  36. $resultSet = $this->tableGateway->select($where);
  37.  
  38. return $resultSet;
  39. }
  40.  
  41. public function fetchSelect($select)
  42. {
  43. $resultSet = $this->tableGateway->selectWith($select);
  44.  
  45. return $resultSet;
  46. }
  47.  
  48. public function addRow($table, $skipNull = true)
  49. {
  50. $cols = array_keys(get_object_vars($table));
  51. $data = array();
  52.  
  53. foreach ($cols as $col) {
  54. if ($skipNull AND $table->{$col} === null AND $col !== 'id') {
  55. continue;
  56. }
  57. $data[$col] = $table->{$col};
  58. }
  59.  
  60. if (empty($data['id'])) {
  61. // pobranie kolejnej wartości dla sekwencji
  62. if ($this->sequence === null) {
  63. throw new Exception('Nie podano nazwy sekwencji dla tej tabeli, mimo iż zawiera klucz główny.');
  64. }
  65.  
  66. $connection = $this->getConnection();
  67. $sql = "SELECT nextval('{$this->sequence}') nextval";
  68. $seq = $connection->execute($sql)->current();
  69.  
  70. $data['id'] = $seq['nextval'];
  71. }
  72.  
  73. $this->tableGateway->insert($data);
  74.  
  75. return (empty($data['id']) ? null : $data['id']);
  76. }
  77.  
  78. public function update($data, $where)
  79. {
  80. $this->tableGateway->update($data, $where);
  81. }
  82.  
  83. public function findOne($primary_key)
  84. {
  85. if (empty($this->primary_key)) {
  86. throw new Exception('Tabela nie posiada określonego klucza głównego.');
  87. }
  88.  
  89. $row = false;
  90.  
  91. if (!empty($primary_key)) {
  92. $resultSet = $this->tableGateway->select(array($this->primary_key => $primary_key));
  93. $row = $resultSet->current();
  94. }
  95.  
  96. return $row;
  97. }
  98.  
  99. public function getTableGateway()
  100. {
  101. return $this->tableGateway;
  102. }
  103.  
  104. }


--------------------
Jeśli pomogłem, kliknij proszę 'pomógł'. Dzięki.
Go to the top of the page
+Quote Post
askalon
post 15.01.2015, 17:09:36
Post #11





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 30.12.2014

Ostrzeżenie: (0%)
-----


To tak na szybko przerobiłem metodę getDictionary (nie uruchamiałem, więc mogą być błędy):

  1. public function getDictionary()
  2. {
  3. $data = $this->model->fetchSelect($this->select);
  4. return Arrays::toMap($data, Functions::extractField($this->idField), $this->joinFilteredValues());
  5. }
  6.  
  7. private function joinFilteredValues()
  8. {
  9. return function($row) {
  10. $values = Arrays::filterByAllowedKeys(get_object_vars($row), $this->nameFields);
  11. return implode($this->separator, $values);
  12. };
  13. }

Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.04.2024 - 16:15