Click.php
1 year ago
Click_Processing_Job.php
1 year ago
Config_File_Manager.php
1 year ago
Link_Rule.php
1 year ago
Link_Rule_Finder.php
1 year ago
Link_Rule_Finder.php
178 lines
| 1 | <?php |
| 2 | |
| 3 | namespace IAWP\Click_Tracking; |
| 4 | |
| 5 | use IAWP\Illuminate_Builder; |
| 6 | use IAWP\Tables; |
| 7 | use IAWP\Utils\URL; |
| 8 | use IAWPSCOPED\Illuminate\Support\Collection; |
| 9 | // TODO - This for more link a matcher and not a finder... |
| 10 | /** @internal */ |
| 11 | class Link_Rule_Finder |
| 12 | { |
| 13 | private $protocol; |
| 14 | private $href; |
| 15 | private $classes; |
| 16 | private $ids; |
| 17 | private static $database_records = null; |
| 18 | public function __construct(?string $protocol, ?string $href, string $classes, string $ids) |
| 19 | { |
| 20 | $this->protocol = $protocol; |
| 21 | $this->href = $href; |
| 22 | $this->classes = $classes; |
| 23 | $this->ids = $ids; |
| 24 | } |
| 25 | public function links() : ?Collection |
| 26 | { |
| 27 | return self::get_database_records()->filter(function ($link_rule) { |
| 28 | return $link_rule->is_active(); |
| 29 | })->filter(function ($link_rule) { |
| 30 | return $this->is_match($link_rule); |
| 31 | })->values(); |
| 32 | } |
| 33 | private function is_match($link_rule) : bool |
| 34 | { |
| 35 | switch ($link_rule->type()) { |
| 36 | case 'class': |
| 37 | return $this->is_matching_class($link_rule); |
| 38 | case 'id': |
| 39 | return $this->is_matching_id($link_rule); |
| 40 | case 'domain': |
| 41 | return $this->is_matching_domain($link_rule); |
| 42 | case 'extension': |
| 43 | return $this->is_matching_extension($link_rule); |
| 44 | case 'subdirectory': |
| 45 | return $this->is_matching_subdirectory($link_rule); |
| 46 | case 'protocol': |
| 47 | return $this->is_matching_protocol($link_rule); |
| 48 | case 'external': |
| 49 | return $this->is_matching_external($link_rule); |
| 50 | default: |
| 51 | return \false; |
| 52 | } |
| 53 | } |
| 54 | private function is_matching_class($link_rule) : bool |
| 55 | { |
| 56 | if ($this->classes === "") { |
| 57 | return \false; |
| 58 | } |
| 59 | return Collection::make(\explode(' ', $this->classes))->contains(function ($value, $key) use($link_rule) { |
| 60 | return $link_rule->value() === $value; |
| 61 | }); |
| 62 | } |
| 63 | private function is_matching_id($link_rule) : bool |
| 64 | { |
| 65 | if ($this->ids === "") { |
| 66 | return \false; |
| 67 | } |
| 68 | return Collection::make(\explode(' ', $this->ids))->contains(function ($value, $key) use($link_rule) { |
| 69 | return $link_rule->value() === $value; |
| 70 | }); |
| 71 | } |
| 72 | private function is_matching_domain($link_rule) : bool |
| 73 | { |
| 74 | if (\is_null($this->href)) { |
| 75 | return \false; |
| 76 | } |
| 77 | $url = new URL($this->href); |
| 78 | if (!$url->is_valid_url()) { |
| 79 | return \false; |
| 80 | } |
| 81 | return $link_rule->value() === $url->get_domain(); |
| 82 | } |
| 83 | private function is_matching_extension($link_rule) : bool |
| 84 | { |
| 85 | if (\is_null($this->href)) { |
| 86 | return \false; |
| 87 | } |
| 88 | $url = new URL($this->href); |
| 89 | if (!$url->is_valid_url()) { |
| 90 | return \false; |
| 91 | } |
| 92 | return $link_rule->value() === $url->get_extension(); |
| 93 | } |
| 94 | private function is_matching_subdirectory($link_rule) : bool |
| 95 | { |
| 96 | if (\is_null($this->href)) { |
| 97 | return \false; |
| 98 | } |
| 99 | $url = URL::new($this->href); |
| 100 | $site_url = URL::new(\get_site_url()); |
| 101 | if (!$url->is_valid_url() || $url->get_domain() !== $site_url->get_domain()) { |
| 102 | return \false; |
| 103 | } |
| 104 | $path = $url->get_path(); |
| 105 | $path_parts = Collection::make(\explode('/', $path))->filter()->values(); |
| 106 | if ($path_parts->isEmpty()) { |
| 107 | return \false; |
| 108 | } |
| 109 | return $link_rule->value() === $path_parts->first(); |
| 110 | } |
| 111 | private function is_matching_protocol($link_rule) : bool |
| 112 | { |
| 113 | if (\is_null($this->href)) { |
| 114 | return \false; |
| 115 | } |
| 116 | return $this->protocol === $link_rule->value(); |
| 117 | } |
| 118 | private function is_matching_external($link_rule) : bool |
| 119 | { |
| 120 | if (\is_null($this->href)) { |
| 121 | return \false; |
| 122 | } |
| 123 | $site_url = URL::new(\get_site_url()); |
| 124 | $link_url = URL::new($this->href); |
| 125 | // Only track valid http/https URLs and not other protocols like mailto:, tel:, etc |
| 126 | if (!$link_url->is_valid_url()) { |
| 127 | return \false; |
| 128 | } |
| 129 | return $link_url->get_domain() !== $site_url->get_domain(); |
| 130 | } |
| 131 | public static function new(?string $protocol, ?string $href, string $classes, ?string $id) : self |
| 132 | { |
| 133 | return new self($protocol, $href, $classes, $id); |
| 134 | } |
| 135 | public static function link_rules() : Collection |
| 136 | { |
| 137 | return self::get_database_records(); |
| 138 | } |
| 139 | public static function active_link_rules() : Collection |
| 140 | { |
| 141 | return self::get_database_records()->filter(function ($link_rule) { |
| 142 | return $link_rule->is_active(); |
| 143 | })->values(); |
| 144 | } |
| 145 | public static function inactive_link_rules() : Collection |
| 146 | { |
| 147 | return self::get_database_records()->filter(function ($link_rule) { |
| 148 | return !$link_rule->is_active(); |
| 149 | })->values(); |
| 150 | } |
| 151 | public static function cached_link_rules() : array |
| 152 | { |
| 153 | $cached_rules = \get_option('iawp_link_rules', \false); |
| 154 | if (!\is_array($cached_rules)) { |
| 155 | $link_rules = \IAWP\Click_Tracking\Link_Rule_Finder::active_link_rules()->map(function (\IAWP\Click_Tracking\Link_Rule $link_rule) { |
| 156 | return ['type' => $link_rule->type(), 'value' => $link_rule->value()]; |
| 157 | }); |
| 158 | \update_option('iawp_link_rules', $link_rules->all()); |
| 159 | } |
| 160 | return \get_option('iawp_link_rules'); |
| 161 | } |
| 162 | public static function require_cleared_cache() |
| 163 | { |
| 164 | \delete_option('iawp_click_tracking_cache_cleared'); |
| 165 | \delete_option('iawp_link_rules'); |
| 166 | } |
| 167 | private static function get_database_records() : Collection |
| 168 | { |
| 169 | if (\is_null(static::$database_records)) { |
| 170 | $records = Illuminate_Builder::new()->from(Tables::link_rules())->orderBy('position')->orderByDesc('created_at')->get(); |
| 171 | static::$database_records = $records->map(function ($link_rule) { |
| 172 | return new \IAWP\Click_Tracking\Link_Rule($link_rule); |
| 173 | }); |
| 174 | } |
| 175 | return static::$database_records; |
| 176 | } |
| 177 | } |
| 178 |