@@ -6,99 +6,99 @@ |
||
6 | 6 | |
7 | 7 | class DigitalPodcast extends AbstractVendor implements VendorInterface |
8 | 8 | { |
9 | - /** |
|
10 | - * @var string |
|
11 | - */ |
|
12 | - const APP_ID = "podcastsearchdemo"; |
|
13 | - |
|
14 | - /** |
|
15 | - * @var string |
|
16 | - */ |
|
17 | - const SEARCH_URL = "http://api.digitalpodcast.com/v2r/search"; |
|
18 | - |
|
19 | - /** |
|
20 | - * @var string |
|
21 | - */ |
|
22 | - const FORMAT = "rss"; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var int |
|
26 | - */ |
|
27 | - private $limit = 15; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var string |
|
31 | - */ |
|
32 | - private $defaultQuery = null; |
|
33 | - |
|
34 | - /** |
|
35 | - * DigitalPodcast constructor. |
|
36 | - */ |
|
37 | - public function __construct() |
|
38 | - { |
|
39 | - $this->setDefaultQuery(); |
|
40 | - } |
|
41 | - |
|
42 | - /** |
|
43 | - * @return int |
|
44 | - */ |
|
45 | - public function getLimit() |
|
46 | - { |
|
47 | - return $this->limit; |
|
48 | - } |
|
49 | - |
|
50 | - /** |
|
51 | - * @param int $limit |
|
52 | - */ |
|
53 | - public function setLimit($limit) |
|
54 | - { |
|
55 | - // `-1` being used here because the API returns 3 items when `results=2`. |
|
56 | - $this->limit = ((int) $limit - 1); |
|
57 | - } |
|
58 | - |
|
59 | - /** |
|
60 | - * @return void |
|
61 | - */ |
|
62 | - public function setDefaultQuery() |
|
63 | - { |
|
64 | - $this->defaultQuery = http_build_query([ |
|
65 | - 'results' => $this->limit, |
|
66 | - 'appid' => self::APP_ID, |
|
67 | - 'format' => self::FORMAT |
|
68 | - ]); |
|
69 | - } |
|
70 | - |
|
71 | - /** |
|
72 | - * @param string $value |
|
73 | - * @return string |
|
74 | - */ |
|
75 | - public function generateUrl($value) |
|
76 | - { |
|
77 | - $value = urlencode($value); |
|
78 | - $url = self::SEARCH_URL . "?keywords={$value}"; |
|
79 | - |
|
80 | - return $url . '&' . $this->defaultQuery; |
|
81 | - } |
|
82 | - |
|
83 | - /** |
|
84 | - * @param array $response |
|
85 | - * @return array |
|
86 | - */ |
|
87 | - public function build(array $response) |
|
88 | - { |
|
89 | - $xml = new SimpleXMLElement($response['search']); |
|
90 | - $xml = $xml->channel; |
|
91 | - |
|
92 | - $output['result_count'] = count($xml->item); |
|
93 | - |
|
94 | - foreach ($xml->item as $value) { |
|
95 | - $output['results'][] = [ |
|
96 | - 'title' => (string) $value->title, |
|
97 | - 'rss' => (string) $value->source, |
|
98 | - 'link' => (string) $value->link, |
|
99 | - ]; |
|
100 | - } |
|
101 | - |
|
102 | - return $output; |
|
103 | - } |
|
9 | + /** |
|
10 | + * @var string |
|
11 | + */ |
|
12 | + const APP_ID = "podcastsearchdemo"; |
|
13 | + |
|
14 | + /** |
|
15 | + * @var string |
|
16 | + */ |
|
17 | + const SEARCH_URL = "http://api.digitalpodcast.com/v2r/search"; |
|
18 | + |
|
19 | + /** |
|
20 | + * @var string |
|
21 | + */ |
|
22 | + const FORMAT = "rss"; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var int |
|
26 | + */ |
|
27 | + private $limit = 15; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var string |
|
31 | + */ |
|
32 | + private $defaultQuery = null; |
|
33 | + |
|
34 | + /** |
|
35 | + * DigitalPodcast constructor. |
|
36 | + */ |
|
37 | + public function __construct() |
|
38 | + { |
|
39 | + $this->setDefaultQuery(); |
|
40 | + } |
|
41 | + |
|
42 | + /** |
|
43 | + * @return int |
|
44 | + */ |
|
45 | + public function getLimit() |
|
46 | + { |
|
47 | + return $this->limit; |
|
48 | + } |
|
49 | + |
|
50 | + /** |
|
51 | + * @param int $limit |
|
52 | + */ |
|
53 | + public function setLimit($limit) |
|
54 | + { |
|
55 | + // `-1` being used here because the API returns 3 items when `results=2`. |
|
56 | + $this->limit = ((int) $limit - 1); |
|
57 | + } |
|
58 | + |
|
59 | + /** |
|
60 | + * @return void |
|
61 | + */ |
|
62 | + public function setDefaultQuery() |
|
63 | + { |
|
64 | + $this->defaultQuery = http_build_query([ |
|
65 | + 'results' => $this->limit, |
|
66 | + 'appid' => self::APP_ID, |
|
67 | + 'format' => self::FORMAT |
|
68 | + ]); |
|
69 | + } |
|
70 | + |
|
71 | + /** |
|
72 | + * @param string $value |
|
73 | + * @return string |
|
74 | + */ |
|
75 | + public function generateUrl($value) |
|
76 | + { |
|
77 | + $value = urlencode($value); |
|
78 | + $url = self::SEARCH_URL . "?keywords={$value}"; |
|
79 | + |
|
80 | + return $url . '&' . $this->defaultQuery; |
|
81 | + } |
|
82 | + |
|
83 | + /** |
|
84 | + * @param array $response |
|
85 | + * @return array |
|
86 | + */ |
|
87 | + public function build(array $response) |
|
88 | + { |
|
89 | + $xml = new SimpleXMLElement($response['search']); |
|
90 | + $xml = $xml->channel; |
|
91 | + |
|
92 | + $output['result_count'] = count($xml->item); |
|
93 | + |
|
94 | + foreach ($xml->item as $value) { |
|
95 | + $output['results'][] = [ |
|
96 | + 'title' => (string) $value->title, |
|
97 | + 'rss' => (string) $value->source, |
|
98 | + 'link' => (string) $value->link, |
|
99 | + ]; |
|
100 | + } |
|
101 | + |
|
102 | + return $output; |
|
103 | + } |
|
104 | 104 | } |
@@ -7,153 +7,153 @@ |
||
7 | 7 | |
8 | 8 | abstract class AbstractVendor |
9 | 9 | { |
10 | - /** |
|
11 | - * @param SimpleXMLElement $feed |
|
12 | - * |
|
13 | - * @return array |
|
14 | - */ |
|
15 | - public function buildFeed(SimpleXMLElement $feed) |
|
16 | - { |
|
17 | - $output = [ |
|
18 | - 'title' => (string) $feed->channel->title, |
|
19 | - 'description' => (string) $feed->channel->description, |
|
20 | - 'summary' => (string) $this->getValueByPath($feed->channel, "summary"), |
|
21 | - 'image' => (string) $feed->channel->image->url, |
|
22 | - 'site' => (string) $feed->channel->link, |
|
23 | - 'author' => (string) $this->getValueByPath($feed->channel, "author"), |
|
24 | - 'language' => (string) $feed->channel->language, |
|
25 | - 'categories' => $this->fetchCategories($feed->channel), |
|
26 | - 'episode_count' => (int) count($feed->channel->item), |
|
27 | - 'episodes' => $this->getEpisodes($feed->channel) |
|
28 | - ]; |
|
29 | - |
|
30 | - return $output; |
|
31 | - } |
|
32 | - |
|
33 | - /** |
|
34 | - * @param SimpleXMLElement|mixed $channel |
|
35 | - * |
|
36 | - * @return array |
|
37 | - */ |
|
38 | - protected function getEpisodes($channel) |
|
39 | - { |
|
40 | - $items = []; |
|
41 | - foreach ($channel->item as $value) { |
|
42 | - $items[] = [ |
|
43 | - 'title' => (string) $value->title, |
|
44 | - 'mp3' => $this->getAudioUrl($value), |
|
45 | - 'size' => $this->getEpisodeSize($value), |
|
46 | - 'duration' => $this->getEpisodeDuration($value), |
|
47 | - 'description' => (string) $value->description, |
|
48 | - 'link' => (string) $value->link, |
|
49 | - 'image' => $this->getEpisodeImage($value, $channel), |
|
50 | - 'published_at' => $this->getPublishedDate($value), |
|
51 | - ]; |
|
52 | - } |
|
53 | - |
|
54 | - return $items; |
|
55 | - } |
|
56 | - |
|
57 | - /** |
|
58 | - * @param SimpleXMLElement $value |
|
59 | - * |
|
60 | - * @return null|string |
|
61 | - */ |
|
62 | - protected function getAudioUrl($value) |
|
63 | - { |
|
64 | - return isset($value->enclosure) ? (string) $value->enclosure->attributes()->url : null; |
|
65 | - } |
|
66 | - |
|
67 | - /** |
|
68 | - * @param SimpleXMLElement $value |
|
69 | - * |
|
70 | - * @return int |
|
71 | - */ |
|
72 | - protected function getEpisodeSize($value) |
|
73 | - { |
|
74 | - return isset($value->enclosure) ? (int) $value->enclosure->attributes()->length : 0; |
|
75 | - } |
|
76 | - |
|
77 | - /** |
|
78 | - * @param SimpleXMLElement $item |
|
79 | - * |
|
80 | - * @return string |
|
81 | - */ |
|
82 | - protected function getPublishedDate($item) |
|
83 | - { |
|
84 | - $published_at = new DateTime(); |
|
85 | - $published_at->setTimestamp(strtotime($item->pubDate)); |
|
86 | - |
|
87 | - return $published_at->format('Y-m-d H:i:s'); |
|
88 | - } |
|
89 | - |
|
90 | - /** |
|
91 | - * @param SimpleXMLElement|mixed $item |
|
92 | - * @param string $path |
|
93 | - * |
|
94 | - * @return SimpleXMLElement |
|
95 | - */ |
|
96 | - protected function getValueByPath($item, $path) |
|
97 | - { |
|
98 | - return empty($item->xpath("itunes:{$path}")) ? null : |
|
99 | - $item->xpath("itunes:{$path}")[0]; |
|
100 | - } |
|
101 | - |
|
102 | - /** |
|
103 | - * @param SimpleXMLElement|mixed $item |
|
104 | - * |
|
105 | - * @return int |
|
106 | - */ |
|
107 | - protected function getEpisodeDuration($item) |
|
108 | - { |
|
109 | - $duration = (string) $this->getValueByPath($item, "duration"); |
|
110 | - |
|
111 | - $durationArray = explode(":", $duration); |
|
112 | - if (count($durationArray) > 1) { |
|
113 | - sscanf($duration, "%d:%d:%d", $hours, $minutes, $seconds); |
|
114 | - |
|
115 | - $duration = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes; |
|
116 | - } |
|
117 | - |
|
118 | - return (int) $duration; |
|
119 | - } |
|
120 | - |
|
121 | - /** |
|
122 | - * @param SimpleXMLElement $item |
|
123 | - * |
|
124 | - * @param SimpleXMLElement $channel |
|
125 | - * |
|
126 | - * @return string |
|
127 | - */ |
|
128 | - protected function getEpisodeImage($item, $channel) |
|
129 | - { |
|
130 | - $xmlImage = $this->getValueByPath($item, "image"); |
|
131 | - |
|
132 | - return $xmlImage ? (string) $xmlImage->attributes()->href : (string) $channel->image->url; |
|
133 | - } |
|
134 | - |
|
135 | - /** |
|
136 | - * @param SimpleXMLElement|mixed $channel |
|
137 | - * |
|
138 | - * @return array |
|
139 | - */ |
|
140 | - protected function fetchCategories($channel) |
|
141 | - { |
|
142 | - $categories = $channel->xpath('itunes:category'); |
|
143 | - |
|
144 | - $items = []; |
|
145 | - foreach ($categories as $category) { |
|
146 | - $item = ['title' => (string) $category->attributes()->text, 'children' => []]; |
|
147 | - |
|
148 | - if (! empty($category->xpath('itunes:category'))) { |
|
149 | - $inner = $this->fetchCategories($category); |
|
150 | - |
|
151 | - $item['children'] = $inner; |
|
152 | - } |
|
153 | - |
|
154 | - $items[] = $item; |
|
155 | - } |
|
156 | - |
|
157 | - return $items; |
|
158 | - } |
|
10 | + /** |
|
11 | + * @param SimpleXMLElement $feed |
|
12 | + * |
|
13 | + * @return array |
|
14 | + */ |
|
15 | + public function buildFeed(SimpleXMLElement $feed) |
|
16 | + { |
|
17 | + $output = [ |
|
18 | + 'title' => (string) $feed->channel->title, |
|
19 | + 'description' => (string) $feed->channel->description, |
|
20 | + 'summary' => (string) $this->getValueByPath($feed->channel, "summary"), |
|
21 | + 'image' => (string) $feed->channel->image->url, |
|
22 | + 'site' => (string) $feed->channel->link, |
|
23 | + 'author' => (string) $this->getValueByPath($feed->channel, "author"), |
|
24 | + 'language' => (string) $feed->channel->language, |
|
25 | + 'categories' => $this->fetchCategories($feed->channel), |
|
26 | + 'episode_count' => (int) count($feed->channel->item), |
|
27 | + 'episodes' => $this->getEpisodes($feed->channel) |
|
28 | + ]; |
|
29 | + |
|
30 | + return $output; |
|
31 | + } |
|
32 | + |
|
33 | + /** |
|
34 | + * @param SimpleXMLElement|mixed $channel |
|
35 | + * |
|
36 | + * @return array |
|
37 | + */ |
|
38 | + protected function getEpisodes($channel) |
|
39 | + { |
|
40 | + $items = []; |
|
41 | + foreach ($channel->item as $value) { |
|
42 | + $items[] = [ |
|
43 | + 'title' => (string) $value->title, |
|
44 | + 'mp3' => $this->getAudioUrl($value), |
|
45 | + 'size' => $this->getEpisodeSize($value), |
|
46 | + 'duration' => $this->getEpisodeDuration($value), |
|
47 | + 'description' => (string) $value->description, |
|
48 | + 'link' => (string) $value->link, |
|
49 | + 'image' => $this->getEpisodeImage($value, $channel), |
|
50 | + 'published_at' => $this->getPublishedDate($value), |
|
51 | + ]; |
|
52 | + } |
|
53 | + |
|
54 | + return $items; |
|
55 | + } |
|
56 | + |
|
57 | + /** |
|
58 | + * @param SimpleXMLElement $value |
|
59 | + * |
|
60 | + * @return null|string |
|
61 | + */ |
|
62 | + protected function getAudioUrl($value) |
|
63 | + { |
|
64 | + return isset($value->enclosure) ? (string) $value->enclosure->attributes()->url : null; |
|
65 | + } |
|
66 | + |
|
67 | + /** |
|
68 | + * @param SimpleXMLElement $value |
|
69 | + * |
|
70 | + * @return int |
|
71 | + */ |
|
72 | + protected function getEpisodeSize($value) |
|
73 | + { |
|
74 | + return isset($value->enclosure) ? (int) $value->enclosure->attributes()->length : 0; |
|
75 | + } |
|
76 | + |
|
77 | + /** |
|
78 | + * @param SimpleXMLElement $item |
|
79 | + * |
|
80 | + * @return string |
|
81 | + */ |
|
82 | + protected function getPublishedDate($item) |
|
83 | + { |
|
84 | + $published_at = new DateTime(); |
|
85 | + $published_at->setTimestamp(strtotime($item->pubDate)); |
|
86 | + |
|
87 | + return $published_at->format('Y-m-d H:i:s'); |
|
88 | + } |
|
89 | + |
|
90 | + /** |
|
91 | + * @param SimpleXMLElement|mixed $item |
|
92 | + * @param string $path |
|
93 | + * |
|
94 | + * @return SimpleXMLElement |
|
95 | + */ |
|
96 | + protected function getValueByPath($item, $path) |
|
97 | + { |
|
98 | + return empty($item->xpath("itunes:{$path}")) ? null : |
|
99 | + $item->xpath("itunes:{$path}")[0]; |
|
100 | + } |
|
101 | + |
|
102 | + /** |
|
103 | + * @param SimpleXMLElement|mixed $item |
|
104 | + * |
|
105 | + * @return int |
|
106 | + */ |
|
107 | + protected function getEpisodeDuration($item) |
|
108 | + { |
|
109 | + $duration = (string) $this->getValueByPath($item, "duration"); |
|
110 | + |
|
111 | + $durationArray = explode(":", $duration); |
|
112 | + if (count($durationArray) > 1) { |
|
113 | + sscanf($duration, "%d:%d:%d", $hours, $minutes, $seconds); |
|
114 | + |
|
115 | + $duration = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes; |
|
116 | + } |
|
117 | + |
|
118 | + return (int) $duration; |
|
119 | + } |
|
120 | + |
|
121 | + /** |
|
122 | + * @param SimpleXMLElement $item |
|
123 | + * |
|
124 | + * @param SimpleXMLElement $channel |
|
125 | + * |
|
126 | + * @return string |
|
127 | + */ |
|
128 | + protected function getEpisodeImage($item, $channel) |
|
129 | + { |
|
130 | + $xmlImage = $this->getValueByPath($item, "image"); |
|
131 | + |
|
132 | + return $xmlImage ? (string) $xmlImage->attributes()->href : (string) $channel->image->url; |
|
133 | + } |
|
134 | + |
|
135 | + /** |
|
136 | + * @param SimpleXMLElement|mixed $channel |
|
137 | + * |
|
138 | + * @return array |
|
139 | + */ |
|
140 | + protected function fetchCategories($channel) |
|
141 | + { |
|
142 | + $categories = $channel->xpath('itunes:category'); |
|
143 | + |
|
144 | + $items = []; |
|
145 | + foreach ($categories as $category) { |
|
146 | + $item = ['title' => (string) $category->attributes()->text, 'children' => []]; |
|
147 | + |
|
148 | + if (! empty($category->xpath('itunes:category'))) { |
|
149 | + $inner = $this->fetchCategories($category); |
|
150 | + |
|
151 | + $item['children'] = $inner; |
|
152 | + } |
|
153 | + |
|
154 | + $items[] = $item; |
|
155 | + } |
|
156 | + |
|
157 | + return $items; |
|
158 | + } |
|
159 | 159 | } |
@@ -145,7 +145,7 @@ |
||
145 | 145 | foreach ($categories as $category) { |
146 | 146 | $item = ['title' => (string) $category->attributes()->text, 'children' => []]; |
147 | 147 | |
148 | - if (! empty($category->xpath('itunes:category'))) { |
|
148 | + if (!empty($category->xpath('itunes:category'))) { |
|
149 | 149 | $inner = $this->fetchCategories($category); |
150 | 150 | |
151 | 151 | $item['children'] = $inner; |
@@ -5,106 +5,106 @@ |
||
5 | 5 | |
6 | 6 | class Itunes extends AbstractVendor implements VendorInterface |
7 | 7 | { |
8 | - /** |
|
9 | - * @var string |
|
10 | - */ |
|
11 | - const SEARCH_URL = "https://itunes.apple.com/search"; |
|
12 | - |
|
13 | - /** |
|
14 | - * @var string |
|
15 | - */ |
|
16 | - const LOOKUP_URL = "https://itunes.apple.com/lookup"; |
|
17 | - |
|
18 | - /** |
|
19 | - * @var string |
|
20 | - */ |
|
21 | - const ENTITY = "podcast"; |
|
22 | - |
|
23 | - /** |
|
24 | - * @var string |
|
25 | - */ |
|
26 | - const MEDIA = "podcast"; |
|
27 | - |
|
28 | - /** |
|
29 | - * @var int |
|
30 | - */ |
|
31 | - private $limit = 15; |
|
32 | - |
|
33 | - /** |
|
34 | - * @var string |
|
35 | - */ |
|
36 | - private $defaultQuery = null; |
|
37 | - |
|
38 | - /** |
|
39 | - * Itunes constructor. |
|
40 | - */ |
|
41 | - public function __construct() |
|
42 | - { |
|
43 | - $this->setDefaultQuery(); |
|
44 | - } |
|
45 | - |
|
46 | - /** |
|
47 | - * @return int |
|
48 | - */ |
|
49 | - public function getLimit() |
|
50 | - { |
|
51 | - return $this->limit; |
|
52 | - } |
|
53 | - |
|
54 | - /** |
|
55 | - * @param int $limit |
|
56 | - */ |
|
57 | - public function setLimit($limit) |
|
58 | - { |
|
59 | - $this->limit = (int) $limit; |
|
60 | - } |
|
61 | - |
|
62 | - /** |
|
63 | - * @return void |
|
64 | - */ |
|
65 | - public function setDefaultQuery() |
|
66 | - { |
|
67 | - $this->defaultQuery = http_build_query([ |
|
68 | - 'limit' => $this->limit, |
|
69 | - 'entity' => self::ENTITY, |
|
70 | - 'media' => self::MEDIA |
|
71 | - ]); |
|
72 | - } |
|
73 | - |
|
74 | - /** |
|
75 | - * @param string $value |
|
76 | - * @return string |
|
77 | - */ |
|
78 | - public function generateUrl($value) |
|
79 | - { |
|
80 | - $value = is_string($value) ? urlencode($value) : $value; |
|
81 | - $url = is_int($value) ? self::LOOKUP_URL . "?id={$value}" : self::SEARCH_URL . "?term={$value}"; |
|
82 | - |
|
83 | - return $url . '&' . $this->defaultQuery; |
|
84 | - } |
|
85 | - |
|
86 | - /** |
|
87 | - * @param array $response |
|
88 | - * @return array |
|
89 | - */ |
|
90 | - public function build(array $response) |
|
91 | - { |
|
92 | - $response = json_decode($response['search']); |
|
93 | - $output['result_count'] = $response->resultCount; |
|
94 | - |
|
95 | - foreach ($response->results as $value) { |
|
96 | - $output['results'][] = [ |
|
97 | - 'itunes_id' => $value->collectionId, |
|
98 | - 'author' => $value->artistName, |
|
99 | - 'title' => $value->collectionName, |
|
100 | - 'episodes' => $value->trackCount, |
|
101 | - 'image' => $value->artworkUrl100, |
|
102 | - 'rss' => $value->feedUrl, |
|
103 | - 'itunes' => $value->collectionViewUrl, |
|
104 | - 'genre' => $value->primaryGenreName, |
|
105 | - ]; |
|
106 | - } |
|
107 | - |
|
108 | - return $output; |
|
109 | - } |
|
8 | + /** |
|
9 | + * @var string |
|
10 | + */ |
|
11 | + const SEARCH_URL = "https://itunes.apple.com/search"; |
|
12 | + |
|
13 | + /** |
|
14 | + * @var string |
|
15 | + */ |
|
16 | + const LOOKUP_URL = "https://itunes.apple.com/lookup"; |
|
17 | + |
|
18 | + /** |
|
19 | + * @var string |
|
20 | + */ |
|
21 | + const ENTITY = "podcast"; |
|
22 | + |
|
23 | + /** |
|
24 | + * @var string |
|
25 | + */ |
|
26 | + const MEDIA = "podcast"; |
|
27 | + |
|
28 | + /** |
|
29 | + * @var int |
|
30 | + */ |
|
31 | + private $limit = 15; |
|
32 | + |
|
33 | + /** |
|
34 | + * @var string |
|
35 | + */ |
|
36 | + private $defaultQuery = null; |
|
37 | + |
|
38 | + /** |
|
39 | + * Itunes constructor. |
|
40 | + */ |
|
41 | + public function __construct() |
|
42 | + { |
|
43 | + $this->setDefaultQuery(); |
|
44 | + } |
|
45 | + |
|
46 | + /** |
|
47 | + * @return int |
|
48 | + */ |
|
49 | + public function getLimit() |
|
50 | + { |
|
51 | + return $this->limit; |
|
52 | + } |
|
53 | + |
|
54 | + /** |
|
55 | + * @param int $limit |
|
56 | + */ |
|
57 | + public function setLimit($limit) |
|
58 | + { |
|
59 | + $this->limit = (int) $limit; |
|
60 | + } |
|
61 | + |
|
62 | + /** |
|
63 | + * @return void |
|
64 | + */ |
|
65 | + public function setDefaultQuery() |
|
66 | + { |
|
67 | + $this->defaultQuery = http_build_query([ |
|
68 | + 'limit' => $this->limit, |
|
69 | + 'entity' => self::ENTITY, |
|
70 | + 'media' => self::MEDIA |
|
71 | + ]); |
|
72 | + } |
|
73 | + |
|
74 | + /** |
|
75 | + * @param string $value |
|
76 | + * @return string |
|
77 | + */ |
|
78 | + public function generateUrl($value) |
|
79 | + { |
|
80 | + $value = is_string($value) ? urlencode($value) : $value; |
|
81 | + $url = is_int($value) ? self::LOOKUP_URL . "?id={$value}" : self::SEARCH_URL . "?term={$value}"; |
|
82 | + |
|
83 | + return $url . '&' . $this->defaultQuery; |
|
84 | + } |
|
85 | + |
|
86 | + /** |
|
87 | + * @param array $response |
|
88 | + * @return array |
|
89 | + */ |
|
90 | + public function build(array $response) |
|
91 | + { |
|
92 | + $response = json_decode($response['search']); |
|
93 | + $output['result_count'] = $response->resultCount; |
|
94 | + |
|
95 | + foreach ($response->results as $value) { |
|
96 | + $output['results'][] = [ |
|
97 | + 'itunes_id' => $value->collectionId, |
|
98 | + 'author' => $value->artistName, |
|
99 | + 'title' => $value->collectionName, |
|
100 | + 'episodes' => $value->trackCount, |
|
101 | + 'image' => $value->artworkUrl100, |
|
102 | + 'rss' => $value->feedUrl, |
|
103 | + 'itunes' => $value->collectionViewUrl, |
|
104 | + 'genre' => $value->primaryGenreName, |
|
105 | + ]; |
|
106 | + } |
|
107 | + |
|
108 | + return $output; |
|
109 | + } |
|
110 | 110 | } |
@@ -6,29 +6,29 @@ |
||
6 | 6 | |
7 | 7 | class Xml |
8 | 8 | { |
9 | - /** |
|
10 | - * @param string $xml |
|
11 | - * |
|
12 | - * @return string |
|
13 | - * @throws Exception |
|
14 | - */ |
|
15 | - public static function repair($xml) |
|
16 | - { |
|
17 | - if (class_exists("Tidy") === false) { |
|
18 | - throw new Exception("Tidy Class not found", 500); |
|
19 | - } |
|
9 | + /** |
|
10 | + * @param string $xml |
|
11 | + * |
|
12 | + * @return string |
|
13 | + * @throws Exception |
|
14 | + */ |
|
15 | + public static function repair($xml) |
|
16 | + { |
|
17 | + if (class_exists("Tidy") === false) { |
|
18 | + throw new Exception("Tidy Class not found", 500); |
|
19 | + } |
|
20 | 20 | |
21 | - $config = [ |
|
22 | - 'indent' => true, |
|
23 | - 'input-xml' => true, |
|
24 | - 'output-xml' => true, |
|
25 | - 'wrap' => false |
|
26 | - ]; |
|
21 | + $config = [ |
|
22 | + 'indent' => true, |
|
23 | + 'input-xml' => true, |
|
24 | + 'output-xml' => true, |
|
25 | + 'wrap' => false |
|
26 | + ]; |
|
27 | 27 | |
28 | - $xml_repaired = new Tidy(); |
|
29 | - $xml_repaired->parseString($xml, $config, 'utf8'); |
|
30 | - $xml_repaired->cleanRepair(); |
|
28 | + $xml_repaired = new Tidy(); |
|
29 | + $xml_repaired->parseString($xml, $config, 'utf8'); |
|
30 | + $xml_repaired->cleanRepair(); |
|
31 | 31 | |
32 | - return $xml_repaired; |
|
33 | - } |
|
32 | + return $xml_repaired; |
|
33 | + } |
|
34 | 34 | } |
@@ -3,58 +3,58 @@ |
||
3 | 3 | |
4 | 4 | class Request |
5 | 5 | { |
6 | - /** |
|
7 | - * @var string |
|
8 | - */ |
|
9 | - private $contentType; |
|
10 | - |
|
11 | - /** |
|
12 | - * @var int |
|
13 | - */ |
|
14 | - private $statusCode; |
|
15 | - |
|
16 | - /** |
|
17 | - * @param string $url |
|
18 | - * @param array $options |
|
19 | - * |
|
20 | - * @return string |
|
21 | - */ |
|
22 | - public function create($url, array $options = []) |
|
23 | - { |
|
24 | - $request = curl_init($url); |
|
25 | - |
|
26 | - $default_options = [ |
|
27 | - CURLOPT_FAILONERROR => true, |
|
28 | - CURLOPT_FOLLOWLOCATION => true, |
|
29 | - CURLOPT_RETURNTRANSFER => true, |
|
30 | - CURLOPT_TIMEOUT => 15, |
|
31 | - CURLOPT_SSL_VERIFYPEER => 0, |
|
32 | - CURLINFO_HEADER_OUT => true |
|
33 | - ] + $options; |
|
34 | - |
|
35 | - curl_setopt_array($request, $default_options); |
|
36 | - |
|
37 | - $result = curl_exec($request); |
|
38 | - $this->statusCode = curl_getinfo($request, CURLINFO_HTTP_CODE); |
|
39 | - $this->contentType = curl_getinfo($request, CURLINFO_CONTENT_TYPE); |
|
40 | - curl_close($request); |
|
41 | - |
|
42 | - return $result; |
|
43 | - } |
|
44 | - |
|
45 | - /** |
|
46 | - * @return int |
|
47 | - */ |
|
48 | - public function getStatusCode() |
|
49 | - { |
|
50 | - return $this->statusCode; |
|
51 | - } |
|
52 | - |
|
53 | - /** |
|
54 | - * @return string |
|
55 | - */ |
|
56 | - public function getContentType() |
|
57 | - { |
|
58 | - return $this->contentType; |
|
59 | - } |
|
6 | + /** |
|
7 | + * @var string |
|
8 | + */ |
|
9 | + private $contentType; |
|
10 | + |
|
11 | + /** |
|
12 | + * @var int |
|
13 | + */ |
|
14 | + private $statusCode; |
|
15 | + |
|
16 | + /** |
|
17 | + * @param string $url |
|
18 | + * @param array $options |
|
19 | + * |
|
20 | + * @return string |
|
21 | + */ |
|
22 | + public function create($url, array $options = []) |
|
23 | + { |
|
24 | + $request = curl_init($url); |
|
25 | + |
|
26 | + $default_options = [ |
|
27 | + CURLOPT_FAILONERROR => true, |
|
28 | + CURLOPT_FOLLOWLOCATION => true, |
|
29 | + CURLOPT_RETURNTRANSFER => true, |
|
30 | + CURLOPT_TIMEOUT => 15, |
|
31 | + CURLOPT_SSL_VERIFYPEER => 0, |
|
32 | + CURLINFO_HEADER_OUT => true |
|
33 | + ] + $options; |
|
34 | + |
|
35 | + curl_setopt_array($request, $default_options); |
|
36 | + |
|
37 | + $result = curl_exec($request); |
|
38 | + $this->statusCode = curl_getinfo($request, CURLINFO_HTTP_CODE); |
|
39 | + $this->contentType = curl_getinfo($request, CURLINFO_CONTENT_TYPE); |
|
40 | + curl_close($request); |
|
41 | + |
|
42 | + return $result; |
|
43 | + } |
|
44 | + |
|
45 | + /** |
|
46 | + * @return int |
|
47 | + */ |
|
48 | + public function getStatusCode() |
|
49 | + { |
|
50 | + return $this->statusCode; |
|
51 | + } |
|
52 | + |
|
53 | + /** |
|
54 | + * @return string |
|
55 | + */ |
|
56 | + public function getContentType() |
|
57 | + { |
|
58 | + return $this->contentType; |
|
59 | + } |
|
60 | 60 | } |
@@ -7,81 +7,81 @@ |
||
7 | 7 | |
8 | 8 | class ScrapePodcast |
9 | 9 | { |
10 | - /** |
|
11 | - * @var VendorInterface |
|
12 | - */ |
|
13 | - protected $vendor; |
|
10 | + /** |
|
11 | + * @var VendorInterface |
|
12 | + */ |
|
13 | + protected $vendor; |
|
14 | 14 | |
15 | - /** |
|
16 | - * @var int |
|
17 | - */ |
|
18 | - protected $count = 15; |
|
15 | + /** |
|
16 | + * @var int |
|
17 | + */ |
|
18 | + protected $count = 15; |
|
19 | 19 | |
20 | - /** |
|
21 | - * ScrapePodcast constructor. |
|
22 | - */ |
|
23 | - public function __construct() |
|
24 | - { |
|
25 | - $this->vendor = new Itunes(); |
|
26 | - } |
|
20 | + /** |
|
21 | + * ScrapePodcast constructor. |
|
22 | + */ |
|
23 | + public function __construct() |
|
24 | + { |
|
25 | + $this->vendor = new Itunes(); |
|
26 | + } |
|
27 | 27 | |
28 | - /** |
|
29 | - * @return ScrapePodcast |
|
30 | - */ |
|
31 | - public function itunes() |
|
32 | - { |
|
33 | - $this->vendor = new Itunes(); |
|
28 | + /** |
|
29 | + * @return ScrapePodcast |
|
30 | + */ |
|
31 | + public function itunes() |
|
32 | + { |
|
33 | + $this->vendor = new Itunes(); |
|
34 | 34 | |
35 | - return $this; |
|
36 | - } |
|
35 | + return $this; |
|
36 | + } |
|
37 | 37 | |
38 | - /** |
|
39 | - * @return ScrapePodcast |
|
40 | - */ |
|
41 | - public function digitalPodcast() |
|
42 | - { |
|
43 | - $this->vendor = new DigitalPodcast(); |
|
38 | + /** |
|
39 | + * @return ScrapePodcast |
|
40 | + */ |
|
41 | + public function digitalPodcast() |
|
42 | + { |
|
43 | + $this->vendor = new DigitalPodcast(); |
|
44 | 44 | |
45 | - return $this; |
|
46 | - } |
|
45 | + return $this; |
|
46 | + } |
|
47 | 47 | |
48 | - /** |
|
49 | - * @param int $count |
|
50 | - * |
|
51 | - * @return ScrapePodcast |
|
52 | - */ |
|
53 | - public function limit($count) |
|
54 | - { |
|
55 | - $this->count = $count; |
|
48 | + /** |
|
49 | + * @param int $count |
|
50 | + * |
|
51 | + * @return ScrapePodcast |
|
52 | + */ |
|
53 | + public function limit($count) |
|
54 | + { |
|
55 | + $this->count = $count; |
|
56 | 56 | |
57 | - return $this; |
|
58 | - } |
|
57 | + return $this; |
|
58 | + } |
|
59 | 59 | |
60 | - /** |
|
61 | - * @param string $term |
|
62 | - * |
|
63 | - * @return array |
|
64 | - */ |
|
65 | - public function search($term) |
|
66 | - { |
|
67 | - return $this->engine()->get($term); |
|
68 | - } |
|
60 | + /** |
|
61 | + * @param string $term |
|
62 | + * |
|
63 | + * @return array |
|
64 | + */ |
|
65 | + public function search($term) |
|
66 | + { |
|
67 | + return $this->engine()->get($term); |
|
68 | + } |
|
69 | 69 | |
70 | - /** |
|
71 | - * @param string $feed |
|
72 | - * |
|
73 | - * @return array |
|
74 | - */ |
|
75 | - public function feed($feed) |
|
76 | - { |
|
77 | - return $this->engine()->find($feed); |
|
78 | - } |
|
70 | + /** |
|
71 | + * @param string $feed |
|
72 | + * |
|
73 | + * @return array |
|
74 | + */ |
|
75 | + public function feed($feed) |
|
76 | + { |
|
77 | + return $this->engine()->find($feed); |
|
78 | + } |
|
79 | 79 | |
80 | - /** |
|
81 | - * @return PodcastScraper |
|
82 | - */ |
|
83 | - protected function engine() |
|
84 | - { |
|
85 | - return (new PodcastScraper($this->vendor))->limit($this->count); |
|
86 | - } |
|
80 | + /** |
|
81 | + * @return PodcastScraper |
|
82 | + */ |
|
83 | + protected function engine() |
|
84 | + { |
|
85 | + return (new PodcastScraper($this->vendor))->limit($this->count); |
|
86 | + } |
|
87 | 87 | } |
@@ -5,41 +5,41 @@ |
||
5 | 5 | |
6 | 6 | interface VendorInterface |
7 | 7 | { |
8 | - /** |
|
9 | - * @param string $value |
|
10 | - * |
|
11 | - * @return string |
|
12 | - */ |
|
13 | - public function generateUrl($value); |
|
8 | + /** |
|
9 | + * @param string $value |
|
10 | + * |
|
11 | + * @return string |
|
12 | + */ |
|
13 | + public function generateUrl($value); |
|
14 | 14 | |
15 | - /** |
|
16 | - * @param array $response |
|
17 | - * |
|
18 | - * @return array |
|
19 | - */ |
|
20 | - public function build(array $response); |
|
15 | + /** |
|
16 | + * @param array $response |
|
17 | + * |
|
18 | + * @return array |
|
19 | + */ |
|
20 | + public function build(array $response); |
|
21 | 21 | |
22 | - /** |
|
23 | - * @return void |
|
24 | - */ |
|
25 | - public function setDefaultQuery(); |
|
22 | + /** |
|
23 | + * @return void |
|
24 | + */ |
|
25 | + public function setDefaultQuery(); |
|
26 | 26 | |
27 | - /** |
|
28 | - * @return int |
|
29 | - */ |
|
30 | - public function getLimit(); |
|
27 | + /** |
|
28 | + * @return int |
|
29 | + */ |
|
30 | + public function getLimit(); |
|
31 | 31 | |
32 | - /** |
|
33 | - * @param int $limit |
|
34 | - * |
|
35 | - * @return void |
|
36 | - */ |
|
37 | - public function setLimit($limit); |
|
32 | + /** |
|
33 | + * @param int $limit |
|
34 | + * |
|
35 | + * @return void |
|
36 | + */ |
|
37 | + public function setLimit($limit); |
|
38 | 38 | |
39 | - /** |
|
40 | - * @param SimpleXMLElement $feed |
|
41 | - * |
|
42 | - * @return array |
|
43 | - */ |
|
44 | - public function buildFeed(SimpleXMLElement $feed); |
|
39 | + /** |
|
40 | + * @param SimpleXMLElement $feed |
|
41 | + * |
|
42 | + * @return array |
|
43 | + */ |
|
44 | + public function buildFeed(SimpleXMLElement $feed); |
|
45 | 45 | } |
@@ -10,11 +10,11 @@ |
||
10 | 10 | class ScrapePod extends Facade |
11 | 11 | { |
12 | 12 | |
13 | - /** |
|
14 | - * @return string |
|
15 | - */ |
|
16 | - public static function getFacadeAccessor() |
|
17 | - { |
|
18 | - return 'tzsk-scrape-pod'; |
|
19 | - } |
|
13 | + /** |
|
14 | + * @return string |
|
15 | + */ |
|
16 | + public static function getFacadeAccessor() |
|
17 | + { |
|
18 | + return 'tzsk-scrape-pod'; |
|
19 | + } |
|
20 | 20 | } |
@@ -9,142 +9,142 @@ |
||
9 | 9 | |
10 | 10 | class PodcastScraper |
11 | 11 | { |
12 | - /** |
|
13 | - * @var VendorInterface |
|
14 | - */ |
|
15 | - private $vendor; |
|
16 | - |
|
17 | - /** |
|
18 | - * @param VendorInterface $vendor |
|
19 | - */ |
|
20 | - public function __construct(VendorInterface $vendor) |
|
21 | - { |
|
22 | - $this->vendor = $vendor; |
|
23 | - } |
|
24 | - |
|
25 | - /** |
|
26 | - * @param string $value |
|
27 | - * @return array |
|
28 | - */ |
|
29 | - public function get($value) |
|
30 | - { |
|
31 | - if (strlen($value) < 1) { |
|
32 | - return $this->failedResponse("Search keyword cannot be empty"); |
|
33 | - } |
|
34 | - |
|
35 | - try { |
|
36 | - $response = $this->search(new Request, $value); |
|
37 | - return [ |
|
38 | - 'status' => true, |
|
39 | - 'data' => $this->vendor->build($response) |
|
40 | - ]; |
|
41 | - } catch (Exception $except) { |
|
42 | - return $this->failedResponse($except->getMessage()); |
|
43 | - } |
|
44 | - } |
|
45 | - |
|
46 | - /** |
|
47 | - * @param Request $request |
|
48 | - * @param string $value |
|
49 | - * @return array |
|
50 | - * @throws Exception |
|
51 | - */ |
|
52 | - private function search(Request $request, $value) |
|
53 | - { |
|
54 | - $response = $request->create($this->vendor->generateUrl($value)); |
|
55 | - |
|
56 | - if (is_null($response)) { |
|
57 | - throw new Exception("Request to Itunes API failed", $request->getStatusCode()); |
|
58 | - } |
|
59 | - |
|
60 | - return [ |
|
61 | - 'search' => $response, |
|
62 | - 'status' => true, |
|
63 | - ]; |
|
64 | - } |
|
65 | - |
|
66 | - /** |
|
67 | - * @param string $feedUrl |
|
68 | - * @return array |
|
69 | - */ |
|
70 | - public function find($feedUrl) |
|
71 | - { |
|
72 | - if (strlen($feedUrl) < 1) { |
|
73 | - return $this->failedResponse("Feed Url cannot be empty"); |
|
74 | - } |
|
75 | - |
|
76 | - try { |
|
77 | - return [ |
|
78 | - 'status' => true, |
|
79 | - 'data' => $this->vendor->buildFeed($this->getFeedFromUrl($feedUrl)) |
|
80 | - ]; |
|
81 | - } catch (Exception $except) { |
|
82 | - return $this->failedResponse($except->getMessage()); |
|
83 | - } |
|
84 | - } |
|
85 | - |
|
86 | - /** |
|
87 | - * @param int $limit |
|
88 | - * @return PodcastScraper |
|
89 | - */ |
|
90 | - public function limit($limit) |
|
91 | - { |
|
92 | - $this->vendor->setLimit($limit); |
|
93 | - $this->vendor->setDefaultQuery(); |
|
94 | - |
|
95 | - return $this; |
|
96 | - } |
|
97 | - |
|
98 | - /** |
|
99 | - * @param Request $request |
|
100 | - * @param string $feedUrl |
|
101 | - * @return array |
|
102 | - * @throws Exception |
|
103 | - */ |
|
104 | - private function read(Request $request, $feedUrl) |
|
105 | - { |
|
106 | - $output = $request->create($feedUrl); |
|
107 | - |
|
108 | - if (is_null($output)) { |
|
109 | - throw new Exception("Request to RSS failed", $request->getStatusCode()); |
|
110 | - } |
|
111 | - |
|
112 | - return [ |
|
113 | - 'feed' => $output, |
|
114 | - 'status' => true, |
|
115 | - ]; |
|
116 | - } |
|
117 | - |
|
118 | - /** |
|
119 | - * @param string $feedUrl |
|
120 | - * |
|
121 | - * @return mixed |
|
122 | - */ |
|
123 | - protected function getFeedFromUrl($feedUrl) |
|
124 | - { |
|
125 | - $response = $this->read(new Request, $feedUrl); |
|
126 | - |
|
127 | - libxml_use_internal_errors(true); |
|
128 | - |
|
129 | - try { |
|
130 | - $feed = new SimpleXMLElement($response['feed'], LIBXML_NOCDATA, false); |
|
131 | - } catch (Exception $except) { |
|
132 | - $feed = new SimpleXMLElement(Xml::repair($response['feed']), LIBXML_NOCDATA, false); |
|
133 | - } |
|
134 | - |
|
135 | - return $feed; |
|
136 | - } |
|
137 | - |
|
138 | - /** |
|
139 | - * @param string $message |
|
140 | - * |
|
141 | - * @return array |
|
142 | - */ |
|
143 | - protected function failedResponse($message) |
|
144 | - { |
|
145 | - return [ |
|
146 | - 'status' => false, |
|
147 | - 'message' => $message |
|
148 | - ]; |
|
149 | - } |
|
12 | + /** |
|
13 | + * @var VendorInterface |
|
14 | + */ |
|
15 | + private $vendor; |
|
16 | + |
|
17 | + /** |
|
18 | + * @param VendorInterface $vendor |
|
19 | + */ |
|
20 | + public function __construct(VendorInterface $vendor) |
|
21 | + { |
|
22 | + $this->vendor = $vendor; |
|
23 | + } |
|
24 | + |
|
25 | + /** |
|
26 | + * @param string $value |
|
27 | + * @return array |
|
28 | + */ |
|
29 | + public function get($value) |
|
30 | + { |
|
31 | + if (strlen($value) < 1) { |
|
32 | + return $this->failedResponse("Search keyword cannot be empty"); |
|
33 | + } |
|
34 | + |
|
35 | + try { |
|
36 | + $response = $this->search(new Request, $value); |
|
37 | + return [ |
|
38 | + 'status' => true, |
|
39 | + 'data' => $this->vendor->build($response) |
|
40 | + ]; |
|
41 | + } catch (Exception $except) { |
|
42 | + return $this->failedResponse($except->getMessage()); |
|
43 | + } |
|
44 | + } |
|
45 | + |
|
46 | + /** |
|
47 | + * @param Request $request |
|
48 | + * @param string $value |
|
49 | + * @return array |
|
50 | + * @throws Exception |
|
51 | + */ |
|
52 | + private function search(Request $request, $value) |
|
53 | + { |
|
54 | + $response = $request->create($this->vendor->generateUrl($value)); |
|
55 | + |
|
56 | + if (is_null($response)) { |
|
57 | + throw new Exception("Request to Itunes API failed", $request->getStatusCode()); |
|
58 | + } |
|
59 | + |
|
60 | + return [ |
|
61 | + 'search' => $response, |
|
62 | + 'status' => true, |
|
63 | + ]; |
|
64 | + } |
|
65 | + |
|
66 | + /** |
|
67 | + * @param string $feedUrl |
|
68 | + * @return array |
|
69 | + */ |
|
70 | + public function find($feedUrl) |
|
71 | + { |
|
72 | + if (strlen($feedUrl) < 1) { |
|
73 | + return $this->failedResponse("Feed Url cannot be empty"); |
|
74 | + } |
|
75 | + |
|
76 | + try { |
|
77 | + return [ |
|
78 | + 'status' => true, |
|
79 | + 'data' => $this->vendor->buildFeed($this->getFeedFromUrl($feedUrl)) |
|
80 | + ]; |
|
81 | + } catch (Exception $except) { |
|
82 | + return $this->failedResponse($except->getMessage()); |
|
83 | + } |
|
84 | + } |
|
85 | + |
|
86 | + /** |
|
87 | + * @param int $limit |
|
88 | + * @return PodcastScraper |
|
89 | + */ |
|
90 | + public function limit($limit) |
|
91 | + { |
|
92 | + $this->vendor->setLimit($limit); |
|
93 | + $this->vendor->setDefaultQuery(); |
|
94 | + |
|
95 | + return $this; |
|
96 | + } |
|
97 | + |
|
98 | + /** |
|
99 | + * @param Request $request |
|
100 | + * @param string $feedUrl |
|
101 | + * @return array |
|
102 | + * @throws Exception |
|
103 | + */ |
|
104 | + private function read(Request $request, $feedUrl) |
|
105 | + { |
|
106 | + $output = $request->create($feedUrl); |
|
107 | + |
|
108 | + if (is_null($output)) { |
|
109 | + throw new Exception("Request to RSS failed", $request->getStatusCode()); |
|
110 | + } |
|
111 | + |
|
112 | + return [ |
|
113 | + 'feed' => $output, |
|
114 | + 'status' => true, |
|
115 | + ]; |
|
116 | + } |
|
117 | + |
|
118 | + /** |
|
119 | + * @param string $feedUrl |
|
120 | + * |
|
121 | + * @return mixed |
|
122 | + */ |
|
123 | + protected function getFeedFromUrl($feedUrl) |
|
124 | + { |
|
125 | + $response = $this->read(new Request, $feedUrl); |
|
126 | + |
|
127 | + libxml_use_internal_errors(true); |
|
128 | + |
|
129 | + try { |
|
130 | + $feed = new SimpleXMLElement($response['feed'], LIBXML_NOCDATA, false); |
|
131 | + } catch (Exception $except) { |
|
132 | + $feed = new SimpleXMLElement(Xml::repair($response['feed']), LIBXML_NOCDATA, false); |
|
133 | + } |
|
134 | + |
|
135 | + return $feed; |
|
136 | + } |
|
137 | + |
|
138 | + /** |
|
139 | + * @param string $message |
|
140 | + * |
|
141 | + * @return array |
|
142 | + */ |
|
143 | + protected function failedResponse($message) |
|
144 | + { |
|
145 | + return [ |
|
146 | + 'status' => false, |
|
147 | + 'message' => $message |
|
148 | + ]; |
|
149 | + } |
|
150 | 150 | } |