├── .editorconfig
├── .gitattributes
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.markdown
├── composer.json
├── demo
├── images.html
├── reader.php
├── test.html
├── writer.html
└── writer.php
├── phpunit.xml.dist
├── src
└── Opengraph
│ ├── Meta.php
│ ├── Opengraph.php
│ ├── Reader.php
│ └── Writer.php
└── tests
└── Opengraph
├── MetaTest.php
├── ReaderTest.php
└── WriterTest.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | [*.yml]
11 | indent_size = 2
12 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.php diff=php
2 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | build-test:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v3
17 | - uses: php-actions/composer@v6
18 | - uses: php-actions/phpunit@v3
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | vendor
3 | composer.phar
4 | composer.lock
5 | .phpunit.result.cache
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - '7.1'
4 | - '7.2'
5 | - '7.3'
6 | - nightly
7 | - hhvm
8 | - hhvm-nightly
9 | sudo: false
10 | before_script:
11 | - curl -s https://getcomposer.org/installer | php
12 | - php composer.phar install --dev
13 | script: ./vendor/bin/phpunit -c phpunit.xml.dist
14 | matrix:
15 | allow_failures:
16 | - php: nightly
17 | - php: hhvm
18 | - php: hhvm-nightly
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Axel Etcheverry
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # Opengraph
2 |
3 | [](http://travis-ci.org/euskadi31/Opengraph)
4 |
5 | ## Test with [Atoum](https://github.com/atoum/atoum)
6 |
7 | cd Opengraph/
8 | curl -s https://getcomposer.org/installer | php
9 | php composer.phar install --dev
10 | ./vendor/bin/phpunit -c phpunit.xml.dist
11 |
12 | ## Writer
13 |
14 | ```php
15 | append(Opengraph\Writer::OG_TITLE, 'The Rock');
26 | $writer->append(Opengraph\Writer::OG_TYPE, Opengraph\Writer::TYPE_VIDEO_MOVIE);
27 | $writer->append(Opengraph\Writer::OG_URL, 'http://www.imdb.com/title/tt0117500/');
28 | $writer->append(Opengraph\Writer::OG_IMAGE, 'http://ia.media-imdb.com/images/rock.jpg');
29 |
30 | echo $writer->render() . PHP_EOL;
31 |
32 | ?>
33 | ```
34 |
35 | Output
36 |
37 | ```html
38 |
39 |
40 |
41 |
42 | ```
43 |
44 | ## Reader
45 |
46 | ```php
47 | parse(file_get_contents('http://www.imdb.com/title/tt0117500/'));
58 | print_r($reader->getArrayCopy());
59 |
60 | ?>
61 | ```
62 |
63 | Output
64 |
65 | Array
66 | (
67 | [og:url] => http://www.imdb.com/title/tt0117500/
68 | [og:title] => Rock (1996)
69 | [og:type] => video.movie
70 | [og:image] => Array
71 | (
72 | [0] => Array
73 | (
74 | [og:image:url] => http://ia.media-imdb.com/images/M/MV5BMTM3MTczOTM1OF5BMl5BanBnXkFtZTYwMjc1NDA5._V1._SX98_SY140_.jpg
75 | )
76 |
77 | )
78 |
79 | [og:site_name] => IMDb
80 | [fb:app_id] => 115109575169727
81 | )
82 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "euskadi31/opengraph",
3 | "type": "library",
4 | "description": "A PHP 5.3+ framework for OpenGraph Protocol",
5 | "keywords": ["sdk","opengraph", "og", "OpenGraph Protocol"],
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Axel Etcheverry",
10 | "email": "axel@etcheverry.biz",
11 | "homepage": "http://www.axel-etcheverry.com"
12 | }
13 | ],
14 | "require": {
15 | "php": ">=5.3.0"
16 | },
17 | "require-dev": {
18 | "phpunit/phpunit": "9.5.26"
19 | },
20 | "autoload": {
21 | "psr-0": {
22 | "Opengraph": "src/"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/demo/images.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | Skyfall (2012) - IMDb
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | test
26 |
27 |
--------------------------------------------------------------------------------
/demo/reader.php:
--------------------------------------------------------------------------------
1 | parse(file_get_contents('http://www.imdb.com/title/tt0117500/'));
13 | print_r($reader->getArrayCopy());
--------------------------------------------------------------------------------
/demo/test.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | Skyfall (2012) - IMDb
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | test
24 |
25 |
--------------------------------------------------------------------------------
/demo/writer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/demo/writer.php:
--------------------------------------------------------------------------------
1 | append(Opengraph\Writer::OG_TITLE, 'The Rock');
13 | $writer->append(Opengraph\Writer::OG_TYPE, Opengraph\Writer::TYPE_VIDEO_MOVIE);
14 | $writer->append(Opengraph\Writer::OG_URL, 'http://www.imdb.com/title/tt0117500/');
15 | $writer->append(Opengraph\Writer::OG_IMAGE, 'http://ia.media-imdb.com/images/rock.jpg');
16 |
17 | echo $writer->render() . PHP_EOL;
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | .
6 |
7 |
8 | ./demo
9 | ./vendor
10 |
11 |
12 |
13 |
14 | ./tests
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Opengraph/Meta.php:
--------------------------------------------------------------------------------
1 |
5 | * @copyright Copyright (c) 2011 Axel Etcheverry (http://www.axel-etcheverry.com)
6 | * Displays MIT
7 | * @license http://creativecommons.org/licenses/MIT/deed.fr MIT
8 | */
9 |
10 | /**
11 | * @namespace
12 | */
13 | namespace Opengraph;
14 |
15 | class Meta
16 | {
17 | /**
18 | * @var String
19 | */
20 | protected $_property;
21 |
22 | /**
23 | * @var Mixed
24 | */
25 | protected $_content;
26 |
27 | /**
28 | * @param String $property
29 | * @param String $content
30 | * @return \Opengraph\Meta
31 | */
32 | public function __construct($property, $content)
33 | {
34 | $this->_property = $property;
35 | $this->_content = $content;
36 | }
37 |
38 | /**
39 | * Set property
40 | *
41 | * @param String $property
42 | * @return \Opengraph\Meta
43 | */
44 | public function setProperty($property)
45 | {
46 | $this->_property = $property;
47 |
48 | return $this;
49 | }
50 |
51 | /**
52 | * Get property name
53 | *
54 | * @return String
55 | */
56 | public function getProperty()
57 | {
58 | return $this->_property;
59 | }
60 |
61 | /**
62 | * Set content
63 | *
64 | * @param String $content
65 | * @return \Opengraph\Meta
66 | */
67 | public function setContent($content)
68 | {
69 | $this->_content = $content;
70 |
71 | return $this;
72 | }
73 |
74 | /**
75 | * Get content
76 | *
77 | * @return String
78 | */
79 | public function getContent()
80 | {
81 | if(is_array($this->_content)) {
82 | return implode(',', $this->_content);
83 | }
84 | return $this->_content;
85 | }
86 |
87 | /**
88 | * Render meta tag
89 | *
90 | * @return String
91 | */
92 | public function render()
93 | {
94 | return '';
95 | }
96 | }
--------------------------------------------------------------------------------
/src/Opengraph/Opengraph.php:
--------------------------------------------------------------------------------
1 |
5 | * @copyright Copyright (c) 2011 Axel Etcheverry (http://www.axel-etcheverry.com)
6 | * Displays MIT
7 | * @license http://creativecommons.org/licenses/MIT/deed.fr MIT
8 | */
9 |
10 | /**
11 | * @namespace
12 | */
13 | namespace Opengraph;
14 |
15 | use ArrayObject;
16 | use Iterator;
17 | use ArrayIterator;
18 | use Serializable;
19 | use Countable;
20 |
21 | abstract class Opengraph implements Iterator, Serializable, Countable
22 | {
23 | /**
24 | * Basic Metadata
25 | */
26 | const OG_TITLE = 'og:title';
27 | const OG_TYPE = 'og:type';
28 | const OG_IMAGE = 'og:image';
29 | const OG_URL = 'og:url';
30 |
31 | /**
32 | * Optional Metadata
33 | */
34 | const OG_IMAGE_SECURE_URL = 'og:image:secure_url';
35 | const OG_IMAGE_TYPE = 'og:image:type';
36 | const OG_IMAGE_WIDTH = 'og:image:width';
37 | const OG_IMAGE_HEIGHT = 'og:image:height';
38 |
39 | const OG_AUDIO = 'og:audio';
40 | const OG_AUDIO_SECURE_URL = 'og:audio:secure_url';
41 | const OG_AUDIO_TYPE = 'og:audio:type';
42 |
43 | const OG_DESCRIPTION = 'og:description';
44 | const OG_DETERMINER = 'og:determiner';
45 | const OG_LOCALE = 'og:locale';
46 | const OG_LOCALE_ALTERNATE = 'og:locale:alternate';
47 | const OG_SITE_NAME = 'og:site_name';
48 |
49 | const OG_VIDEO = 'og:video';
50 | const OG_VIDEO_SECURE_URL = 'og:video:secure_url';
51 | const OG_VIDEO_TYPE = 'og:video:type';
52 | const OG_VIDEO_WIDTH = 'og:video:width';
53 | const OG_VIDEO_HEIGHT = 'og:video:height';
54 |
55 | const OG_AVAILABILITY = 'og:availability';
56 | const OG_PRICE_AMOUNT = 'og:price:amount';
57 | const OG_PRICE_CURRENCY = 'og:price:currency';
58 |
59 | /**
60 | * Facebook Metadata
61 | */
62 | const FB_ADMINS = 'fb:admins';
63 | const FB_PAGE = 'fb:page_id';
64 | const FB_APP = 'fb:app_id';
65 |
66 | /**
67 | * DEPRECATED PROPERTIES! DO NOT READ ON UNLESS YOU MUST!
68 | */
69 | const OG_LATITUDE = 'og:latitude';
70 | const OG_LONGITUDE = 'og:longitude';
71 | const OG_STREET_ADDRESS = 'og:street-address';
72 | const OG_LOCALITY = 'og:locality';
73 | const OG_REGION = 'og:region';
74 | const OG_POSTAL_CODE = 'og:postal-code';
75 | const OG_COUNTRY_NAME = 'og:country-name';
76 | const OG_EMAIL = 'og:email';
77 | const OG_PHONE_NUMBER = 'og:phone_number';
78 | const OG_FAX_NUMBER = 'og:fax_number';
79 | const OG_ISBN = 'og:isbn';
80 | const OG_UPC = 'og:upc';
81 | const OG_AUDIO_TITLE = 'og:audio:title';
82 | const OG_AUDIO_ARTIST = 'og:audio:artist';
83 | const OG_AUDIO_ALBUM = 'og:audio:album';
84 |
85 | /**
86 | * Types
87 | */
88 | const TYPE_MUSIC_SONG = 'music.song';
89 | const TYPE_MUSIC_ALBUM = 'music.album';
90 | const TYPE_MUSIC_PLAYLIST = 'music.playlist';
91 | const TYPE_MUSIC_RADIOSTATION = 'music.radio_station';
92 |
93 | const TYPE_VIDEO_MOVIE = 'video.movie';
94 | const TYPE_VIDEO_EPISODE = 'video.episode';
95 | const TYPE_VIDEO_TVSHOW = 'video.tv_show';
96 | const TYPE_VIDEO_OTHER = 'video.other';
97 |
98 | const TYPE_ARTICLE = 'article';
99 | const TYPE_BOOK = 'book';
100 | const TYPE_PROFILE = 'profile';
101 | const TYPE_WEBSITE = 'website';
102 |
103 | const TYPE_PRODUCT = 'product';
104 | const TYPE_PRODUCT_GROUP = 'product.group';
105 | const TYPE_PRODUCT_ITEM = 'product.item';
106 |
107 | /**
108 | * Article content fields
109 | */
110 | const ARTICLE_PUBLISHED_TIME = 'article:published_time';
111 | const ARTICLE_MODIFIED_TIME = 'article:modified_time';
112 | const ARTICLE_AUTHOR = 'article:author';
113 | const ARTICLE_SECTION = 'article:section';
114 | const ARTICLE_TAG = 'article:tag';
115 |
116 | /**
117 | * Positions
118 | */
119 | const APPEND = 'append';
120 | const PREPEND = 'prepend';
121 |
122 | /**
123 | * @var \ArrayObject
124 | */
125 | protected static $storage;
126 |
127 | /**
128 | * @var Integer
129 | */
130 | protected $_position = 0;
131 |
132 |
133 | public function __construct()
134 | {
135 | if(is_null(static::$storage)) {
136 | static::$storage = new ArrayObject();
137 | //static::$position = 0;
138 | }
139 | }
140 |
141 | /**
142 | * Add meta
143 | *
144 | * @param String $property
145 | * @param Mixed $content
146 | * @param String $position
147 | * @return \Opengraph\Opengraph
148 | */
149 | public function addMeta($property, $content, $position)
150 | {
151 | $content = $this->_normalizeContent($property, $content);
152 |
153 | switch($property) {
154 | case self::OG_TITLE:
155 | case self::OG_TYPE:
156 | case self::OG_DESCRIPTION:
157 | case self::OG_LOCALE:
158 | case self::OG_SITE_NAME:
159 | case self::OG_URL:
160 | if($this->hasMeta($property)) {
161 | $this->removeMeta($property);
162 | //$this->getMeta($property)->setContent($content);
163 | }
164 | break;
165 | }
166 |
167 | if($position == self::APPEND) {
168 | static::$storage->append(new Meta($property, $content));
169 | } else {
170 | $values = static::$storage->getArrayCopy();
171 | array_unshift($values, new Meta($property, $content));
172 | static::$storage->exchangeArray($values);
173 | unset($values);
174 | }
175 |
176 | return $this;
177 | }
178 |
179 | /**
180 | * Check is meta exists
181 | *
182 | * @param String $property
183 | * @return Boolean
184 | */
185 | public function hasMeta($property)
186 | {
187 | foreach(static::$storage as $meta) {
188 | if($meta->getProperty() == $property) {
189 | return true;
190 | }
191 | }
192 |
193 | return false;
194 | }
195 |
196 | /**
197 | * Get meta by property name
198 | *
199 | * @param String $property
200 | * @return \Opengraph\Meta
201 | */
202 | public function getMeta($property)
203 | {
204 | foreach(static::$storage as $meta) {
205 | if($meta->getProperty() == $property) {
206 | return $meta->getContent();
207 | }
208 | }
209 |
210 | return false;
211 | }
212 |
213 | /**
214 | * Remove meta
215 | *
216 | * @param String $property
217 | * @return Boolean
218 | */
219 | public function removeMeta($property)
220 | {
221 | foreach(static::$storage as $i => $meta) {
222 | if($meta->getProperty() == $property) {
223 | unset(static::$storage[$i]);
224 | return true;
225 | }
226 | }
227 |
228 | return false;
229 | }
230 |
231 | /**
232 | * @return \ArrayObject
233 | */
234 | public function getMetas()
235 | {
236 | return static::$storage;
237 | }
238 |
239 | /**
240 | * Normalize content
241 | *
242 | * @param String $property
243 | * @param Mixed $content
244 | * @return Mixed
245 | */
246 | protected function _normalizeContent($property, $content)
247 | {
248 | if($property == self::FB_ADMINS && is_string($content)) {
249 | return (array)explode(',', $content);
250 | }
251 |
252 | return $content;
253 | }
254 |
255 | /**
256 | * Get array
257 | *
258 | * @return Array
259 | */
260 | public function getArrayCopy()
261 | {
262 | $graph = array();
263 |
264 | $metas = static::$storage->getArrayCopy();
265 |
266 | foreach($metas as $i => $meta) {
267 |
268 | $property = $meta->getProperty();
269 | $content = $meta->getContent();
270 |
271 | switch($property) {
272 |
273 | case self::OG_IMAGE:
274 |
275 | $data = array(
276 | $property . ':url' => $content
277 | );
278 |
279 | for($j = ($i+1); $j <= ($i+4); $j++) {
280 |
281 | if(isset($metas[$j])) {
282 | $next = $metas[$j];
283 |
284 | if(!empty($next)) {
285 | $nextProperty = $next->getProperty();
286 |
287 | switch($nextProperty) {
288 | case self::OG_IMAGE_SECURE_URL:
289 | case self::OG_IMAGE_HEIGHT:
290 | case self::OG_IMAGE_WIDTH:
291 | case self::OG_IMAGE_TYPE:
292 | if(!isset($data[$nextProperty])) {
293 | $data[$nextProperty] = $next->getContent();
294 | unset($metas[$j]);
295 | }
296 | break;
297 | }
298 | }
299 | }
300 | }
301 |
302 | if(!isset($graph[$property])) {
303 | $graph[$property] = array();
304 | }
305 |
306 | $graph[$property][] = $data;
307 | unset($data);
308 |
309 | break;
310 |
311 | case self::OG_VIDEO:
312 | $data = array(
313 | $property . ':url' => $content
314 | );
315 |
316 | for($j = ($i+1); $j <= ($i+4); $j++) {
317 | if(isset($metas[$j])) {
318 | $next = $metas[$j];
319 | if(!empty($next)) {
320 | $nextProperty = $next->getProperty();
321 |
322 | switch($nextProperty) {
323 | case self::OG_VIDEO_SECURE_URL:
324 | case self::OG_VIDEO_HEIGHT:
325 | case self::OG_VIDEO_WIDTH:
326 | case self::OG_VIDEO_TYPE:
327 | if(!isset($data[$nextProperty])) {
328 | $data[$nextProperty] = $next->getContent();
329 | unset($metas[$j]);
330 | }
331 | break;
332 | }
333 | }
334 | }
335 | }
336 |
337 | if(!isset($graph[$property])) {
338 | $graph[$property] = array();
339 | }
340 |
341 | $graph[$property][] = $data;
342 | unset($data);
343 |
344 | break;
345 |
346 | case self::OG_AUDIO:
347 | $data = array(
348 | $property . ':url' => $content
349 | );
350 |
351 | for($j = ($i+1); $j <= ($i+2); $j++) {
352 | if(isset($metas[$j])) {
353 | $next = $metas[$j];
354 | if(!empty($next)) {
355 | $nextProperty = $next->getProperty();
356 |
357 | switch($nextProperty) {
358 | case self::OG_AUDIO_SECURE_URL:
359 | case self::OG_AUDIO_TYPE:
360 | if(!isset($data[$nextProperty])) {
361 | $data[$nextProperty] = $next->getContent();
362 | unset($metas[$j]);
363 | }
364 | break;
365 | }
366 | }
367 | }
368 | }
369 |
370 | if(!isset($graph[$property])) {
371 | $graph[$property] = array();
372 | }
373 |
374 | $graph[$property][] = $data;
375 | unset($data);
376 |
377 | break;
378 |
379 | default:
380 | $denyProperties = array(
381 | self::OG_AUDIO_SECURE_URL,
382 | self::OG_AUDIO_TYPE,
383 | self::OG_VIDEO_SECURE_URL,
384 | self::OG_VIDEO_HEIGHT,
385 | self::OG_VIDEO_WIDTH,
386 | self::OG_VIDEO_TYPE,
387 | self::OG_IMAGE_SECURE_URL,
388 | self::OG_IMAGE_HEIGHT,
389 | self::OG_IMAGE_WIDTH,
390 | self::OG_IMAGE_TYPE
391 | );
392 |
393 | if(!in_array($property, $denyProperties)) {
394 | $graph[$property] = $content;
395 | unset($metas[$i]);
396 | }
397 |
398 | }
399 | }
400 | unset($metas);
401 |
402 | return $graph;
403 | }
404 |
405 | /**
406 | * Rewind the Iterator to the first element
407 | *
408 | * @return void
409 | */
410 | public function rewind(): void
411 | {
412 | $this->_position = 0;
413 | }
414 |
415 | /**
416 | * Return the current element
417 | *
418 | * @return mixed
419 | */
420 | public function current(): mixed
421 | {
422 | return static::$storage[$this->_position];
423 | }
424 |
425 | /**
426 | * Return the key of the current element
427 | *
428 | * @return scalar
429 | */
430 | public function key(): mixed
431 | {
432 | return $this->_position;
433 | }
434 |
435 | /**
436 | * Move forward to next element
437 | *
438 | * @return void
439 | */
440 | public function next(): void
441 | {
442 | ++$this->_position;
443 | }
444 |
445 | /**
446 | * Checks if current position is valid
447 | *
448 | * @return boolean
449 | */
450 | public function valid(): bool
451 | {
452 | return $this->_position < sizeof(static::$storage);
453 | }
454 |
455 | /**
456 | * Count elements of an object
457 | *
458 | * @return integer
459 | */
460 | public function count(): int
461 | {
462 | return count(static::$storage);
463 | }
464 |
465 | /**
466 | * String representation of object (PHP 8.1)
467 | *
468 | * @return array
469 | */
470 | public function __serialize(): array
471 | {
472 | return (array)serialize(static::$storage);
473 | }
474 |
475 | /**
476 | * String representation of object
477 | *
478 | * @return string
479 | */
480 | public function serialize(): string
481 | {
482 | return serialize(static::$storage);
483 | }
484 |
485 | /**
486 | * Constructs the object form string (PHP 8.1)
487 | *
488 | * @param string $data The string representation of the object.
489 | * @return void
490 | */
491 | public function __unserialize($data): void
492 | {
493 | static::$storage = unserialize($data);
494 | }
495 |
496 | /**
497 | * Constructs the object form string
498 | *
499 | * @param string $data The string representation of the object.
500 | * @return void
501 | */
502 | public function unserialize($data): void
503 | {
504 | static::$storage = unserialize($data);
505 | }
506 |
507 | /**
508 | * Clear elements of storage
509 | *
510 | * @return void
511 | */
512 | public function clear(): void
513 | {
514 | static::$storage->exchangeArray(array());
515 | }
516 | }
517 |
--------------------------------------------------------------------------------
/src/Opengraph/Reader.php:
--------------------------------------------------------------------------------
1 |
5 | * @copyright Copyright (c) 2011 Axel Etcheverry (http://www.axel-etcheverry.com)
6 | * Displays MIT
7 | * @license http://creativecommons.org/licenses/MIT/deed.fr MIT
8 | */
9 |
10 | /**
11 | * @namespace
12 | */
13 | namespace Opengraph;
14 |
15 | use DOMDocument;
16 | use RuntimeException;
17 | use ArrayObject;
18 |
19 | class Reader extends Opengraph
20 | {
21 | /**
22 | * @var \ArrayObject
23 | */
24 | protected static $storage;
25 |
26 | public function __construct()
27 | {
28 | static::$storage = new ArrayObject();
29 | }
30 |
31 | /**
32 | * parse html tags
33 | *
34 | * @param $contents
35 | * @param bool $includeDefaults
36 | * @return $this
37 | */
38 | public function parse($contents, $includeDefaults = false)
39 | {
40 | if (empty($contents)) {
41 | throw new RuntimeException('Contents is empty');
42 | }
43 |
44 | $old_libxml_error = libxml_use_internal_errors(true);
45 |
46 | $dom = new DOMDocument;
47 |
48 | if(@$dom->loadHTML($contents) === false) {
49 | throw new RuntimeException("Contents is empty");
50 | }
51 |
52 | libxml_use_internal_errors($old_libxml_error);
53 |
54 | foreach($dom->getElementsByTagName('meta') as $tag) {
55 | if($includeDefaults && $tag->hasAttribute('name') && $tag->hasAttribute('content') && $tag->getAttribute('name') == 'description') {
56 | $this->addMeta('non-og-description', $tag->getAttribute('content'), self::APPEND);
57 | } else if($tag->hasAttribute('property') && $tag->hasAttribute('content')) {
58 | $this->addMeta($tag->getAttribute('property'), $tag->getAttribute('content'), self::APPEND);
59 | }
60 | }
61 |
62 | if($includeDefaults) {
63 | $titles = $dom->getElementsByTagName('title');
64 | if ($titles->length > 0) {
65 | $this->addMeta('non-og-title', $titles->item(0)->textContent, self::APPEND);
66 | }
67 | }
68 |
69 | unset($dom);
70 |
71 | return $this;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Opengraph/Writer.php:
--------------------------------------------------------------------------------
1 |
5 | * @copyright Copyright (c) 2011 Axel Etcheverry (http://www.axel-etcheverry.com)
6 | * Displays MIT
7 | * @license http://creativecommons.org/licenses/MIT/deed.fr MIT
8 | */
9 |
10 | /**
11 | * @namespace
12 | */
13 | namespace Opengraph;
14 |
15 | class Writer extends Opengraph
16 | {
17 | /**
18 | * @var \ArrayObject
19 | */
20 | protected static $storage;
21 |
22 | /**
23 | * @var Integer
24 | */
25 | //protected static $position;
26 |
27 | /**
28 | * Append meta
29 | *
30 | * @param String $property
31 | * @param String $content
32 | * @return \Opengraph\Opengraph
33 | */
34 | public function append($property, $content)
35 | {
36 | return $this->addMeta($property, $content, self::APPEND);
37 | }
38 |
39 | /**
40 | * Prepend meta
41 | *
42 | * @param String $property
43 | * @param String $content
44 | * @return \Opengraph\Opengraph
45 | */
46 | public function prepend($property, $content)
47 | {
48 | return $this->addMeta($property, $content, self::PREPEND);
49 | }
50 |
51 | /**
52 | * Render all meta tags
53 | *
54 | * @return String
55 | */
56 | public function render($indent = "\t")
57 | {
58 | $html = '';
59 | foreach(self::$storage as $meta) {
60 | $html .= $indent . $meta->render() . PHP_EOL;
61 | }
62 |
63 | return $html;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/tests/Opengraph/MetaTest.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | use PHPUnit\Framework\TestCase;
12 |
13 | class MetaTest extends TestCase
14 | {
15 | public function testMeta()
16 | {
17 | $meta = new Opengraph\Meta(Opengraph\Opengraph::OG_TITLE, 'test');
18 |
19 | $this->assertInstanceOf('\Opengraph\Meta', $meta);
20 |
21 | $this->assertEquals('og:title', $meta->getProperty());
22 |
23 | $this->assertEquals('test', $meta->getContent());
24 |
25 | $this->assertEquals('', $meta->render());
26 |
27 |
28 | $meta->setProperty(Opengraph\Opengraph::OG_TYPE);
29 |
30 | $this->assertEquals('og:type', $meta->getProperty());
31 |
32 | $meta->setContent(Opengraph\Opengraph::TYPE_BOOK);
33 |
34 | $this->assertEquals('book', $meta->getContent());
35 |
36 |
37 | $this->assertEquals('', $meta->render());
38 |
39 | $meta->setContent(array(123, 456));
40 |
41 | $this->assertEquals('', $meta->render());
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/Opengraph/ReaderTest.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | use PHPUnit\Framework\TestCase;
12 |
13 | class Reader extends TestCase
14 | {
15 | public function testClass()
16 | {
17 | $reader = new Opengraph\Reader();
18 |
19 | $this->assertInstanceOf('\Opengraph\Opengraph', $reader);
20 | $this->assertInstanceOf('\Iterator', $reader);
21 | $this->assertInstanceOf('\Serializable', $reader);
22 | $this->assertInstanceOf('\Countable', $reader);
23 | }
24 |
25 | public function testReaderParseException()
26 | {
27 | $this->expectException(\RuntimeException::class);
28 | $this->expectExceptionMessage('Contents is empty');
29 |
30 | $reader = new Opengraph\Reader();
31 | $reader->parse('');
32 | }
33 |
34 | public function testReader()
35 | {
36 | $html = '
37 |
38 |
39 |
40 |
41 | ';
42 |
43 | $reader = new Opengraph\Reader();
44 |
45 | $this->assertInstanceOf('\Opengraph\Reader', $reader);
46 |
47 | $reader->parse($html);
48 |
49 | $this->assertEquals(6, $reader->count());
50 |
51 | $this->assertEquals([
52 | 'og:url' => 'http://www.imdb.com/title/tt1074638/',
53 | 'og:title' => 'Skyfall (2012)',
54 | 'og:type' => 'video.movie',
55 | 'og:image' => [
56 | 0 => [
57 | 'og:image:url' => 'http://ia.media-imdb.com/images/M/MV5BMTczMjQ5NjE4NV5BMl5BanBnXkFtZTcwMjk0NjAwNw@@._V1._SX95_SY140_.jpg',
58 | ],
59 | ],
60 | 'og:site_name' => 'IMDb',
61 | 'fb:app_id' => '115109575169727',
62 | ], $reader->getArrayCopy());
63 |
64 | $this->assertInstanceOf('\ArrayObject', $reader->getMetas());
65 |
66 | $this->assertInstanceOf('\Opengraph\Meta', $reader->current());
67 |
68 | $this->assertEquals(0, $reader->key());
69 |
70 | $reader->next();
71 |
72 | $this->assertEquals(1, $reader->key());
73 |
74 | $this->assertTrue($reader->valid());
75 |
76 | $reader->next();
77 | $reader->next();
78 | $reader->next();
79 | $reader->next();
80 | $reader->next();
81 |
82 | $this->assertFalse($reader->valid());
83 |
84 | $reader->rewind();
85 |
86 | $this->assertEquals(0, $reader->key());
87 |
88 | $html = 'Skyfall Title
89 |
90 |
91 |
92 |
93 |
94 |
95 | ';
96 |
97 | $reader = new Opengraph\Reader();
98 |
99 | $this->assertInstanceOf('\Opengraph\Reader', $reader);
100 |
101 | $reader->parse($html, true);
102 |
103 | $this->assertEquals(8, $reader->count());
104 |
105 | $this->assertEquals([
106 | 'og:url' => 'http://www.imdb.com/title/tt1074638/',
107 | 'og:title' => 'Skyfall (2012)',
108 | 'og:type' => 'video.movie',
109 | 'og:image' => [
110 | 0 => [
111 | 'og:image:url' => 'http://ia.media-imdb.com/images/M/MV5BMTczMjQ5NjE4NV5BMl5BanBnXkFtZTcwMjk0NjAwNw@@._V1._SX95_SY140_.jpg',
112 | ],
113 | ],
114 | 'og:site_name' => 'IMDb',
115 | 'non-og-description' => 'Skyfall meta description',
116 | 'og:description' => 'Skyfall og description',
117 | 'non-og-title' => 'Skyfall Title'
118 | ], $reader->getArrayCopy());
119 |
120 | $reader = new Opengraph\Reader();
121 |
122 | $reader->parse($html, false);
123 |
124 | $this->assertEquals(6, $reader->count());
125 |
126 | $this->assertEquals([
127 | 'og:url' => 'http://www.imdb.com/title/tt1074638/',
128 | 'og:title' => 'Skyfall (2012)',
129 | 'og:type' => 'video.movie',
130 | 'og:image' => [
131 | 0 => [
132 | 'og:image:url' => 'http://ia.media-imdb.com/images/M/MV5BMTczMjQ5NjE4NV5BMl5BanBnXkFtZTcwMjk0NjAwNw@@._V1._SX95_SY140_.jpg',
133 | ],
134 | ],
135 | 'og:site_name' => 'IMDb',
136 | 'og:description' => 'Skyfall og description'
137 | ], $reader->getArrayCopy());
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/tests/Opengraph/WriterTest.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | use PHPUnit\Framework\TestCase;
12 |
13 | class WriterTest extends TestCase
14 | {
15 | public function testClass()
16 | {
17 | $writer = new Opengraph\Writer();
18 |
19 | $this->assertInstanceOf('\Opengraph\Opengraph', $writer);
20 | $this->assertInstanceOf('\Iterator', $writer);
21 | $this->assertInstanceOf('\Serializable', $writer);
22 | $this->assertInstanceOf('\Countable', $writer);
23 | }
24 |
25 | public function testWriter()
26 | {
27 | $writer = new Opengraph\Writer();
28 | $writer->append(Opengraph\Writer::OG_TITLE, 'test');
29 |
30 | $this->assertEquals("\t" . '' . PHP_EOL, $writer->render());
31 |
32 | $this->assertInstanceOf('\Opengraph\Writer', $writer->addMeta(
33 | Opengraph\Writer::OG_TYPE,
34 | Opengraph\Writer::TYPE_WEBSITE,
35 | Opengraph\Writer::APPEND
36 | ));
37 |
38 | $this->assertInstanceOf('\Opengraph\Writer', $writer->append(Opengraph\Writer::OG_TYPE, Opengraph\Writer::TYPE_WEBSITE));
39 |
40 | $this->assertInstanceOf('\Opengraph\Writer', $writer->prepend(Opengraph\Writer::OG_IMAGE, 'http://www.google.com/'));
41 |
42 | $this->assertInstanceOf('\ArrayObject', $writer->getMetas());
43 |
44 | $this->assertEquals('d2d171c74585f44ee53ba4c351ba0416', md5($writer->serialize()));
45 |
46 | $this->assertEquals(3, $writer->count());
47 |
48 | $this->assertInstanceOf('\Opengraph\Meta', $writer->current());
49 |
50 | $this->assertEquals(0, $writer->key());
51 |
52 | $writer->next();
53 |
54 | $this->assertEquals(1, $writer->key());
55 |
56 | $this->assertTrue($writer->valid());
57 |
58 | $writer->next();
59 | $writer->next();
60 | $writer->next();
61 |
62 | $this->assertFalse($writer->valid());
63 |
64 | $writer->rewind();
65 |
66 | $this->assertEquals(0, $writer->key());
67 |
68 | $writer->unserialize('C:11:"ArrayObject":751:{x:i:0;a:6:{i:0;O:14:"Opengraph\Meta":2:{s:12:" * _property";s:6:"og:url";s:11:" * _content";s:36:"http://www.imdb.com/title/tt0117500/";}i:1;O:14:"Opengraph\Meta":2:{s:12:" * _property";s:8:"og:title";s:11:" * _content";s:11:"Rock (1996)";}i:2;O:14:"Opengraph\Meta":2:{s:12:" * _property";s:7:"og:type";s:11:" * _content";s:11:"video.movie";}i:3;O:14:"Opengraph\Meta":2:{s:12:" * _property";s:8:"og:image";s:11:" * _content";s:99:"http://ia.media-imdb.com/images/M/MV5BMTM3MTczOTM1OF5BMl5BanBnXkFtZTYwMjc1NDA5._V1._SX98_SY140_.jpg";}i:4;O:14:"Opengraph\Meta":2:{s:12:" * _property";s:12:"og:site_name";s:11:" * _content";s:4:"IMDb";}i:5;O:14:"Opengraph\Meta":2:{s:12:" * _property";s:9:"fb:app_id";s:11:" * _content";s:15:"115109575169727";}};m:a:0:{}}');
69 |
70 | $this->assertEquals(6, $writer->count());
71 |
72 | $this->assertEquals([
73 | 'og:url' => 'http://www.imdb.com/title/tt0117500/',
74 | 'og:title' => 'Rock (1996)',
75 | 'og:type' => 'video.movie',
76 | 'og:image' => [
77 | 0 => [
78 | 'og:image:url' => 'http://ia.media-imdb.com/images/M/MV5BMTM3MTczOTM1OF5BMl5BanBnXkFtZTYwMjc1NDA5._V1._SX98_SY140_.jpg'
79 | ]
80 | ],
81 | 'og:site_name' => 'IMDb',
82 | 'fb:app_id' => '115109575169727'
83 | ], $writer->getArrayCopy());
84 |
85 | $this->assertEquals('Rock (1996)', $writer->getMeta(Opengraph\Writer::OG_TITLE));
86 |
87 | $this->assertTrue($writer->hasMeta(Opengraph\Writer::OG_TITLE));
88 |
89 | $this->assertTrue($writer->removeMeta(Opengraph\Writer::OG_TITLE));
90 |
91 | $this->assertEquals(5, $writer->count());
92 |
93 | $this->assertFalse($writer->removeMeta(Opengraph\Writer::OG_TITLE));
94 |
95 | $this->assertFalse($writer->getMeta(Opengraph\Writer::OG_TITLE));
96 |
97 | $this->assertFalse($writer->hasMeta(Opengraph\Writer::OG_TITLE));
98 |
99 | $writer->addMeta(Opengraph\Writer::OG_TYPE, Opengraph\Writer::TYPE_BOOK, Opengraph\Writer::APPEND);
100 |
101 | $this->assertEquals(Opengraph\Writer::TYPE_BOOK, $writer->getMeta(Opengraph\Writer::OG_TYPE));
102 |
103 | $writer = new Opengraph\Writer();
104 | $this->assertEquals(5, $writer->count());
105 |
106 | $writer = new Opengraph\Writer();
107 | $writer->clear();
108 |
109 | $this->assertEquals(0, $writer->count());
110 |
111 | $writer->append(Opengraph\Writer::FB_ADMINS, 12345567657868);
112 |
113 | $this->assertEquals("\t" . '' . PHP_EOL, $writer->render());
114 |
115 | $writer->clear();
116 |
117 | $writer->append(Opengraph\Writer::FB_ADMINS, '12345567657868,23334543656456');
118 | $this->assertEquals("\t" . '' . PHP_EOL, $writer->render());
119 | }
120 | }
121 |
--------------------------------------------------------------------------------