From a7639d8137393103e8410b84e670e4f8e0d9ee27 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Mon, 13 Feb 2017 15:48:33 +0100 Subject: [PATCH 01/53] :memo: README title --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de9a808..135a1e3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# search +# Search Basic extensions for searching in WordPress. From 0c871744129170744e7b4bf822fdd068b34ef4c2 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Mon, 13 Feb 2017 16:40:33 +0100 Subject: [PATCH 02/53] =?UTF-8?q?=F0=9F=9A=A7=20Base=20class=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimensions.php | 6 ++++++ src/Hook/Posts.php | 35 +++++++++++++++++++++++++++++++++++ src/Search.php | 22 ++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/Dimension/Dimensions.php create mode 100644 src/Hook/Posts.php create mode 100644 src/Search.php diff --git a/src/Dimension/Dimensions.php b/src/Dimension/Dimensions.php new file mode 100644 index 0000000..6a7b532 --- /dev/null +++ b/src/Dimension/Dimensions.php @@ -0,0 +1,6 @@ +dimensions = $dimensions; + $this->wpdb = $wpdb; + } + + public function init() + { + $acceptedArgs = 2; + $defaultPriority = 10; + + add_filter('posts_join', [$this, 'join'], $defaultPriority, $acceptedArgs); + add_filter('posts_search', [$this, 'search'], $defaultPriority, $acceptedArgs); + } + + public function join($sql, $query) + { + return $sql; + } + + public function search($sql, $query) + { + return $sql; + } +} diff --git a/src/Search.php b/src/Search.php new file mode 100644 index 0000000..58c008e --- /dev/null +++ b/src/Search.php @@ -0,0 +1,22 @@ +dimensions = new Dimensions(); + $this->postsHook = new Posts($wpdb, $this->dimensions); + } + + public function init() + { + $this->postsHook->init(); + } +} From ce57d6cf8c953edd760e6eff532c07302ee234b2 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Mon, 13 Feb 2017 16:42:42 +0100 Subject: [PATCH 03/53] =?UTF-8?q?=F0=9F=9A=A7=20Introduce=20dimension=20co?= =?UTF-8?q?llection=20with=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimension.php | 6 ++++++ src/Dimension/Dimensions.php | 5 +++++ src/Search.php | 6 ++++++ 3 files changed, 17 insertions(+) create mode 100644 src/Dimension/Dimension.php diff --git a/src/Dimension/Dimension.php b/src/Dimension/Dimension.php new file mode 100644 index 0000000..518bb6b --- /dev/null +++ b/src/Dimension/Dimension.php @@ -0,0 +1,6 @@ +dimensions[] = $dimension; + } } diff --git a/src/Search.php b/src/Search.php index 58c008e..39da34a 100644 --- a/src/Search.php +++ b/src/Search.php @@ -1,6 +1,7 @@ postsHook->init(); } + + public function addDimension(Dimension $dimension) + { + $this->dimensions->add($dimension); + } } From 8d8eda2ba0cc42bed9e5b50235643d8d67e59e5e Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Mon, 13 Feb 2017 16:53:44 +0100 Subject: [PATCH 04/53] =?UTF-8?q?=E2=9C=A8=20Introduce=20concrete=20class?= =?UTF-8?q?=20Meta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimension.php | 1 + src/Dimension/Dimensions.php | 5 +++++ src/Dimension/Meta.php | 8 ++++++++ 3 files changed, 14 insertions(+) create mode 100644 src/Dimension/Meta.php diff --git a/src/Dimension/Dimension.php b/src/Dimension/Dimension.php index 518bb6b..cc2031a 100644 --- a/src/Dimension/Dimension.php +++ b/src/Dimension/Dimension.php @@ -3,4 +3,5 @@ interface Dimension { + public function join(); } diff --git a/src/Dimension/Dimensions.php b/src/Dimension/Dimensions.php index a5d8072..17dc00b 100644 --- a/src/Dimension/Dimensions.php +++ b/src/Dimension/Dimensions.php @@ -8,4 +8,9 @@ final class Dimensions public function add(Dimension $dimension) { $this->dimensions[] = $dimension; } + + public function get() + { + return $this->dimensions; + } } diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php new file mode 100644 index 0000000..69bfc00 --- /dev/null +++ b/src/Dimension/Meta.php @@ -0,0 +1,8 @@ + Date: Tue, 14 Feb 2017 13:33:24 +0100 Subject: [PATCH 05/53] :rotating_light: PSR --- src/Dimension/Dimensions.php | 3 ++- src/Dimension/Meta.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Dimension/Dimensions.php b/src/Dimension/Dimensions.php index 17dc00b..ec99b20 100644 --- a/src/Dimension/Dimensions.php +++ b/src/Dimension/Dimensions.php @@ -5,7 +5,8 @@ final class Dimensions { private $dimensions = []; - public function add(Dimension $dimension) { + public function add(Dimension $dimension) + { $this->dimensions[] = $dimension; } diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 69bfc00..97d1a36 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -3,6 +3,7 @@ final class Meta implements Dimension { - public function join() { + public function join() + { } } From 2c063540ce0f0812f132ec2abaa4e9bf95783979 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Tue, 14 Feb 2017 14:05:36 +0100 Subject: [PATCH 06/53] =?UTF-8?q?=F0=9F=9A=A7=20Join=20clause=20+=20Type?= =?UTF-8?q?=20hinting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimension.php | 4 +++- src/Dimension/Meta.php | 8 +++++++- src/Hook/Posts.php | 31 +++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/Dimension/Dimension.php b/src/Dimension/Dimension.php index cc2031a..759fb9d 100644 --- a/src/Dimension/Dimension.php +++ b/src/Dimension/Dimension.php @@ -1,7 +1,9 @@ postmeta . ' AS ' . $this->tableAlias . + ' ON (' . $wpdb->posts . '.ID = ' . $this->tableAlias . '.post_id)'; } } diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index 8fb1a50..6830cf7 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -1,6 +1,9 @@ dimensions = $dimensions; $this->wpdb = $wpdb; @@ -23,13 +26,33 @@ public function init() add_filter('posts_search', [$this, 'search'], $defaultPriority, $acceptedArgs); } - public function join($sql, $query) + public function join($sql, WP_Query $query) { - return $sql; + if (! $query->is_search) { + return $sql; + } + + $joins = $this->forDimensions(function (Dimension $dimension) { + return $dimension->join($this->wpdb); + }); + + return $sql . ' ' . implode(' ', $joins); } - public function search($sql, $query) + public function search($sql, WP_Query $query) { return $sql; } + + private function forDimensions($callback) + { + $results = []; + + foreach ($this->dimensions->get() as $dimension) { + $dimensionType = get_class($dimension); + $results[$dimensionType] = $callback($dimension); + } + + return array_values($results); + } } From 455de6c35f8b580b0b1070b489df7a6738313e05 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Tue, 14 Feb 2017 16:30:18 +0100 Subject: [PATCH 07/53] =?UTF-8?q?=F0=9F=9A=A7=20Dimension->search()=20for?= =?UTF-8?q?=20Meta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimension.php | 2 ++ src/Dimension/Meta.php | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Dimension/Dimension.php b/src/Dimension/Dimension.php index 759fb9d..820c121 100644 --- a/src/Dimension/Dimension.php +++ b/src/Dimension/Dimension.php @@ -5,5 +5,7 @@ interface Dimension { + public function __construct(array $options); public function join(wpdb $wpdb); + public function search(wpdb $wpdb, array $words); } diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 1530eab..d1c1a08 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -1,15 +1,32 @@ options = $options; + } + public function join(wpdb $wpdb) { return 'INNER JOIN ' . $wpdb->postmeta . ' AS ' . $this->tableAlias . ' ON (' . $wpdb->posts . '.ID = ' . $this->tableAlias . '.post_id)'; } + + public function search(wpdb $wpdb, array $words) + { + return '(' . $this->tableAlias . '.meta_key = \'' . $this->options['key'] . '\' AND ' . + $this->tableAlias . '.meta_value REGEXP \'' . implode('|', $words) . '\')'; + } } From e3dfcdc24c55ffe17c4f7d243dfdad7e01fa16e1 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Tue, 14 Feb 2017 16:41:52 +0100 Subject: [PATCH 08/53] =?UTF-8?q?=E2=9C=A8=20Search=20meta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Hook/Posts.php | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index 6830cf7..7aad7fe 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -22,37 +22,60 @@ public function init() $acceptedArgs = 2; $defaultPriority = 10; + add_filter('posts_distinct', [$this, 'distinct'], $defaultPriority, $acceptedArgs); add_filter('posts_join', [$this, 'join'], $defaultPriority, $acceptedArgs); add_filter('posts_search', [$this, 'search'], $defaultPriority, $acceptedArgs); } + public function distinct($sql, WP_Query $query) + { + if (! $query->is_search) { + return $sql; + } + + return 'DISTINCT'; + } + public function join($sql, WP_Query $query) { if (! $query->is_search) { return $sql; } - $joins = $this->forDimensions(function (Dimension $dimension) { - return $dimension->join($this->wpdb); - }); + $joins = []; + + foreach ($this->dimensions->get() as $dimension) { + $dimensionType = get_class($dimension); + $joins[$dimensionType] = $dimension->join($this->wpdb); + } return $sql . ' ' . implode(' ', $joins); } public function search($sql, WP_Query $query) { - return $sql; - } + if (! $query->is_search) { + return $sql; + } - private function forDimensions($callback) - { - $results = []; + $searchWords = $query->get('search_terms'); + + $searches = []; foreach ($this->dimensions->get() as $dimension) { - $dimensionType = get_class($dimension); - $results[$dimensionType] = $callback($dimension); + $searches[] = $dimension->search($this->wpdb, $searchWords); + } + + if ($searches) { + $metaSearch = implode(' OR ', $searches); } - return array_values($results); + if ($metaSearch) { + $and = ' AND '; + $sql = preg_replace('/' . $and . '/', $and . '(', $sql, 1); + $sql .= ' OR (' . $metaSearch . '))'; + } + + return $sql; } } From 26ae8836cf1368ea1185a3a5562033b7c034cdbd Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Tue, 14 Feb 2017 16:44:31 +0100 Subject: [PATCH 09/53] =?UTF-8?q?=F0=9F=8E=A8=20Check=20if=20metaSearch=20?= =?UTF-8?q?is=20set=20at=20all?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Hook/Posts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index 7aad7fe..0d61ba9 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -70,7 +70,7 @@ public function search($sql, WP_Query $query) $metaSearch = implode(' OR ', $searches); } - if ($metaSearch) { + if (isset($metaSearch)) { $and = ' AND '; $sql = preg_replace('/' . $and . '/', $and . '(', $sql, 1); $sql .= ' OR (' . $metaSearch . '))'; From 9dfb55dbb455854175024cfcbccaa057ed9a2ea7 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Tue, 14 Feb 2017 18:07:48 +0100 Subject: [PATCH 10/53] =?UTF-8?q?=F0=9F=94=A8=20Support=20proper=20multipl?= =?UTF-8?q?e=20word=20matching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimension.php | 4 ++-- src/Dimension/Meta.php | 16 ++++++++++------ src/Hook/Posts.php | 35 ++++++++++++++++++++--------------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/Dimension/Dimension.php b/src/Dimension/Dimension.php index 820c121..bc1b857 100644 --- a/src/Dimension/Dimension.php +++ b/src/Dimension/Dimension.php @@ -6,6 +6,6 @@ interface Dimension { public function __construct(array $options); - public function join(wpdb $wpdb); - public function search(wpdb $wpdb, array $words); + public function join(wpdb $wpdb, $aliasCount = 0); + public function search(wpdb $wpdb, $searchWord, $aliasCount = 0); } diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index d1c1a08..c2b1e8e 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -18,15 +18,19 @@ public function __construct(array $options) $this->options = $options; } - public function join(wpdb $wpdb) + public function join(wpdb $wpdb, $aliasCount = 0) { - return 'INNER JOIN ' . $wpdb->postmeta . ' AS ' . $this->tableAlias . - ' ON (' . $wpdb->posts . '.ID = ' . $this->tableAlias . '.post_id)'; + $tableAlias = $this->tableAlias . $aliasCount; + + return 'INNER JOIN ' . $wpdb->postmeta . ' AS ' . $tableAlias . + ' ON (' . $wpdb->posts . '.ID = ' . $tableAlias . '.post_id)'; } - public function search(wpdb $wpdb, array $words) + public function search(wpdb $wpdb, $searchWord, $aliasCount = 0) { - return '(' . $this->tableAlias . '.meta_key = \'' . $this->options['key'] . '\' AND ' . - $this->tableAlias . '.meta_value REGEXP \'' . implode('|', $words) . '\')'; + $tableAlias = $this->tableAlias . $aliasCount; + + return '(' . $tableAlias . '.meta_key = \'' . $this->options['key'] . '\' AND ' . + $tableAlias . '.meta_value LIKE \'%' . $searchWord . '%\')'; } } diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index 0d61ba9..e79f76e 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -42,11 +42,15 @@ public function join($sql, WP_Query $query) return $sql; } + $searchWords = $query->get('search_terms'); + $joins = []; - foreach ($this->dimensions->get() as $dimension) { - $dimensionType = get_class($dimension); - $joins[$dimensionType] = $dimension->join($this->wpdb); + foreach ($searchWords as $wordCount => $searchWord) { + foreach ($this->dimensions->get() as $dimension) { + $dimensionType = get_class($dimension); + $joins[$dimensionType . $wordCount] = $dimension->join($this->wpdb, $wordCount); + } } return $sql . ' ' . implode(' ', $joins); @@ -58,24 +62,25 @@ public function search($sql, WP_Query $query) return $sql; } + $and = ' AND '; + $or = ' OR '; + $searchWords = $query->get('search_terms'); + $andClauses = array_values(array_filter(explode($and, $sql))); - $searches = []; + foreach ($andClauses as $index => &$clause) { + $searchWord = $searchWords[$index]; + $searches = []; - foreach ($this->dimensions->get() as $dimension) { - $searches[] = $dimension->search($this->wpdb, $searchWords); - } + foreach ($this->dimensions->get() as $dimension) { + $searches[] = $dimension->search($this->wpdb, $searchWord, $index); + } - if ($searches) { - $metaSearch = implode(' OR ', $searches); - } + $search = '(' . implode(' OR ', $searches) . ')' . $or; - if (isset($metaSearch)) { - $and = ' AND '; - $sql = preg_replace('/' . $and . '/', $and . '(', $sql, 1); - $sql .= ' OR (' . $metaSearch . '))'; + $clause = preg_replace('/' . $or . '/', $or . $search, $clause, 1); } - return $sql; + return $and . implode($and, $andClauses); } } From 5d63799eb31dbefa87650386139995b8fb3810e8 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 09:25:58 +0100 Subject: [PATCH 11/53] =?UTF-8?q?=E2=9C=A8=20Compare=20option=20+=20defaul?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index c2b1e8e..a41b759 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -15,7 +15,9 @@ public function __construct(array $options) throw new BadMethodCallException('`key` is a required property.'); } - $this->options = $options; + $this->options = wp_parse_args($options, [ + 'compare' => '=', + ]); } public function join(wpdb $wpdb, $aliasCount = 0) From e2f939177747284e1e9fa27531e526d259c14762 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 09:42:20 +0100 Subject: [PATCH 12/53] =?UTF-8?q?=F0=9F=8E=A8=20Double=20quotes=20and=20br?= =?UTF-8?q?aces=20for=20SQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 10 ++++++---- src/Hook/Posts.php | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index a41b759..6457164 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -24,15 +24,17 @@ public function join(wpdb $wpdb, $aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - return 'INNER JOIN ' . $wpdb->postmeta . ' AS ' . $tableAlias . - ' ON (' . $wpdb->posts . '.ID = ' . $tableAlias . '.post_id)'; + return "INNER JOIN {$wpdb->postmeta} AS {$tableAlias} ON ({$wpdb->posts}.ID = {$tableAlias}.post_id)"; } public function search(wpdb $wpdb, $searchWord, $aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - return '(' . $tableAlias . '.meta_key = \'' . $this->options['key'] . '\' AND ' . - $tableAlias . '.meta_value LIKE \'%' . $searchWord . '%\')'; + $searchSql = "({$tableAlias}.meta_key = '{$this->options['key']}'"; + $searchSql .= " AND "; + $searchSql .= "{$tableAlias}.meta_value LIKE '%{$searchWord}%')"; + + return $searchSql; } } diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index e79f76e..dd3d215 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -33,7 +33,7 @@ public function distinct($sql, WP_Query $query) return $sql; } - return 'DISTINCT'; + return "DISTINCT"; } public function join($sql, WP_Query $query) @@ -62,8 +62,8 @@ public function search($sql, WP_Query $query) return $sql; } - $and = ' AND '; - $or = ' OR '; + $and = " AND "; + $or = " OR "; $searchWords = $query->get('search_terms'); $andClauses = array_values(array_filter(explode($and, $sql))); @@ -76,7 +76,7 @@ public function search($sql, WP_Query $query) $searches[] = $dimension->search($this->wpdb, $searchWord, $index); } - $search = '(' . implode(' OR ', $searches) . ')' . $or; + $search = '(' . implode($or, $searches) . ')' . $or; $clause = preg_replace('/' . $or . '/', $or . $search, $clause, 1); } From 1eaa689f8c0d7832628c7524e9336719529559f7 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 09:44:22 +0100 Subject: [PATCH 13/53] =?UTF-8?q?=E2=9C=A8=20Compare=20key=20LIKE=20suppor?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 6457164..eaf4f6b 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -31,7 +31,12 @@ public function search(wpdb $wpdb, $searchWord, $aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - $searchSql = "({$tableAlias}.meta_key = '{$this->options['key']}'"; + if ($this->options['compare'] == 'LIKE') { + $searchSql = "({$tableAlias}.meta_key LIKE '{$this->options['key']}'"; + } else { + $searchSql = "({$tableAlias}.meta_key = '{$this->options['key']}'"; + } + $searchSql .= " AND "; $searchSql .= "{$tableAlias}.meta_value LIKE '%{$searchWord}%')"; From 611f5081037ff3c46add76f866bbec690da73516 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 09:55:00 +0100 Subject: [PATCH 14/53] =?UTF-8?q?=F0=9F=8E=A8=20Simplify=20compare,=20prep?= =?UTF-8?q?are=20statement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index eaf4f6b..36599a5 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -31,15 +31,10 @@ public function search(wpdb $wpdb, $searchWord, $aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - if ($this->options['compare'] == 'LIKE') { - $searchSql = "({$tableAlias}.meta_key LIKE '{$this->options['key']}'"; - } else { - $searchSql = "({$tableAlias}.meta_key = '{$this->options['key']}'"; - } - + $searchSql = "({$tableAlias}.meta_key {$this->options['compare']} %s"; $searchSql .= " AND "; - $searchSql .= "{$tableAlias}.meta_value LIKE '%{$searchWord}%')"; + $searchSql .= "{$tableAlias}.meta_value LIKE %s)"; - return $searchSql; + return $wpdb->prepare($searchSql, $this->options['key'], $searchWord); } } From c13c9f70515ebb9040c4d43b1f37f8f0cb0985eb Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 09:59:54 +0100 Subject: [PATCH 15/53] =?UTF-8?q?=F0=9F=8E=A8=20Only=20perform=20meta=20ac?= =?UTF-8?q?tions=20when=20actually=20searching=20on=20words?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Hook/Posts.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index dd3d215..d195ecb 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -29,7 +29,7 @@ public function init() public function distinct($sql, WP_Query $query) { - if (! $query->is_search) { + if (! $this->isSearch($query)) { return $sql; } @@ -38,7 +38,7 @@ public function distinct($sql, WP_Query $query) public function join($sql, WP_Query $query) { - if (! $query->is_search) { + if (! $this->isSearch($query)) { return $sql; } @@ -58,7 +58,7 @@ public function join($sql, WP_Query $query) public function search($sql, WP_Query $query) { - if (! $query->is_search) { + if (! $this->isSearch($query)) { return $sql; } @@ -83,4 +83,19 @@ public function search($sql, WP_Query $query) return $and . implode($and, $andClauses); } + + private function isSearch(WP_Query $query) + { + if (! $query->is_search) { + return false; + } + + $searchWords = $query->get('search_terms'); + + if (! $searchWords) { + return false; + } + + return true; + } } From 1ddc632a1a9288ac5852c30b779da191b8188ad7 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 10:05:43 +0100 Subject: [PATCH 16/53] =?UTF-8?q?=F0=9F=94=A8=20Receive=20database=20on=20?= =?UTF-8?q?construction=20of=20Dimension=20instead=20of=20passing=20it=20a?= =?UTF-8?q?round?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Dimension.php | 6 +++--- src/Dimension/Meta.php | 12 +++++++----- src/Hook/Posts.php | 9 +++------ src/Search.php | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Dimension/Dimension.php b/src/Dimension/Dimension.php index bc1b857..19fa020 100644 --- a/src/Dimension/Dimension.php +++ b/src/Dimension/Dimension.php @@ -5,7 +5,7 @@ interface Dimension { - public function __construct(array $options); - public function join(wpdb $wpdb, $aliasCount = 0); - public function search(wpdb $wpdb, $searchWord, $aliasCount = 0); + public function __construct(wpdb $wpdb, array $options); + public function join($aliasCount = 0); + public function search($searchWord, $aliasCount = 0); } diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 36599a5..6a0106f 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -8,8 +8,9 @@ final class Meta implements Dimension { private $options; private $tableAlias = 'searchMeta'; + private $wpdb; - public function __construct(array $options) + public function __construct(wpdb $wpdb, array $options) { if (! isset($options['key'])) { throw new BadMethodCallException('`key` is a required property.'); @@ -18,16 +19,17 @@ public function __construct(array $options) $this->options = wp_parse_args($options, [ 'compare' => '=', ]); + $this->wpdb = $wpdb; } - public function join(wpdb $wpdb, $aliasCount = 0) + public function join($aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - return "INNER JOIN {$wpdb->postmeta} AS {$tableAlias} ON ({$wpdb->posts}.ID = {$tableAlias}.post_id)"; + return "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; } - public function search(wpdb $wpdb, $searchWord, $aliasCount = 0) + public function search($searchWord, $aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; @@ -35,6 +37,6 @@ public function search(wpdb $wpdb, $searchWord, $aliasCount = 0) $searchSql .= " AND "; $searchSql .= "{$tableAlias}.meta_value LIKE %s)"; - return $wpdb->prepare($searchSql, $this->options['key'], $searchWord); + return $this->wpdb->prepare($searchSql, $this->options['key'], $searchWord); } } diff --git a/src/Hook/Posts.php b/src/Hook/Posts.php index d195ecb..45c3a81 100644 --- a/src/Hook/Posts.php +++ b/src/Hook/Posts.php @@ -4,17 +4,14 @@ use Trendwerk\Search\Dimension\Dimension; use Trendwerk\Search\Dimension\Dimensions; use WP_Query; -use wpdb; final class Posts { private $dimensions; - private $wpdb; - public function __construct(wpdb $wpdb, Dimensions $dimensions) + public function __construct(Dimensions $dimensions) { $this->dimensions = $dimensions; - $this->wpdb = $wpdb; } public function init() @@ -49,7 +46,7 @@ public function join($sql, WP_Query $query) foreach ($searchWords as $wordCount => $searchWord) { foreach ($this->dimensions->get() as $dimension) { $dimensionType = get_class($dimension); - $joins[$dimensionType . $wordCount] = $dimension->join($this->wpdb, $wordCount); + $joins[$dimensionType . $wordCount] = $dimension->join($wordCount); } } @@ -73,7 +70,7 @@ public function search($sql, WP_Query $query) $searches = []; foreach ($this->dimensions->get() as $dimension) { - $searches[] = $dimension->search($this->wpdb, $searchWord, $index); + $searches[] = $dimension->search($searchWord, $index); } $search = '(' . implode($or, $searches) . ')' . $or; diff --git a/src/Search.php b/src/Search.php index 39da34a..b4b0cd4 100644 --- a/src/Search.php +++ b/src/Search.php @@ -10,10 +10,10 @@ final class Search { private $dimensions; - public function __construct(wpdb $wpdb) + public function __construct() { $this->dimensions = new Dimensions(); - $this->postsHook = new Posts($wpdb, $this->dimensions); + $this->postsHook = new Posts($this->dimensions); } public function init() From 56289e63685f854c0597bd4479625af9d71fc46a Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 10:25:53 +0100 Subject: [PATCH 17/53] :rotating_light: Multiline string --- src/Dimension/Meta.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 6a0106f..3de9f88 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -26,7 +26,8 @@ public function join($aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - return "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; + return "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} + ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; } public function search($searchWord, $aliasCount = 0) From 6afc9b81ba3fc25f4d66c1af0d6e678335bcf835 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 10:55:42 +0100 Subject: [PATCH 18/53] =?UTF-8?q?=F0=9F=94=A8=20Unit=20test=20in=20isolati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/install-wp-tests.sh | 127 ------------------------------------ tests/Search/SampleTest.php | 4 +- tests/bootstrap.php | 19 +----- 3 files changed, 3 insertions(+), 147 deletions(-) delete mode 100644 bin/install-wp-tests.sh diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh deleted file mode 100644 index 73bb4c7..0000000 --- a/bin/install-wp-tests.sh +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env bash - -if [ $# -lt 3 ]; then - echo "usage: $0 [db-host] [wp-version] [skip-database-creation]" - exit 1 -fi - -DB_NAME=$1 -DB_USER=$2 -DB_PASS=$3 -DB_HOST=${4-localhost} -WP_VERSION=${5-latest} -SKIP_DB_CREATE=${6-false} - -WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} - -download() { - if [ `which curl` ]; then - curl -s "$1" > "$2"; - elif [ `which wget` ]; then - wget -nv -O "$2" "$1" - fi -} - -if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then - WP_TESTS_TAG="tags/$WP_VERSION" -elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - WP_TESTS_TAG="trunk" -else - # http serves a single offer, whereas https serves multiple. we only want one - download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json - grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json - LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') - if [[ -z "$LATEST_VERSION" ]]; then - echo "Latest WordPress version could not be found" - exit 1 - fi - WP_TESTS_TAG="tags/$LATEST_VERSION" -fi - -set -ex - -install_wp() { - - if [ -d $WP_CORE_DIR ]; then - return; - fi - - mkdir -p $WP_CORE_DIR - - if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - mkdir -p /tmp/wordpress-nightly - download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip - unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ - mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR - else - if [ $WP_VERSION == 'latest' ]; then - local ARCHIVE_NAME='latest' - else - local ARCHIVE_NAME="wordpress-$WP_VERSION" - fi - download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR - fi - - download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php -} - -install_test_suite() { - # portable in-place argument for both GNU sed and Mac OSX sed - if [[ $(uname -s) == 'Darwin' ]]; then - local ioption='-i .bak' - else - local ioption='-i' - fi - - # set up testing suite if it doesn't yet exist - if [ ! -d $WP_TESTS_DIR ]; then - # set up testing suite - mkdir -p $WP_TESTS_DIR - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes - svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data - fi - - if [ ! -f wp-tests-config.php ]; then - download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php - # remove all forward slashes in the end - WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") - sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php - sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php - fi - -} - -install_db() { - - if [ ${SKIP_DB_CREATE} = "true" ]; then - return 0 - fi - - # parse DB_HOST for port or socket references - local PARTS=(${DB_HOST//\:/ }) - local DB_HOSTNAME=${PARTS[0]}; - local DB_SOCK_OR_PORT=${PARTS[1]}; - local EXTRA="" - - if ! [ -z $DB_HOSTNAME ] ; then - if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then - EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" - elif ! [ -z $DB_SOCK_OR_PORT ] ; then - EXTRA=" --socket=$DB_SOCK_OR_PORT" - elif ! [ -z $DB_HOSTNAME ] ; then - EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" - fi - fi - - # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA -} - -install_wp -install_test_suite -install_db diff --git a/tests/Search/SampleTest.php b/tests/Search/SampleTest.php index 58c85d7..067e9d9 100644 --- a/tests/Search/SampleTest.php +++ b/tests/Search/SampleTest.php @@ -1,9 +1,9 @@ Date: Wed, 15 Feb 2017 11:05:12 +0100 Subject: [PATCH 19/53] :construction_worker: Remove WP tests install from Travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4e86352..a1b9372 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,6 @@ matrix: env: WP_VERSION=latest WP_MULTISITE=1 before_script: - - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION - composer install script: From a5d9e7966a56405a3a8ae70ee6424f68f284fd86 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 11:21:29 +0100 Subject: [PATCH 20/53] =?UTF-8?q?=F0=9F=8E=A8=20Make=20postsHook=20private?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Search.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Search.php b/src/Search.php index b4b0cd4..6dd2a78 100644 --- a/src/Search.php +++ b/src/Search.php @@ -9,6 +9,7 @@ final class Search { private $dimensions; + private $postsHook; public function __construct() { From be56d0378e7a03cfef83f82eccc22ef95564dfde Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 11:32:05 +0100 Subject: [PATCH 21/53] :heavy_plus_sign: WP_Mock + Mockery --- composer.json | 3 +- composer.lock | 201 +++++++++++++++++++++++++++++++++++++++++++- tests/bootstrap.php | 2 + 3 files changed, 202 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index a558707..1fe75d6 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ }, "require-dev": { "phpunit/phpunit": "5.7.*", - "squizlabs/php_codesniffer": "2.*" + "squizlabs/php_codesniffer": "2.*", + "10up/wp_mock": "dev-master" } } diff --git a/composer.lock b/composer.lock index e913f7a..789be3e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,10 +4,93 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2acfe3d253f465fa7a2431863b8343fc", - "content-hash": "ba217e22e6436ef5179464b66a86aa41", + "hash": "2f3e41d7dba81aff7c7608ed15c53137", + "content-hash": "dd261d147fe5fa4a34597e7617e29cf0", "packages": [], "packages-dev": [ + { + "name": "10up/wp_mock", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/10up/wp_mock.git", + "reference": "994e0ad5b15a4b539ca77d377c198b1c43b1b7f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/10up/wp_mock/zipball/994e0ad5b15a4b539ca77d377c198b1c43b1b7f5", + "reference": "994e0ad5b15a4b539ca77d377c198b1c43b1b7f5", + "shasum": "" + }, + "require": { + "antecedent/patchwork": "~1.2", + "mockery/mockery": "~0.8", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~3.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-dev": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "WP_Mock\\": "./" + }, + "classmap": [ + "WP_Mock.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "description": "A mocking library to take the pain out of unit testing for WordPress", + "time": "2016-09-20 15:24:58" + }, + { + "name": "antecedent/patchwork", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/antecedent/patchwork.git", + "reference": "6e1a0a0c1282c9690d38fb4831cbdfcd04d02171" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/6e1a0a0c1282c9690d38fb4831cbdfcd04d02171", + "reference": "6e1a0a0c1282c9690d38fb4831cbdfcd04d02171", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignas Rudaitis", + "email": "ignas.rudaitis@gmail.com" + } + ], + "description": "Method redefinition (monkey-patching) functionality for PHP.", + "keywords": [ + "aop", + "aspect", + "interception", + "monkeypatching", + "redefinition", + "runkit", + "testing" + ], + "time": "2016-07-02 04:25:33" + }, { "name": "doctrine/instantiator", "version": "1.0.5", @@ -62,6 +145,116 @@ ], "time": "2015-06-14 21:17:01" }, + { + "name": "hamcrest/hamcrest-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "hamcrest" + ], + "files": [ + "hamcrest/Hamcrest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2015-05-11 14:41:42" + }, + { + "name": "mockery/mockery", + "version": "0.9.8", + "source": { + "type": "git", + "url": "https://github.com/padraic/mockery.git", + "reference": "1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/padraic/mockery/zipball/1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855", + "reference": "1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "~1.1", + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2017-02-09 13:29:38" + }, { "name": "myclabs/deep-copy", "version": "1.6.0", @@ -1397,7 +1590,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "10up/wp_mock": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f9e62ac..575446a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,2 +1,4 @@ Date: Wed, 15 Feb 2017 11:32:34 +0100 Subject: [PATCH 22/53] =?UTF-8?q?=E2=9C=85=20WP=5FMock-based=20TestCase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/SampleTest.php | 12 ------------ tests/Search/TestCase.php | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 12 deletions(-) delete mode 100644 tests/Search/SampleTest.php create mode 100644 tests/Search/TestCase.php diff --git a/tests/Search/SampleTest.php b/tests/Search/SampleTest.php deleted file mode 100644 index 067e9d9..0000000 --- a/tests/Search/SampleTest.php +++ /dev/null @@ -1,12 +0,0 @@ -assertTrue(true); - } -} diff --git a/tests/Search/TestCase.php b/tests/Search/TestCase.php new file mode 100644 index 0000000..c20b3e4 --- /dev/null +++ b/tests/Search/TestCase.php @@ -0,0 +1,18 @@ + Date: Wed, 15 Feb 2017 11:33:02 +0100 Subject: [PATCH 23/53] =?UTF-8?q?=E2=9C=85=20Search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/SearchTest.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/Search/SearchTest.php diff --git a/tests/Search/SearchTest.php b/tests/Search/SearchTest.php new file mode 100644 index 0000000..af323c2 --- /dev/null +++ b/tests/Search/SearchTest.php @@ -0,0 +1,33 @@ +search = new Search(); + } + + public function testInit() + { + $this->assertNull($this->search->init()); + } + + public function testAddDimension() + { + $wpdb = Mockery::mock('\wpdb'); + + $this->expectException(BadMethodCallException::class); + $this->search->addDimension(new Meta($wpdb, [])); + } +} From 3230f88af35d1f301f8080ab0502565d7ba9566a Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 11:38:00 +0100 Subject: [PATCH 24/53] =?UTF-8?q?=F0=9F=8E=A8=20No=20need=20to=20use=20glo?= =?UTF-8?q?bal=20namespace=20identifier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/DimensionsTest.php | 27 +++++++++++++++++++++++ tests/Search/SearchTest.php | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/Search/Dimension/DimensionsTest.php diff --git a/tests/Search/Dimension/DimensionsTest.php b/tests/Search/Dimension/DimensionsTest.php new file mode 100644 index 0000000..6f9cd5c --- /dev/null +++ b/tests/Search/Dimension/DimensionsTest.php @@ -0,0 +1,27 @@ +dimensions = new Dimensions(); + } + + public function testGetSet() + { + // $wpdb = Mockery::mock('\wpdb'); + // $metaSearches = [ + // new Meta(), + // new Meta() + // ]; + } +} diff --git a/tests/Search/SearchTest.php b/tests/Search/SearchTest.php index af323c2..2209e05 100644 --- a/tests/Search/SearchTest.php +++ b/tests/Search/SearchTest.php @@ -25,7 +25,7 @@ public function testInit() public function testAddDimension() { - $wpdb = Mockery::mock('\wpdb'); + $wpdb = Mockery::mock('wpdb'); $this->expectException(BadMethodCallException::class); $this->search->addDimension(new Meta($wpdb, [])); From a433fadf8376645f85a8ac76853d00a95624fa50 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 11:43:07 +0100 Subject: [PATCH 25/53] =?UTF-8?q?=E2=9C=85=20Dimensions=20collection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/DimensionsTest.php | 24 ++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/Search/Dimension/DimensionsTest.php b/tests/Search/Dimension/DimensionsTest.php index 6f9cd5c..921c713 100644 --- a/tests/Search/Dimension/DimensionsTest.php +++ b/tests/Search/Dimension/DimensionsTest.php @@ -4,6 +4,7 @@ use Mockery; use Trendwerk\Search\Dimension\Dimensions; use Trendwerk\Search\Dimension\Meta; +use WP_Mock; final class DimensionsTest extends TestCase { @@ -18,10 +19,23 @@ public function setUp() public function testGetSet() { - // $wpdb = Mockery::mock('\wpdb'); - // $metaSearches = [ - // new Meta(), - // new Meta() - // ]; + $wpdb = Mockery::mock('wpdb'); + + WP_Mock::wpPassthruFunction('wp_parse_args', ['times' => 2]); + + $metaSearches = [ + new Meta($wpdb, [ + 'key' => 'firstName', + ]), + new Meta($wpdb, [ + 'key' => 'lastName', + ]), + ]; + + foreach ($metaSearches as $metaSearch) { + $this->assertNull($this->dimensions->add($metaSearch)); + } + + $this->assertEquals($this->dimensions->get(), $metaSearches); } } From db1ff3044894ea5388a0db775bcb8d6835711c89 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 11:46:32 +0100 Subject: [PATCH 26/53] =?UTF-8?q?=E2=9C=85=20Meta:=20invalid=20constructio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/MetaTest.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/Search/Dimension/MetaTest.php diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php new file mode 100644 index 0000000..04ba666 --- /dev/null +++ b/tests/Search/Dimension/MetaTest.php @@ -0,0 +1,24 @@ +wpdb = Mockery::mock('wpdb');; + } + + public function testKeyRequired() + { + $this->expectException(BadMethodCallException::class); + $meta = new Meta($this->wpdb, []); + } +} From 1c6fa60b3ef56da41402c5345168706f22573daa Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 11:48:46 +0100 Subject: [PATCH 27/53] :rotating_light: Remove excessive semicolon --- tests/Search/Dimension/MetaTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index 04ba666..32c04be 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -13,7 +13,7 @@ public function setUp() { parent::setUp(); - $this->wpdb = Mockery::mock('wpdb');; + $this->wpdb = Mockery::mock('wpdb'); } public function testKeyRequired() From 3997d5e5259dcdc53a71e1db5719ebddf9d8f1bf Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 13:20:27 +0100 Subject: [PATCH 28/53] =?UTF-8?q?=E2=9C=85=20Search:=20equals?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/MetaTest.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index 32c04be..d42733e 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -4,6 +4,7 @@ use BadMethodCallException; use Mockery; use Trendwerk\Search\Dimension\Meta; +use WP_Mock; final class MetaTest extends TestCase { @@ -21,4 +22,31 @@ public function testKeyRequired() $this->expectException(BadMethodCallException::class); $meta = new Meta($this->wpdb, []); } + + public function testSearchEquals() + { + $this->search('Testman', 'firstName', '='); + } + + private function search($searchWord, $metaKey, $compare) + { + $expectation = "(searchMeta0.meta_key {$compare} %s AND searchMeta0.meta_value LIKE %s)"; + + WP_Mock::wpPassthruFunction('wp_parse_args', ['times' => 1]); + + $meta = new Meta($this->wpdb, [ + 'compare' => $compare, + 'key' => $metaKey, + ]); + + $this->wpdb->shouldReceive('prepare') + ->once() + ->andReturnUsing(function () { + return func_get_args(); + }); + + $result = $meta->search($searchWord); + + $this->assertEquals($result, [$expectation, $metaKey, $searchWord]); + } } From 3b1623111e7592993fe813c53df46214bc80a2b2 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 13:21:22 +0100 Subject: [PATCH 29/53] =?UTF-8?q?=E2=9C=85=20Search:=20LIKE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/MetaTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index d42733e..d32ef44 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -28,6 +28,11 @@ public function testSearchEquals() $this->search('Testman', 'firstName', '='); } + public function testSearchLike() + { + $this->search('McTest', 'lastName', 'LIKE'); + } + private function search($searchWord, $metaKey, $compare) { $expectation = "(searchMeta0.meta_key {$compare} %s AND searchMeta0.meta_value LIKE %s)"; From 8d19876ca8ea2b666023bad5bf81f6909953892b Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 13:25:48 +0100 Subject: [PATCH 30/53] =?UTF-8?q?=E2=9C=85=20Actually=20run=20Search->add(?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/SearchTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Search/SearchTest.php b/tests/Search/SearchTest.php index 2209e05..e919cb6 100644 --- a/tests/Search/SearchTest.php +++ b/tests/Search/SearchTest.php @@ -27,7 +27,8 @@ public function testAddDimension() { $wpdb = Mockery::mock('wpdb'); - $this->expectException(BadMethodCallException::class); - $this->search->addDimension(new Meta($wpdb, [])); + $this->assertNull($this->search->addDimension(new Meta($wpdb, [ + 'key' => 'firstName', + ]))); } } From 6c03036380796c5148e80e301ba7bb3872df8158 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 13:32:46 +0100 Subject: [PATCH 31/53] =?UTF-8?q?=E2=9C=85=20Search:=20aliasCount?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/MetaTest.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index d32ef44..85d7e35 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -33,9 +33,15 @@ public function testSearchLike() $this->search('McTest', 'lastName', 'LIKE'); } - private function search($searchWord, $metaKey, $compare) + public function testSearchAliasCount() { - $expectation = "(searchMeta0.meta_key {$compare} %s AND searchMeta0.meta_value LIKE %s)"; + $this->search('Testman', 'firstName', '=', 2); + } + + private function search($searchWord, $metaKey, $compare, $tableAliasCount = 0) + { + $tableAlias = 'searchMeta' . $tableAliasCount; + $expectation = "({$tableAlias}.meta_key {$compare} %s AND {$tableAlias}.meta_value LIKE %s)"; WP_Mock::wpPassthruFunction('wp_parse_args', ['times' => 1]); @@ -50,7 +56,7 @@ private function search($searchWord, $metaKey, $compare) return func_get_args(); }); - $result = $meta->search($searchWord); + $result = $meta->search($searchWord, $tableAliasCount); $this->assertEquals($result, [$expectation, $metaKey, $searchWord]); } From c67b9d43b2093b9d63fccb257a3918c16fb248a3 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 13:38:07 +0100 Subject: [PATCH 32/53] =?UTF-8?q?=F0=9F=94=A8=20Separate=20tableAlias=20an?= =?UTF-8?q?d=20meta=20creation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/MetaTest.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index 85d7e35..de54d8d 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -8,6 +8,7 @@ final class MetaTest extends TestCase { + private $tableAlias = 'searchMeta'; private $wpdb; public function setUp() @@ -40,15 +41,10 @@ public function testSearchAliasCount() private function search($searchWord, $metaKey, $compare, $tableAliasCount = 0) { - $tableAlias = 'searchMeta' . $tableAliasCount; + $tableAlias = $this->tableAlias . $tableAliasCount; $expectation = "({$tableAlias}.meta_key {$compare} %s AND {$tableAlias}.meta_value LIKE %s)"; - WP_Mock::wpPassthruFunction('wp_parse_args', ['times' => 1]); - - $meta = new Meta($this->wpdb, [ - 'compare' => $compare, - 'key' => $metaKey, - ]); + $meta = $this->create($metaKey, $compare); $this->wpdb->shouldReceive('prepare') ->once() @@ -60,4 +56,15 @@ private function search($searchWord, $metaKey, $compare, $tableAliasCount = 0) $this->assertEquals($result, [$expectation, $metaKey, $searchWord]); } + + private function create($metaKey, $compare) { + WP_Mock::wpPassthruFunction('wp_parse_args', ['times' => 1]); + + $meta = new Meta($this->wpdb, [ + 'compare' => $compare, + 'key' => $metaKey, + ]); + + return $meta; + } } From 0f7bfe8d6afc48cd30ed2a1f8a8d09dbb04caa4c Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 13:39:50 +0100 Subject: [PATCH 33/53] =?UTF-8?q?=E2=9C=85=20Meta:=20Join?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Dimension/MetaTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index de54d8d..a1f702a 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -24,6 +24,24 @@ public function testKeyRequired() $meta = new Meta($this->wpdb, []); } + public function testJoin() + { + $tableAliasCount = 2; + $tableAlias = $this->tableAlias . $tableAliasCount; + + $this->wpdb->posts = 'wp_posts'; + $this->wpdb->postmeta = 'wp_postmeta'; + + $expectation = "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} + ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; + + $meta = $this->create('firstName', '='); + + $result = $meta->join($tableAliasCount); + + $this->assertEquals($expectation, $result); + } + public function testSearchEquals() { $this->search('Testman', 'firstName', '='); From 53a01b1570f2441011e85ed8ea8f48169ec1ef47 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:03:11 +0100 Subject: [PATCH 34/53] =?UTF-8?q?=E2=9C=85=20Posts=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/Search/Hook/PostsTest.php diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php new file mode 100644 index 0000000..ca0547a --- /dev/null +++ b/tests/Search/Hook/PostsTest.php @@ -0,0 +1,41 @@ +add(new Meta($wpdb, [ + 'key' => 'lastName', + ])); + + $this->posts = new Posts($dimensions); + } + + public function testInit() + { + $argsCount = 2; + $priority = 10; + + WP_Mock::expectFilterAdded('posts_distinct', [$this->posts, 'distinct'], $priority, $argsCount); + WP_Mock::expectFilterAdded('posts_join', [$this->posts, 'join'], $priority, $argsCount); + WP_Mock::expectFilterAdded('posts_search', [$this->posts, 'search'], $priority, $argsCount); + + $this->posts->init(); + + WP_Mock::assertHooksAdded(); + } +} From b3d9dbb2eed790965120d6c148c340bef5435325 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:08:10 +0100 Subject: [PATCH 35/53] =?UTF-8?q?=E2=9C=85=20Posts:=20DISTINCT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index ca0547a..f1cc071 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -38,4 +38,19 @@ public function testInit() WP_Mock::assertHooksAdded(); } + + public function testDistinct() + { + $expectation = "DISTINCT"; + + $wpQuery = Mockery::mock('WP_Query'); + $wpQuery->is_search = true; + $wpQuery->shouldReceive('get') + ->with('search_terms') + ->andReturn(['Testman', 'mcTest']); + + $result = $this->posts->distinct('', $wpQuery); + + $this->assertEquals($expectation, $result); + } } From f09f5f28a961075955c1798456706b5a72267334 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:09:29 +0100 Subject: [PATCH 36/53] =?UTF-8?q?=E2=9C=85=20Posts:=20Distinct=20without?= =?UTF-8?q?=20is=5Fsearch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index f1cc071..26c3e71 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -53,4 +53,19 @@ public function testDistinct() $this->assertEquals($expectation, $result); } + + public function testDistinctNotSearch() + { + $expectation = ''; + + $wpQuery = Mockery::mock('WP_Query'); + $wpQuery->is_search = false; + $wpQuery->shouldReceive('get') + ->with('search_terms') + ->andReturn(['Testman', 'mcTest']); + + $result = $this->posts->distinct('', $wpQuery); + + $this->assertEquals($expectation, $result); + } } From 52941e0ddd280f56df0734a417b1cbd45f11c2c7 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:10:15 +0100 Subject: [PATCH 37/53] =?UTF-8?q?=E2=9C=85=20Posts:=20DISTINCT=20without?= =?UTF-8?q?=20words?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index 26c3e71..a17fe2a 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -68,4 +68,19 @@ public function testDistinctNotSearch() $this->assertEquals($expectation, $result); } + + public function testDistinctNoWords() + { + $expectation = ''; + + $wpQuery = Mockery::mock('WP_Query'); + $wpQuery->is_search = true; + $wpQuery->shouldReceive('get') + ->with('search_terms') + ->andReturn([]); + + $result = $this->posts->distinct('', $wpQuery); + + $this->assertEquals($expectation, $result); + } } From 213d6c5acf24b8cf72ccad6991feef9a26ee7e3a Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:12:37 +0100 Subject: [PATCH 38/53] =?UTF-8?q?=F0=9F=94=A8=20Extract=20method:=20getQue?= =?UTF-8?q?ry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index a17fe2a..928afb8 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -42,14 +42,7 @@ public function testInit() public function testDistinct() { $expectation = "DISTINCT"; - - $wpQuery = Mockery::mock('WP_Query'); - $wpQuery->is_search = true; - $wpQuery->shouldReceive('get') - ->with('search_terms') - ->andReturn(['Testman', 'mcTest']); - - $result = $this->posts->distinct('', $wpQuery); + $result = $this->posts->distinct('', $this->getQuery()); $this->assertEquals($expectation, $result); } @@ -57,14 +50,7 @@ public function testDistinct() public function testDistinctNotSearch() { $expectation = ''; - - $wpQuery = Mockery::mock('WP_Query'); - $wpQuery->is_search = false; - $wpQuery->shouldReceive('get') - ->with('search_terms') - ->andReturn(['Testman', 'mcTest']); - - $result = $this->posts->distinct('', $wpQuery); + $result = $this->posts->distinct('', $this->getQuery(false)); $this->assertEquals($expectation, $result); } @@ -72,15 +58,19 @@ public function testDistinctNotSearch() public function testDistinctNoWords() { $expectation = ''; + $result = $this->posts->distinct('', $this->getQuery(true, [])); + + $this->assertEquals($expectation, $result); + } + private function getQuery($isSearch = true, $terms = ['Testman', 'mcTest']) + { $wpQuery = Mockery::mock('WP_Query'); - $wpQuery->is_search = true; + $wpQuery->is_search = $isSearch; $wpQuery->shouldReceive('get') ->with('search_terms') - ->andReturn([]); + ->andReturn($terms); - $result = $this->posts->distinct('', $wpQuery); - - $this->assertEquals($expectation, $result); + return $wpQuery; } } From f54e099cb2f6b03c80cc6b01b250b760f13558bc Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:20:54 +0100 Subject: [PATCH 39/53] :rotating_light: Brace on new line, PSR --- tests/Search/Dimension/MetaTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index a1f702a..cc5cfa6 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -75,7 +75,8 @@ private function search($searchWord, $metaKey, $compare, $tableAliasCount = 0) $this->assertEquals($result, [$expectation, $metaKey, $searchWord]); } - private function create($metaKey, $compare) { + private function create($metaKey, $compare) + { WP_Mock::wpPassthruFunction('wp_parse_args', ['times' => 1]); $meta = new Meta($this->wpdb, [ From 66603532a4346566c0ee8c9254e48d9289c6667c Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:32:24 +0100 Subject: [PATCH 40/53] =?UTF-8?q?=F0=9F=8E=A8=20Refrain=20from=20multi-lin?= =?UTF-8?q?e=20PHP=20strings=20for=20more=20reliable=20testing=20of=20outp?= =?UTF-8?q?ut=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 6 ++++-- tests/Search/Dimension/MetaTest.php | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 3de9f88..9ca8df5 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -26,8 +26,10 @@ public function join($aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; - return "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} - ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; + $sql = "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} "; + $sql .= "ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; + + return $sql; } public function search($searchWord, $aliasCount = 0) diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index cc5cfa6..c0ac4a6 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -32,8 +32,8 @@ public function testJoin() $this->wpdb->posts = 'wp_posts'; $this->wpdb->postmeta = 'wp_postmeta'; - $expectation = "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} - ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; + $expectation = "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} "; + $expectation .= "ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; $meta = $this->create('firstName', '='); From 0a71b2c683898351c4607ec783a5127ba92fd436 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:32:44 +0100 Subject: [PATCH 41/53] =?UTF-8?q?=E2=9C=85=20Test=20JOIN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index 928afb8..e22ec05 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -10,15 +10,18 @@ final class PostsTest extends TestCase { private $posts; + private $wpdb; public function setUp() { parent::setUp(); - $wpdb = Mockery::mock('wpdb'); + $this->wpdb = Mockery::mock('wpdb'); + $this->wpdb->postmeta = 'wp_postmeta'; + $this->wpdb->posts = 'wp_posts'; $dimensions = new Dimensions(); - $dimensions->add(new Meta($wpdb, [ + $dimensions->add(new Meta($this->wpdb, [ 'key' => 'lastName', ])); @@ -63,6 +66,28 @@ public function testDistinctNoWords() $this->assertEquals($expectation, $result); } + public function testJoin() + { + $baseSql = 'INNER JOIN alreadyAvailableSql'; + + $searchTerms = ['Testman', 'theTester']; + $expectation = []; + + foreach ($searchTerms as $index => $searchTerm) { + $tableAlias = 'searchMeta' . $index; + + $wordExpectation = "INNER JOIN {$this->wpdb->postmeta} AS {$tableAlias} "; + $wordExpectation .= "ON ({$this->wpdb->posts}.ID = {$tableAlias}.post_id)"; + + $expectation[] = $wordExpectation; + } + + $expectation = $baseSql . ' ' . implode(' ', $expectation); + $result = $this->posts->join($baseSql, $this->getQuery(true, $searchTerms)); + + $this->assertEquals($expectation, $result); + } + private function getQuery($isSearch = true, $terms = ['Testman', 'mcTest']) { $wpQuery = Mockery::mock('WP_Query'); From 84f716fc606e4efda81eb781917cee01a972dafc Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:35:09 +0100 Subject: [PATCH 42/53] =?UTF-8?q?=E2=9C=85=20Join:=20not=20on=20search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index e22ec05..18bdbd1 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -88,6 +88,15 @@ public function testJoin() $this->assertEquals($expectation, $result); } + public function testJoinWithoutSearch() + { + $baseSql = 'INNER JOIN alreadyAvailable'; + $expectation = $baseSql; + $result = $this->posts->join($baseSql, $this->getQuery(false)); + + $this->assertEquals($expectation, $result); + } + private function getQuery($isSearch = true, $terms = ['Testman', 'mcTest']) { $wpQuery = Mockery::mock('WP_Query'); From 29d7ec8ee5081677d93f92f4d8f9be32015c7aad Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:54:54 +0100 Subject: [PATCH 43/53] =?UTF-8?q?=E2=9C=85=20Search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 42 ++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index 18bdbd1..51adea2 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -9,6 +9,7 @@ final class PostsTest extends TestCase { + private $metaKey = 'lastName'; private $posts; private $wpdb; @@ -22,7 +23,8 @@ public function setUp() $dimensions = new Dimensions(); $dimensions->add(new Meta($this->wpdb, [ - 'key' => 'lastName', + 'compare' => '=', + 'key' => $this->metaKey, ])); $this->posts = new Posts($dimensions); @@ -97,6 +99,44 @@ public function testJoinWithoutSearch() $this->assertEquals($expectation, $result); } + public function testSearch() + { + $and = " AND "; + $or = " OR "; + + $searchTerms = ['Testman', 'theTester']; + $baseSql = $and . "("; + + foreach ($searchTerms as $searchTerm) { + $baseSql .= "("; + $baseSql .= "({$this->wpdb->posts}.post_title LIKE '%{$searchTerm}%')"; + $baseSql .= $or; + $baseSql .= "({$this->wpdb->posts}.post_content LIKE '%{$searchTerm}%')"; + $baseSql .= ")" . $and; + } + + $baseSql = mb_substr($baseSql, 0, mb_strlen($baseSql) - mb_strlen($or)); + $baseSql .= ")"; + + $expectations = []; + + foreach ($searchTerms as $index => $searchTerm) { + $expectations[] = "searchMeta{$index}.meta_key %s AND searchMeta{$index}.meta_value LIKE %s"; + } + + $this->wpdb->shouldReceive('prepare') + ->times(count($searchTerms)) + ->andReturnUsing(function ($sql) { + return $sql; + }); + + $result = $this->posts->search($baseSql, $this->getQuery(true, $searchTerms)); + + foreach ($expectations as $expectation) { + $this->assertContains($expectation, $result); + } + } + private function getQuery($isSearch = true, $terms = ['Testman', 'mcTest']) { $wpQuery = Mockery::mock('WP_Query'); From 5dabf9007ab5ae73211a5b07dc703d0865ac02be Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 14:56:19 +0100 Subject: [PATCH 44/53] =?UTF-8?q?=E2=9C=85=20Search=20without=20being=20on?= =?UTF-8?q?=20search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Search/Hook/PostsTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index 51adea2..590a8a7 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -137,6 +137,14 @@ public function testSearch() } } + public function testSearchWithoutSearch() + { + $expectation = ''; + $result = $this->posts->search('', $this->getQuery(false)); + + $this->assertEquals($expectation, $result); + } + private function getQuery($isSearch = true, $terms = ['Testman', 'mcTest']) { $wpQuery = Mockery::mock('WP_Query'); From 75d6c8654adad79eef8a23acb8f8cb7a1a65251c Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 15:04:43 +0100 Subject: [PATCH 45/53] =?UTF-8?q?=F0=9F=8E=A8=20Support=20wildcard=20for?= =?UTF-8?q?=20search=20term?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 9ca8df5..9716e7c 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -40,6 +40,6 @@ public function search($searchWord, $aliasCount = 0) $searchSql .= " AND "; $searchSql .= "{$tableAlias}.meta_value LIKE %s)"; - return $this->wpdb->prepare($searchSql, $this->options['key'], $searchWord); + return $this->wpdb->prepare($searchSql, $this->options['key'], '%' . $searchWord . '%'); } } From a6983735236e3c2126564fac559526f04c6887cf Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 15:29:38 +0100 Subject: [PATCH 46/53] =?UTF-8?q?=F0=9F=8E=A8=20Escape=20LIKE=20search=20w?= =?UTF-8?q?ord?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dimension/Meta.php | 1 + tests/Search/Dimension/MetaTest.php | 7 ++++++- tests/Search/Hook/PostsTest.php | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Dimension/Meta.php b/src/Dimension/Meta.php index 9716e7c..cd66b9d 100644 --- a/src/Dimension/Meta.php +++ b/src/Dimension/Meta.php @@ -35,6 +35,7 @@ public function join($aliasCount = 0) public function search($searchWord, $aliasCount = 0) { $tableAlias = $this->tableAlias . $aliasCount; + $searchWord = $this->wpdb->esc_like($searchWord); $searchSql = "({$tableAlias}.meta_key {$this->options['compare']} %s"; $searchSql .= " AND "; diff --git a/tests/Search/Dimension/MetaTest.php b/tests/Search/Dimension/MetaTest.php index c0ac4a6..8618e60 100644 --- a/tests/Search/Dimension/MetaTest.php +++ b/tests/Search/Dimension/MetaTest.php @@ -64,6 +64,11 @@ private function search($searchWord, $metaKey, $compare, $tableAliasCount = 0) $meta = $this->create($metaKey, $compare); + $this->wpdb->shouldReceive('esc_like') + ->andReturnUsing(function ($searchWord) { + return $searchWord; + }); + $this->wpdb->shouldReceive('prepare') ->once() ->andReturnUsing(function () { @@ -72,7 +77,7 @@ private function search($searchWord, $metaKey, $compare, $tableAliasCount = 0) $result = $meta->search($searchWord, $tableAliasCount); - $this->assertEquals($result, [$expectation, $metaKey, $searchWord]); + $this->assertEquals($result, [$expectation, $metaKey, '%' . $searchWord . '%']); } private function create($metaKey, $compare) diff --git a/tests/Search/Hook/PostsTest.php b/tests/Search/Hook/PostsTest.php index 590a8a7..44ef22c 100644 --- a/tests/Search/Hook/PostsTest.php +++ b/tests/Search/Hook/PostsTest.php @@ -124,6 +124,11 @@ public function testSearch() $expectations[] = "searchMeta{$index}.meta_key %s AND searchMeta{$index}.meta_value LIKE %s"; } + $this->wpdb->shouldReceive('esc_like') + ->andReturnUsing(function ($searchWord) { + return $searchWord; + }); + $this->wpdb->shouldReceive('prepare') ->times(count($searchTerms)) ->andReturnUsing(function ($sql) { From de3a6c05ae7246944c77c750dc821f3118de5d96 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 16:51:14 +0100 Subject: [PATCH 47/53] :memo: First draft for README --- README.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 135a1e3..ddeb123 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,72 @@ # Search -Basic extensions for searching in WordPress. +[![Build Status](https://travis-ci.org/trendwerk/search.svg?branch=master)](https://travis-ci.org/trendwerk/search) [![codecov](https://codecov.io/gh/trendwerk/search/branch/master/graph/badge.svg)](https://codecov.io/gh/trendwerk/search) + +Basic extensions for searching in WordPress. Currently only supports searching in `postmeta`. + +Quick links: [Install](#install) | [Usage](#usage) | [Dimensions](#dimensions) | [Example](#example) + +## Install +```sh +composer require trendwerk/acf-forms +``` + +## Usage +Extending search by looking inside a posts' meta data consists of two parts: + +1. [Initialize package](#initialize) +2. [Add search dimension(s)](#dimensions) + +### Initialize + +```php +$search = new \Trendwerk\Search\Search(); +$search->init(); +``` + +This code should be run when bootstrapping your theme. + +### Dimensions +Currently this package only supports metadata as a search dimension. Dimensions can be added by using `addDimension`: + +```php +$search->addDimension($dimension); +``` + +| Parameter | Default | Required | Description | +| :--- | :--- | :--- | :--- | +| `$dimension` | `null` | Yes | Should be an instance of a class that implements [`Dimension\Dimension`](https://github.com/trendwerk/search/blob/master/src/Dimension/Dimension.php). + +### Meta +```php +$metaDimension = new \Trendwerk\Search\Dimension\Meta([ + 'key' => 'firstName', +]); + +$search->addDimension($metaDimension); +``` + +Available options for constructing an instance of `Meta`: + +| Parameter | Default | Required | Description | +| :--- | :--- | :--- | :--- | +| `key` | `null` | Yes | The `meta_key` to search for +| `compare` | `null` | No | The database comparison that should be made for the meta key. Currently supports `LIKE` and `=`. When using `LIKE`, make sure to include a percent symbol (`%`) in your `key` parameter as a wildcard. See [Example](#example) + +## Example + +```php +use Trendwerk\Search\Dimension\Meta; +use Trendwerk\Search\Search; + +$search = new \Trendwerk\Search\Search(); +$search->init(); + +$search->addDimension(new Meta($wpdb, [ + 'compare' => 'LIKE', + 'key' => 'lastNames%', +])); + +$search->addDimension(new Meta($wpdb, [ + 'key' => 'firstName', +])); +``` From de3c8589405895d19c1c750bff41685553dbba95 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 16:52:10 +0100 Subject: [PATCH 48/53] :memo: Omit difficult explanation --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ddeb123..da5f242 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ composer require trendwerk/acf-forms ``` ## Usage -Extending search by looking inside a posts' meta data consists of two parts: 1. [Initialize package](#initialize) 2. [Add search dimension(s)](#dimensions) From 790309a9aab4c3e75adeb790677b9e39c84d324d Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 16:53:43 +0100 Subject: [PATCH 49/53] :memo: Correct default for compare --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da5f242..a6b04af 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Available options for constructing an instance of `Meta`: | Parameter | Default | Required | Description | | :--- | :--- | :--- | :--- | | `key` | `null` | Yes | The `meta_key` to search for -| `compare` | `null` | No | The database comparison that should be made for the meta key. Currently supports `LIKE` and `=`. When using `LIKE`, make sure to include a percent symbol (`%`) in your `key` parameter as a wildcard. See [Example](#example) +| `compare` | `=` | No | The database comparison that should be made for the meta key. Currently supports `LIKE` and `=`. When using `LIKE`, make sure to include a percent symbol (`%`) in your `key` parameter as a wildcard. See [Example](#example) ## Example From dd43a337773a26b92f77bb42f41161408a5e9d11 Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 16:58:57 +0100 Subject: [PATCH 50/53] :memo: Add performance disclaimer for larger databases --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a6b04af..a4d6b87 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Basic extensions for searching in WordPress. Currently only supports searching i Quick links: [Install](#install) | [Usage](#usage) | [Dimensions](#dimensions) | [Example](#example) +_Note: This basic extension is not meant for larger databases and could get slow for complex meta searches in larger databases. In that case, [Elasticsearch](https://www.elastic.co/) would be a good solution._ + ## Install ```sh composer require trendwerk/acf-forms From ac3be5cd2e368c19d2b2d7d1998bf792484d1c0a Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Wed, 15 Feb 2017 16:59:52 +0100 Subject: [PATCH 51/53] :memo: Improve readability on memo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a4d6b87..e0085c1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Basic extensions for searching in WordPress. Currently only supports searching i Quick links: [Install](#install) | [Usage](#usage) | [Dimensions](#dimensions) | [Example](#example) -_Note: This basic extension is not meant for larger databases and could get slow for complex meta searches in larger databases. In that case, [Elasticsearch](https://www.elastic.co/) would be a good solution._ +_Note: This basic extension is not very scalable and meant for smaller databases. This package could get slow for complex meta searches. In that case, [Elasticsearch](https://www.elastic.co/) would be a better solution._ ## Install ```sh From ab2d9a8ce3b8cae30d5627c5f3140f9d7e3a7c4f Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Thu, 16 Feb 2017 13:05:40 +0100 Subject: [PATCH 52/53] :memo: Change package name for installation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0085c1..c7efe30 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ _Note: This basic extension is not very scalable and meant for smaller databases ## Install ```sh -composer require trendwerk/acf-forms +composer require trendwerk/search ``` ## Usage From 5d2f3d208e7b1ca11e999525a5287e02db0059ff Mon Sep 17 00:00:00 2001 From: Harold Angenent Date: Thu, 16 Feb 2017 13:06:51 +0100 Subject: [PATCH 53/53] :memo: Remove specific namespace in favor of above use statement --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7efe30..cd14cf1 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Available options for constructing an instance of `Meta`: use Trendwerk\Search\Dimension\Meta; use Trendwerk\Search\Search; -$search = new \Trendwerk\Search\Search(); +$search = Search(); $search->init(); $search->addDimension(new Meta($wpdb, [