Version Description
Download this release
Release Info
Developer | diegoquinteiro |
Plugin | Instant Articles for WP |
Version | 4.0.0 |
Comparing to | |
See all releases |
Code changes from version 3.3.5 to 4.0.0
- class-instant-articles-amp-markup.php +173 -0
- class-instant-articles-post.php +77 -5
- compat.php +2 -2
- compat/class-instant-articles-google-analytics-for-wordpress.php +14 -8
- facebook-instant-articles.php +98 -16
- meta-box/class-instant-articles-meta-box.php +10 -42
- meta-box/meta-box-template.php +45 -116
- readme.txt +1 -1
- rules-configuration.json +3 -0
- vendor/autoload.php +1 -1
- vendor/bin/phpcbf +23 -0
- vendor/bin/phpcs +25 -0
- vendor/composer/autoload_classmap.php +252 -0
- vendor/composer/autoload_psr4.php +1 -1
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +257 -4
- vendor/composer/installed.json +213 -43
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/.gitignore +7 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/.travis.yml +28 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/CONTRIBUTING.md +54 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/LICENSE +19 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/README.md +105 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/composer.json +43 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/composer.lock +1329 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/example-override-styling.php +31 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/example-quick-start.php +64 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/example-simple-styling.php +32 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/instant-article-example.html +89 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/quiet_logger.php +18 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/styles/gray.style.json +993 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/styles/style-got-from-somewhereelse.json +993 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/phpcs.xml +8 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/phpunit.xml +18 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPArticle.php +1460 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPCaption.php +158 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPContext.php +709 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPCover.php +59 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPCoverImage.php +90 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPHeader.php +141 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPImage.php +23 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/configuration/default-amp.style.json +1133 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/configuration/global.amp.css +202 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/CSSBuilder.php +189 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/CallbackHook.php +390 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/Hook.php +161 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/Observer.php +285 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/Warning.php +40 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPArticleTest.php +1092 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPCaptionTest.php +149 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPContextTest.php +563 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPCoverImageTest.php +129 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPHeaderTest.php +107 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/amp-converted.html +54 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/amp-example.html +79 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/fail1.jpg +0 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/fb_icon_325x325.png +0 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/heart-rate-age-300x182.gif +0 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/timelapse-final-4x3.mp4 +0 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test1-amp-converted.html +90 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test1-instant-article.html +58 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test2-amp-converted.html +95 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test2-instant-article.html +60 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test3-amp-converted.html +99 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test3-instant-article.html +73 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test4-amp-converted.html +103 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test4-instant-article.html +73 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test5-amp-converted.html +112 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test5-instant-article.html +80 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/tutorial-amp-converted.html +258 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/tutorial-instant-article.html +277 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/default.amp-custom.css +9 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/default.style.json +1128 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/wod-gray.style.json +993 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/CSSBuilderTest.php +190 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/FileUtilsPHPUnitTestCase.php +80 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/Greeting.php +46 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/HookTest.php +252 -0
- vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/ObserverTest.php +155 -0
- vendor/facebook/facebook-instant-articles-sdk-php/.travis.yml +1 -0
- vendor/facebook/facebook-instant-articles-sdk-php/README.md +22 -10
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/Analytics.php +1 -1
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/Emphasized.php +53 -0
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/InstantArticle.php +29 -6
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/TextContainer.php +9 -1
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Parser/Parser.php +7 -3
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Parser/instant-articles-rules.json +14 -1
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Rules/EmphasizedRule.php +38 -0
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Rules/InstantArticleRule.php +7 -0
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Rules/TimeRule.php +8 -1
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Transformer.php +35 -1
- vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Validators/Type.php +2 -2
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/ImageTest.php +2 -2
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/InstantArticleTest.php +33 -1
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/ParagraphTest.php +3 -1
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/Validators/InstantArticleValidatorTest.php +2 -2
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/Validators/TypeTest.php +3 -1
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/ParserTest.php +52 -0
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-ads.html +38 -0
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-no-timezone.html +199 -0
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-nyc-timezone.html +199 -0
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-standard-timezone.html +199 -0
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example.html +1 -1
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/CustomHTMLTransformerTest.php +1 -1
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/Example/simple-ia.html +2 -45
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/Example/simple.html +2 -42
- vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/Rules/AuthorRuleTest.php +36 -0
- vendor/squizlabs/php_codesniffer/.gitattributes +13 -0
- vendor/squizlabs/php_codesniffer/.gitignore +6 -0
- vendor/squizlabs/php_codesniffer/CONTRIBUTING.md +13 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist +9 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer.php +2578 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php +1444 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php +184 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php +292 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php +179 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php +265 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/Exception.php +31 -0
- vendor/squizlabs/php_codesniffer/CodeSniffer/File.php +1502 -0
class-instant-articles-amp-markup.php
ADDED
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Facebook Instant Articles for WP.
|
4 |
+
* This source code is licensed under the license found in the
|
5 |
+
* LICENSE file in the root directory of this source tree.
|
6 |
+
*
|
7 |
+
* @package default
|
8 |
+
* @since 4.0
|
9 |
+
*/
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\AMP\AMPArticle;
|
12 |
+
use Facebook\InstantArticles\Validators\Type;
|
13 |
+
|
14 |
+
class Instant_Articles_AMP_Markup {
|
15 |
+
|
16 |
+
const SETTING_AMP_MARKUP = 'amp_markup'; // Setting to check if AMP Markup generation is enabled
|
17 |
+
const SETTING_STYLE = 'amp_stylesheet'; // Setting that stores the JSON stylesheet
|
18 |
+
const SETTING_DL_MEDIA = 'amp_download_media'; // Enable or disable media download option
|
19 |
+
const QUERY_ARG = 'amp_markup'; // Query argument that will trigger the AMP markup generation
|
20 |
+
|
21 |
+
// To memoize the settings
|
22 |
+
static $settings = null;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Gets the settings
|
26 |
+
*
|
27 |
+
* @return array The settings, check Instant_Articles_Option::get_option_decoded()
|
28 |
+
* @since 4.0
|
29 |
+
*/
|
30 |
+
static function get_settings() {
|
31 |
+
if ( self::$settings === null ) {
|
32 |
+
self::$settings = Instant_Articles_Option_AMP::get_option_decoded();
|
33 |
+
}
|
34 |
+
|
35 |
+
return self::$settings;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Checks if the AMP markup is enabled
|
40 |
+
*
|
41 |
+
* @return bool true if markup is enabled
|
42 |
+
* @since 4.0
|
43 |
+
*/
|
44 |
+
static function is_markup_enabled() {
|
45 |
+
$settings = self::get_settings();
|
46 |
+
|
47 |
+
return
|
48 |
+
isset( $settings[ self::SETTING_AMP_MARKUP ] )
|
49 |
+
? (bool) $settings[ self::SETTING_AMP_MARKUP ]
|
50 |
+
: false;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Adds the meta tag for AMP Markup if enabled
|
55 |
+
*
|
56 |
+
* @since 4.0
|
57 |
+
*/
|
58 |
+
static function inject_link_rel() {
|
59 |
+
|
60 |
+
if ( ! self::is_markup_enabled() ) {
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
|
64 |
+
// Transform the post to an Instant Article.
|
65 |
+
$adapter = new Instant_Articles_Post( get_post() );
|
66 |
+
|
67 |
+
if ( ! $adapter->should_submit_post() ) {
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
|
71 |
+
$url = $adapter->get_canonical_url();
|
72 |
+
$url = add_query_arg( self::QUERY_ARG, '1', $url );
|
73 |
+
|
74 |
+
echo '<link rel="amphtml" href="' . $url . '">';
|
75 |
+
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Generates the AMP markup if post has amp_markup
|
80 |
+
*
|
81 |
+
* NOTE: side-effect: function calls die() in the end.
|
82 |
+
*
|
83 |
+
* @since 4.0
|
84 |
+
*/
|
85 |
+
static function markup_version() {
|
86 |
+
if ( ! (isset( $_GET[ self::QUERY_ARG ] ) && $_GET[ self::QUERY_ARG ]) ) {
|
87 |
+
return;
|
88 |
+
}
|
89 |
+
|
90 |
+
$settings = self::get_settings();
|
91 |
+
|
92 |
+
if ( ! self::is_markup_enabled() ) {
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
|
96 |
+
$has_stylesheet =
|
97 |
+
isset( $settings[ self::SETTING_STYLE ] )
|
98 |
+
? self::validate_json( $settings[ self::SETTING_STYLE ] )
|
99 |
+
: false;
|
100 |
+
|
101 |
+
$properties = array();
|
102 |
+
|
103 |
+
$download_media =
|
104 |
+
isset( $settings[ self::SETTING_DL_MEDIA ] )
|
105 |
+
? (bool) $settings[ self::SETTING_DL_MEDIA ]
|
106 |
+
: false;
|
107 |
+
|
108 |
+
$properties[ AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY ] = $download_media;
|
109 |
+
|
110 |
+
if ( $has_stylesheet ) {
|
111 |
+
$properties[ AMPArticle::OVERRIDE_STYLES_KEY ] =
|
112 |
+
json_decode( $settings[ self::SETTING_STYLE ], true );
|
113 |
+
}
|
114 |
+
|
115 |
+
$post = get_post();
|
116 |
+
|
117 |
+
// This array will hold the image sizes
|
118 |
+
$media_sizes = array();
|
119 |
+
|
120 |
+
// Get all children with mime type image that are attached to the posts
|
121 |
+
// NOTE: this will not get images that are not hosted in the WP
|
122 |
+
$image_children = get_children( 'post_type=attachment&post_mime_type=image&post_parent=' . $post->ID );
|
123 |
+
|
124 |
+
foreach ( $image_children as $img_id => $img ) {
|
125 |
+
$meta = wp_get_attachment_metadata( $img_id );
|
126 |
+
|
127 |
+
// Removes the file name from the URL
|
128 |
+
$url_chunks = explode( '/', $img->guid );
|
129 |
+
array_pop( $url_chunks );
|
130 |
+
$base_image_url = implode( '/', $url_chunks ) . '/';
|
131 |
+
|
132 |
+
// This is the uploaded original file
|
133 |
+
$media_sizes[ $img->guid ] = array( $meta['width'], $meta['height'] );
|
134 |
+
|
135 |
+
// These are the possible redimensions
|
136 |
+
foreach ( $meta['sizes'] as $size ) {
|
137 |
+
$size_url = $base_image_url . $size['file'];
|
138 |
+
$media_sizes[ $size_url ] = array( $size['width'], $size['height'] );
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
$properties[ AMPArticle::MEDIA_SIZES_KEY ] = $media_sizes;
|
143 |
+
|
144 |
+
// Transform the post to an Instant Article.
|
145 |
+
$adapter = new Instant_Articles_Post( $post );
|
146 |
+
$article = $adapter->to_instant_article();
|
147 |
+
$article_html = $article->render();
|
148 |
+
$amp = AMPArticle::create( $article_html, $properties );
|
149 |
+
echo $amp->render();
|
150 |
+
|
151 |
+
die();
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Helper function to validate the json string
|
156 |
+
*
|
157 |
+
* @param $json_str string JSON string
|
158 |
+
* @return bool true for valid JSON
|
159 |
+
* @since 4.0
|
160 |
+
*/
|
161 |
+
static function validate_json( $json_str ) {
|
162 |
+
if ( Type::isTextEmpty( $json_str ) ) {
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
|
166 |
+
json_decode( $json_str );
|
167 |
+
if ( json_last_error() == JSON_ERROR_NONE ) {
|
168 |
+
return true;
|
169 |
+
}
|
170 |
+
|
171 |
+
return false;
|
172 |
+
}
|
173 |
+
}
|
class-instant-articles-post.php
CHANGED
@@ -17,7 +17,10 @@ use Facebook\InstantArticles\Elements\Image;
|
|
17 |
use Facebook\InstantArticles\Elements\Video;
|
18 |
use Facebook\InstantArticles\Elements\Caption;
|
19 |
use Facebook\InstantArticles\Elements\Footer;
|
|
|
20 |
use Facebook\InstantArticles\Transformer\Transformer;
|
|
|
|
|
21 |
/**
|
22 |
* Class responsible for constructing our content and preparing it for rendering
|
23 |
*
|
@@ -690,8 +693,11 @@ class Instant_Articles_Post {
|
|
690 |
Image::setDefaultCommentEnabled( $settings_publishing[ 'comments_on_media' ] );
|
691 |
Video::setDefaultCommentEnabled( $settings_publishing[ 'comments_on_media' ] );
|
692 |
}
|
693 |
-
|
694 |
-
$
|
|
|
|
|
|
|
695 |
|
696 |
$this->add_ads_from_settings();
|
697 |
$this->add_analytics_from_settings();
|
@@ -865,6 +871,69 @@ class Instant_Articles_Post {
|
|
865 |
}
|
866 |
}
|
867 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
868 |
/**
|
869 |
* Apply appearance settings for an InstantArticle.
|
870 |
*
|
@@ -880,9 +949,12 @@ class Instant_Articles_Post {
|
|
880 |
}
|
881 |
|
882 |
if ( isset( $settings['copyright'] ) && ! empty( $settings['copyright'] ) ) {
|
883 |
-
$
|
884 |
-
|
885 |
-
|
|
|
|
|
|
|
886 |
}
|
887 |
|
888 |
if ( isset( $settings['rtl_enabled'] ) ) {
|
17 |
use Facebook\InstantArticles\Elements\Video;
|
18 |
use Facebook\InstantArticles\Elements\Caption;
|
19 |
use Facebook\InstantArticles\Elements\Footer;
|
20 |
+
use Facebook\InstantArticles\Elements\Small;
|
21 |
use Facebook\InstantArticles\Transformer\Transformer;
|
22 |
+
use Facebook\InstantArticles\Validators\Type;
|
23 |
+
|
24 |
/**
|
25 |
* Class responsible for constructing our content and preparing it for rendering
|
26 |
*
|
693 |
Image::setDefaultCommentEnabled( $settings_publishing[ 'comments_on_media' ] );
|
694 |
Video::setDefaultCommentEnabled( $settings_publishing[ 'comments_on_media' ] );
|
695 |
}
|
696 |
+
|
697 |
+
$the_content = $this->get_the_content();
|
698 |
+
if (!Type::isTextEmpty($the_content)) {
|
699 |
+
$transformer->transformString( $this->instant_article, $the_content, get_option( 'blog_charset' ) );
|
700 |
+
}
|
701 |
|
702 |
$this->add_ads_from_settings();
|
703 |
$this->add_analytics_from_settings();
|
871 |
}
|
872 |
}
|
873 |
|
874 |
+
/**
|
875 |
+
* Returns whether the article should be ingested as an Instant Article.
|
876 |
+
*/
|
877 |
+
public function should_submit_post() {
|
878 |
+
|
879 |
+
$post = get_post( $this->get_the_id() );
|
880 |
+
|
881 |
+
$fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
|
882 |
+
if ( ! $fb_page_settings[ "page_id" ] ) {
|
883 |
+
return false;
|
884 |
+
}
|
885 |
+
|
886 |
+
// Don't process if this is just a revision or an autosave.
|
887 |
+
if ( wp_is_post_revision( $this->post ) || wp_is_post_autosave( $this->post ) ) {
|
888 |
+
return false;
|
889 |
+
}
|
890 |
+
|
891 |
+
// Don't process if this post is not published
|
892 |
+
if ( 'publish' !== $post->post_status ) {
|
893 |
+
return false;
|
894 |
+
}
|
895 |
+
|
896 |
+
// Only process posts
|
897 |
+
$post_types = apply_filters( 'instant_articles_post_types', array( 'post' ) );
|
898 |
+
if ( ! in_array( $post->post_type, $post_types ) ) {
|
899 |
+
return false;
|
900 |
+
}
|
901 |
+
|
902 |
+
// Transform the post to an Instant Article.
|
903 |
+
$adapter = new Instant_Articles_Post( $post );
|
904 |
+
$instant_article = $this->to_instant_article();
|
905 |
+
|
906 |
+
// Skip empty articles or articles missing title.
|
907 |
+
// This is important because the save_post action is also triggered by bulk updates, but in this case
|
908 |
+
// WordPress does not load the content field from DB for performance reasons. In this case, articles
|
909 |
+
// will be empty here, despite of them actually having content.
|
910 |
+
if ( count( $instant_article->getChildren() ) === 0 || ! $instant_article->getHeader() || ! $instant_article->getHeader()->getTitle() ) {
|
911 |
+
return false;
|
912 |
+
}
|
913 |
+
|
914 |
+
// Don't publish posts with password protection
|
915 |
+
if ( post_password_required( $post ) ) {
|
916 |
+
return false;
|
917 |
+
}
|
918 |
+
|
919 |
+
// Don't process if contains warnings and blocker flag for transformation warnings is turned on.
|
920 |
+
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
921 |
+
$force_submit = get_post_meta( $post->ID, IA_PLUGIN_FORCE_SUBMIT_KEY, true );
|
922 |
+
if ( count( $this->transformer->getWarnings() ) > 0
|
923 |
+
&& ( ! isset( $publishing_settings[ 'publish_with_warnings' ] ) || ! $publishing_settings[ 'publish_with_warnings' ] )
|
924 |
+
&& ( ! $force_submit )
|
925 |
+
) {
|
926 |
+
return false;
|
927 |
+
}
|
928 |
+
|
929 |
+
// Allow to disable post submit via filter
|
930 |
+
if ( false === apply_filters( 'instant_articles_should_submit_post', true, $adapter ) ) {
|
931 |
+
return false;
|
932 |
+
}
|
933 |
+
|
934 |
+
return true;
|
935 |
+
}
|
936 |
+
|
937 |
/**
|
938 |
* Apply appearance settings for an InstantArticle.
|
939 |
*
|
949 |
}
|
950 |
|
951 |
if ( isset( $settings['copyright'] ) && ! empty( $settings['copyright'] ) ) {
|
952 |
+
$footer = Footer::create();
|
953 |
+
$this->transformer->transformString(
|
954 |
+
$footer,
|
955 |
+
'<small>' . $settings['copyright'] . '</small>',
|
956 |
+
get_option( 'blog_charset' ) );
|
957 |
+
$this->instant_article->withFooter( $footer );
|
958 |
}
|
959 |
|
960 |
if ( isset( $settings['rtl_enabled'] ) ) {
|
compat.php
CHANGED
@@ -21,8 +21,8 @@ if ( defined( 'WPSEO_VERSION' ) && ! defined( 'WPSEO_IA_COMPAT' ) ) {
|
|
21 |
$yseo->init();
|
22 |
}
|
23 |
|
24 |
-
// Load support for Google Analytics for WordPress
|
25 |
-
if ( defined( 'GAWP_VERSION' ) && ! defined( 'GAWP_IA_COMPAT' ) ) {
|
26 |
include( dirname( __FILE__ ) . '/compat/class-instant-articles-google-analytics-for-wordpress.php' );
|
27 |
$gawp = new Instant_Articles_Google_Analytics_For_WordPress;
|
28 |
$gawp->init();
|
21 |
$yseo->init();
|
22 |
}
|
23 |
|
24 |
+
// Load support for Google Analytics for WordPress by MonsterInsights.
|
25 |
+
if ( ( defined( 'GAWP_VERSION' ) || function_exists( 'MonsterInsights' ) ) && ! defined( 'GAWP_IA_COMPAT' ) ) {
|
26 |
include( dirname( __FILE__ ) . '/compat/class-instant-articles-google-analytics-for-wordpress.php' );
|
27 |
$gawp = new Instant_Articles_Google_Analytics_For_WordPress;
|
28 |
$gawp->init();
|
compat/class-instant-articles-google-analytics-for-wordpress.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
-
* Support class for Google Analytics for WordPress
|
5 |
*
|
6 |
* @since 0.1
|
7 |
*/
|
@@ -30,7 +30,7 @@ class Instant_Articles_Google_Analytics_For_WordPress {
|
|
30 |
*/
|
31 |
function add_to_registry( &$registry ) {
|
32 |
|
33 |
-
$display_name = 'Google Analytics by
|
34 |
|
35 |
$identifier = 'google-analytics-for-wordpress';
|
36 |
|
@@ -49,16 +49,22 @@ class Instant_Articles_Google_Analytics_For_WordPress {
|
|
49 |
*/
|
50 |
function get_raw_embed_code() {
|
51 |
|
52 |
-
|
53 |
|
54 |
-
if (
|
55 |
-
|
56 |
} else {
|
57 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
|
60 |
-
ob_start();
|
61 |
-
$tracker->tracking();
|
62 |
$ga_code = ob_get_clean();
|
63 |
|
64 |
return $ga_code;
|
1 |
<?php
|
2 |
|
3 |
/**
|
4 |
+
* Support class for Google Analytics for WordPress by MonsterInsights
|
5 |
*
|
6 |
* @since 0.1
|
7 |
*/
|
30 |
*/
|
31 |
function add_to_registry( &$registry ) {
|
32 |
|
33 |
+
$display_name = 'Google Analytics by MonsterInsights';
|
34 |
|
35 |
$identifier = 'google-analytics-for-wordpress';
|
36 |
|
49 |
*/
|
50 |
function get_raw_embed_code() {
|
51 |
|
52 |
+
ob_start();
|
53 |
|
54 |
+
if ( function_exists( 'monsterinsights_tracking_script' ) ) {
|
55 |
+
monsterinsights_tracking_script();
|
56 |
} else {
|
57 |
+
$options = Yoast_GA_Options::instance()->options;
|
58 |
+
|
59 |
+
if ( isset( $options['enable_universal'] ) && 1 === intval( $options['enable_universal'] ) ) {
|
60 |
+
$tracker = new Yoast_GA_Universal;
|
61 |
+
} else {
|
62 |
+
$tracker = new Yoast_GA_JS;
|
63 |
+
}
|
64 |
+
|
65 |
+
$tracker->tracking();
|
66 |
}
|
67 |
|
|
|
|
|
68 |
$ga_code = ob_get_clean();
|
69 |
|
70 |
return $ga_code;
|
facebook-instant-articles.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Description: Add support for Instant Articles for Facebook to your WordPress site.
|
5 |
* Author: Automattic, Dekode, Facebook
|
6 |
* Author URI: https://vip.wordpress.com/plugins/instant-articles/
|
7 |
-
* Version:
|
8 |
* Text Domain: instant-articles
|
9 |
* License: GPLv2
|
10 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
@@ -31,6 +31,7 @@ if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
|
|
31 |
|
32 |
$autoloader = require __DIR__ . '/vendor/autoload.php';
|
33 |
$autoloader->add( 'Facebook\\', __DIR__ . '/vendor/facebook/facebook-instant-articles-sdk-php/src' );
|
|
|
34 |
|
35 |
// Configures log to go through console.
|
36 |
\Logger::configure(
|
@@ -67,11 +68,12 @@ if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
|
|
67 |
|
68 |
defined( 'ABSPATH' ) || die( 'Shame on you' );
|
69 |
|
70 |
-
define( 'IA_PLUGIN_VERSION', '
|
71 |
define( 'IA_PLUGIN_PATH_FULL', __FILE__ );
|
72 |
define( 'IA_PLUGIN_PATH', plugin_basename( __FILE__ ) );
|
73 |
define( 'IA_PLUGIN_FILE_BASENAME', pathinfo( __FILE__, PATHINFO_FILENAME ) );
|
74 |
define( 'IA_PLUGIN_TEXT_DOMAIN', 'instant-articles' );
|
|
|
75 |
|
76 |
// Let users define their own feed slug.
|
77 |
if ( ! defined( 'INSTANT_ARTICLES_SLUG' ) ) {
|
@@ -82,7 +84,7 @@ if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
|
|
82 |
require_once( dirname( __FILE__ ) . '/class-instant-articles-post.php' );
|
83 |
require_once( dirname( __FILE__ ) . '/wizard/class-instant-articles-wizard.php' );
|
84 |
require_once( dirname( __FILE__ ) . '/meta-box/class-instant-articles-meta-box.php' );
|
85 |
-
require_once( dirname( __FILE__ ) . '/class-instant-articles-
|
86 |
|
87 |
/**
|
88 |
* Plugin activation hook to add our rewrite rules.
|
@@ -102,7 +104,7 @@ if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
|
|
102 |
add_action( 'network_admin_notices', 'instant_articles_setup_admin_notice' ); // also show message on multisite
|
103 |
function instant_articles_setup_admin_notice() {
|
104 |
global $pagenow;
|
105 |
-
if ( $pagenow === 'plugins.php' &&
|
106 |
$settings_url = Instant_Articles_Wizard::get_url();
|
107 |
echo '<div class="updated settings-error notice is-dismissible">';
|
108 |
echo '<p>Congrats, you\'ve installed the Instant Articles for WP plugin. Now <a href="' . esc_url_raw($settings_url) . '">set it up</a> to start publishing Instant Articles.';
|
@@ -314,13 +316,6 @@ if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
|
|
314 |
IA_PLUGIN_VERSION,
|
315 |
false
|
316 |
);
|
317 |
-
wp_register_script(
|
318 |
-
'instant-articles-wizard',
|
319 |
-
plugins_url( '/js/instant-articles-wizard.js', __FILE__ ),
|
320 |
-
null,
|
321 |
-
IA_PLUGIN_VERSION,
|
322 |
-
false
|
323 |
-
);
|
324 |
}
|
325 |
add_action( 'init', 'instant_articles_register_scripts' );
|
326 |
|
@@ -354,20 +349,107 @@ if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
|
|
354 |
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
355 |
$fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
|
356 |
|
357 |
-
if ( isset( $fb_page_settings['page_id'] ) ) {
|
358 |
?>
|
359 |
-
<meta property="fb:pages" content="<?php echo esc_attr( $fb_page_settings['page_id'] ); ?>" />
|
360 |
<?php
|
361 |
}
|
362 |
}
|
363 |
add_action( 'wp_head', 'inject_url_claiming_meta_tag' );
|
364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
// Initialize the Instant Articles meta box.
|
366 |
Instant_Articles_Meta_Box::init();
|
367 |
|
368 |
-
|
369 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
|
371 |
-
// Initialize the Instant Articles Wizard page.
|
372 |
Instant_Articles_Wizard::init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
373 |
}
|
4 |
* Description: Add support for Instant Articles for Facebook to your WordPress site.
|
5 |
* Author: Automattic, Dekode, Facebook
|
6 |
* Author URI: https://vip.wordpress.com/plugins/instant-articles/
|
7 |
+
* Version: 4.0.0
|
8 |
* Text Domain: instant-articles
|
9 |
* License: GPLv2
|
10 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
31 |
|
32 |
$autoloader = require __DIR__ . '/vendor/autoload.php';
|
33 |
$autoloader->add( 'Facebook\\', __DIR__ . '/vendor/facebook/facebook-instant-articles-sdk-php/src' );
|
34 |
+
$autoloader->add( 'Facebook\\', __DIR__ . '/vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src' );
|
35 |
|
36 |
// Configures log to go through console.
|
37 |
\Logger::configure(
|
68 |
|
69 |
defined( 'ABSPATH' ) || die( 'Shame on you' );
|
70 |
|
71 |
+
define( 'IA_PLUGIN_VERSION', '4.0.0' );
|
72 |
define( 'IA_PLUGIN_PATH_FULL', __FILE__ );
|
73 |
define( 'IA_PLUGIN_PATH', plugin_basename( __FILE__ ) );
|
74 |
define( 'IA_PLUGIN_FILE_BASENAME', pathinfo( __FILE__, PATHINFO_FILENAME ) );
|
75 |
define( 'IA_PLUGIN_TEXT_DOMAIN', 'instant-articles' );
|
76 |
+
define( 'IA_PLUGIN_FORCE_SUBMIT_KEY', 'instant_articles_force_submit' );
|
77 |
|
78 |
// Let users define their own feed slug.
|
79 |
if ( ! defined( 'INSTANT_ARTICLES_SLUG' ) ) {
|
84 |
require_once( dirname( __FILE__ ) . '/class-instant-articles-post.php' );
|
85 |
require_once( dirname( __FILE__ ) . '/wizard/class-instant-articles-wizard.php' );
|
86 |
require_once( dirname( __FILE__ ) . '/meta-box/class-instant-articles-meta-box.php' );
|
87 |
+
require_once( dirname( __FILE__ ) . '/class-instant-articles-amp-markup.php' );
|
88 |
|
89 |
/**
|
90 |
* Plugin activation hook to add our rewrite rules.
|
104 |
add_action( 'network_admin_notices', 'instant_articles_setup_admin_notice' ); // also show message on multisite
|
105 |
function instant_articles_setup_admin_notice() {
|
106 |
global $pagenow;
|
107 |
+
if ( $pagenow === 'plugins.php' && ! Instant_Articles_Option_FB_Page::get_option_decoded()[ "page_id" ] ) {
|
108 |
$settings_url = Instant_Articles_Wizard::get_url();
|
109 |
echo '<div class="updated settings-error notice is-dismissible">';
|
110 |
echo '<p>Congrats, you\'ve installed the Instant Articles for WP plugin. Now <a href="' . esc_url_raw($settings_url) . '">set it up</a> to start publishing Instant Articles.';
|
316 |
IA_PLUGIN_VERSION,
|
317 |
false
|
318 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
}
|
320 |
add_action( 'init', 'instant_articles_register_scripts' );
|
321 |
|
349 |
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
350 |
$fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
|
351 |
|
352 |
+
if ( isset( $fb_page_settings[ 'page_id' ] ) ) {
|
353 |
?>
|
354 |
+
<meta property="fb:pages" content="<?php echo esc_attr( $fb_page_settings[ 'page_id' ] ); ?>" />
|
355 |
<?php
|
356 |
}
|
357 |
}
|
358 |
add_action( 'wp_head', 'inject_url_claiming_meta_tag' );
|
359 |
|
360 |
+
/**
|
361 |
+
* Automatically add meta tag for Instant Articles Open Publish scraper
|
362 |
+
*
|
363 |
+
* @since 4.0
|
364 |
+
*/
|
365 |
+
function inject_ia_markup_meta_tag() {
|
366 |
+
$post = get_post();
|
367 |
+
// Transform the post to an Instant Article.
|
368 |
+
$adapter = new Instant_Articles_Post( $post );
|
369 |
+
if ( $adapter->should_submit_post() ) {
|
370 |
+
$url = $adapter->get_canonical_url();
|
371 |
+
$url = add_query_arg( 'ia_markup', '1', $url );
|
372 |
+
$fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
|
373 |
+
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
374 |
+
$dev_mode = isset( $publishing_settings['dev_mode'] )
|
375 |
+
? ( $publishing_settings['dev_mode'] ? true : false )
|
376 |
+
: false;
|
377 |
+
|
378 |
+
if ( $dev_mode ) {
|
379 |
+
?>
|
380 |
+
<meta property="ia:markup_url_dev" content="<?php echo esc_attr( $url ); ?>" />
|
381 |
+
<?php
|
382 |
+
} else {
|
383 |
+
?>
|
384 |
+
<meta property="ia:markup_url" content="<?php echo esc_attr( $url ); ?>" />
|
385 |
+
<?php
|
386 |
+
}
|
387 |
+
}
|
388 |
+
}
|
389 |
+
add_action( 'wp_head', 'inject_ia_markup_meta_tag' );
|
390 |
+
|
391 |
+
// Injects the <link rel...> tag if the AMP Markup is enabled
|
392 |
+
add_action( 'wp_head', array('Instant_Articles_AMP_Markup', 'inject_link_rel') );
|
393 |
+
|
394 |
// Initialize the Instant Articles meta box.
|
395 |
Instant_Articles_Meta_Box::init();
|
396 |
|
397 |
+
function ia_markup_version( ) {
|
398 |
+
$post = get_post();
|
399 |
+
|
400 |
+
if (isset( $_GET[ 'ia_markup' ] ) && $_GET[ 'ia_markup' ]) {
|
401 |
+
// Transform the post to an Instant Article.
|
402 |
+
$adapter = new Instant_Articles_Post( $post );
|
403 |
+
$article = $adapter->to_instant_article();
|
404 |
+
echo $article->render( null, true );
|
405 |
+
|
406 |
+
die();
|
407 |
+
}
|
408 |
+
}
|
409 |
+
add_action( 'wp', 'ia_markup_version' );
|
410 |
+
|
411 |
+
// Add hook for generating the AMP markup
|
412 |
+
add_action( 'wp', array('Instant_Articles_AMP_Markup', 'markup_version') );
|
413 |
|
|
|
414 |
Instant_Articles_Wizard::init();
|
415 |
+
|
416 |
+
function rescrape_article( $post_id, $post ) {
|
417 |
+
$adapter = new Instant_Articles_Post( $post );
|
418 |
+
$old_slugs = get_post_meta( $post_id, '_wp_old_slug' );
|
419 |
+
if ( $adapter->should_submit_post() ) {
|
420 |
+
try {
|
421 |
+
$client = Facebook\HttpClients\HttpClientsFactory::createHttpClient( null );
|
422 |
+
$url_encoded = urlencode($adapter->get_canonical_url());
|
423 |
+
$client->send(
|
424 |
+
"https://graph.facebook.com/?id=$url_encoded&scrape=true",
|
425 |
+
'POST',
|
426 |
+
'',
|
427 |
+
array(),
|
428 |
+
60
|
429 |
+
);
|
430 |
+
foreach ( $old_slugs as $slug ) {
|
431 |
+
$clone_post = clone $post;
|
432 |
+
$clone_post->post_name = $slug;
|
433 |
+
$clone_adapter = new Instant_Articles_Post( $clone_post );
|
434 |
+
|
435 |
+
$url_encoded = urlencode($clone_adapter->get_canonical_url());
|
436 |
+
$client->send(
|
437 |
+
"https://graph.facebook.com/?id=$url_encoded&scrape=true",
|
438 |
+
'POST',
|
439 |
+
'',
|
440 |
+
array(),
|
441 |
+
60
|
442 |
+
);
|
443 |
+
}
|
444 |
+
} catch ( Exception $e ) {
|
445 |
+
Logger::getLogger( 'instantarticles-wp-plugin' )->error(
|
446 |
+
'Unable to submit article.',
|
447 |
+
$e->getTraceAsString()
|
448 |
+
);
|
449 |
+
}
|
450 |
+
}
|
451 |
+
}
|
452 |
+
add_action( 'save_post', 'rescrape_article', 999, 2 );
|
453 |
+
|
454 |
+
|
455 |
}
|
meta-box/class-instant-articles-meta-box.php
CHANGED
@@ -75,8 +75,7 @@ class Instant_Articles_Meta_Box {
|
|
75 |
|
76 |
check_ajax_referer( 'instant-articles-force-submit-' . $post_id, 'security' );
|
77 |
$force = sanitize_text_field( $_POST[ 'force' ] ) === 'true';
|
78 |
-
update_post_meta( $post_id,
|
79 |
-
Instant_Articles_Publisher::submit_article( $post_id, get_post( $post_id ) );
|
80 |
}
|
81 |
|
82 |
/**
|
@@ -94,53 +93,22 @@ class Instant_Articles_Meta_Box {
|
|
94 |
$adapter = new Instant_Articles_Post( $post );
|
95 |
$article = $adapter->to_instant_article();
|
96 |
$canonical_url = $adapter->get_canonical_url();
|
97 |
-
$
|
98 |
-
$published = 'publish' === $post->post_status;
|
99 |
$dev_mode = false;
|
100 |
-
$force_submit = get_post_meta( $post_id,
|
101 |
-
$
|
102 |
|
103 |
Instant_Articles_Wizard::menu_items();
|
104 |
$settings_page_href = Instant_Articles_Wizard::get_url();
|
105 |
|
106 |
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
107 |
$publish_with_warnings = $publishing_settings[ 'publish_with_warnings' ];
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
$dev_mode = isset( $publishing_settings['dev_mode'] )
|
115 |
-
? ( $publishing_settings['dev_mode'] ? true : false )
|
116 |
-
: false;
|
117 |
-
|
118 |
-
if ( isset( $fb_app_settings['app_id'] )
|
119 |
-
&& isset( $fb_app_settings['app_secret'] )
|
120 |
-
&& isset( $fb_page_settings['page_access_token'] )
|
121 |
-
&& isset( $fb_page_settings['page_id'] ) ) {
|
122 |
-
// Instantiate a new Client to get the status of this article.
|
123 |
-
$client = Client::create(
|
124 |
-
$fb_app_settings['app_id'],
|
125 |
-
$fb_app_settings['app_secret'],
|
126 |
-
$fb_page_settings['page_access_token'],
|
127 |
-
$fb_page_settings['page_id'],
|
128 |
-
$dev_mode
|
129 |
-
);
|
130 |
-
|
131 |
-
$submission_status_id = get_post_meta( $post_id, Instant_Articles_Publisher::SUBMISSION_ID_KEY, true );
|
132 |
-
if ( ! empty( $submission_status_id ) ) {
|
133 |
-
$submission_status = $client->getSubmissionStatus( $submission_status_id );
|
134 |
-
} else {
|
135 |
-
// Grab the latest status of this article and display.
|
136 |
-
$article_id = $client->getArticleIDFromCanonicalURL( $canonical_url );
|
137 |
-
$submission_status = $client->getLastSubmissionStatus( $article_id );
|
138 |
-
}
|
139 |
-
}
|
140 |
-
} catch ( FacebookResponseException $e ) {
|
141 |
-
$submission_status = null;
|
142 |
-
}
|
143 |
-
}
|
144 |
|
145 |
include( dirname( __FILE__ ) . '/meta-box-template.php' );
|
146 |
|
75 |
|
76 |
check_ajax_referer( 'instant-articles-force-submit-' . $post_id, 'security' );
|
77 |
$force = sanitize_text_field( $_POST[ 'force' ] ) === 'true';
|
78 |
+
update_post_meta( $post_id, IA_PLUGIN_FORCE_SUBMIT_KEY, $force );
|
|
|
79 |
}
|
80 |
|
81 |
/**
|
93 |
$adapter = new Instant_Articles_Post( $post );
|
94 |
$article = $adapter->to_instant_article();
|
95 |
$canonical_url = $adapter->get_canonical_url();
|
96 |
+
$published = ( 'publish' === $post->post_status );
|
|
|
97 |
$dev_mode = false;
|
98 |
+
$force_submit = get_post_meta( $post_id, IA_PLUGIN_FORCE_SUBMIT_KEY, true );
|
99 |
+
$instant_articles_should_submit_post_filter = apply_filters( 'instant_articles_should_submit_post', true, $adapter );
|
100 |
|
101 |
Instant_Articles_Wizard::menu_items();
|
102 |
$settings_page_href = Instant_Articles_Wizard::get_url();
|
103 |
|
104 |
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
105 |
$publish_with_warnings = $publishing_settings[ 'publish_with_warnings' ];
|
106 |
+
$fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
|
107 |
+
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
|
108 |
+
|
109 |
+
$dev_mode = isset( $publishing_settings['dev_mode'] )
|
110 |
+
? ( $publishing_settings['dev_mode'] ? true : false )
|
111 |
+
: false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
include( dirname( __FILE__ ) . '/meta-box-template.php' );
|
114 |
|
meta-box/meta-box-template.php
CHANGED
@@ -18,135 +18,64 @@ use Facebook\InstantArticles\Client\ServerMessage;
|
|
18 |
</a>
|
19 |
<?php endif; ?>
|
20 |
|
21 |
-
<?php if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
<p>
|
23 |
<b>
|
24 |
<span class="dashicons dashicons-no-alt"></span>
|
25 |
This post will not be submitted to Instant Articles due to a rule created in your site.
|
26 |
</b>
|
27 |
</p>
|
|
|
28 |
<?php elseif ( ! $published ) : ?>
|
29 |
<p>
|
30 |
<b>
|
31 |
<span class="dashicons dashicons-media-document"></span>
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
</b>
|
34 |
</p>
|
35 |
-
|
36 |
-
<?php elseif ( $submission_status ) : ?>
|
37 |
-
|
38 |
-
<!-- Display the last submission status -->
|
39 |
-
<?php switch ( $submission_status->getStatus() ) :
|
40 |
-
case InstantArticleStatus::SUCCESS : ?>
|
41 |
-
<p>
|
42 |
-
<b>
|
43 |
-
<span class="dashicons dashicons-yes"></span>
|
44 |
-
Your article was submitted to Instant Articles successfully
|
45 |
-
</b>
|
46 |
-
</p>
|
47 |
-
<?php break; ?>
|
48 |
-
|
49 |
-
<?php case InstantArticleStatus::FAILED : ?>
|
50 |
-
<p>
|
51 |
-
<b>
|
52 |
-
<span class="dashicons dashicons-no-alt"></span>
|
53 |
-
It wasn't possible to submit your article
|
54 |
-
</b>
|
55 |
-
</p>
|
56 |
-
<?php break; ?>
|
57 |
-
|
58 |
-
<?php case InstantArticleStatus::IN_PROGRESS : ?>
|
59 |
-
<p>
|
60 |
-
<b>
|
61 |
-
<span class="dashicons dashicons-update"></span>
|
62 |
-
Your article is being submitted...
|
63 |
-
</b>
|
64 |
-
</p>
|
65 |
-
<script>
|
66 |
-
setTimeout(function () {
|
67 |
-
instant_articles_load_meta_box( <?php echo absint( $post->ID ); ?> );
|
68 |
-
}, 2000);
|
69 |
-
</script>
|
70 |
-
|
71 |
-
<?php break; ?>
|
72 |
-
|
73 |
-
<?php default : ?>
|
74 |
-
<p>
|
75 |
-
<b>
|
76 |
-
<span class="dashicons dashicons-no-alt"></span>
|
77 |
-
This post was not yet submitted to Instant Articles.
|
78 |
-
</b>
|
79 |
-
</p>
|
80 |
-
<?php break; ?>
|
81 |
-
|
82 |
-
<?php endswitch; ?>
|
83 |
-
|
84 |
-
|
85 |
-
<!-- Display the submission messages if any -->
|
86 |
-
<?php if ( count( $submission_status->getMessages() ) > 0 ) : ?>
|
87 |
-
|
88 |
-
<p>The server responded with the following messages:</p>
|
89 |
-
|
90 |
-
<ul class="instant-articles-messages">
|
91 |
-
|
92 |
-
<?php foreach ( $submission_status->getMessages() as $message ) : ?>
|
93 |
-
|
94 |
-
<?php switch ( $message->getLevel() ) :
|
95 |
-
case ServerMessage::WARNING : ?>
|
96 |
-
<li class="wp-ui-text-highlight">
|
97 |
-
<span class="dashicons dashicons-warning"></span>
|
98 |
-
<div>
|
99 |
-
<?php echo esc_html( $message->getMessage() ); ?>
|
100 |
-
</div>
|
101 |
-
</li>
|
102 |
-
<?php break; ?>
|
103 |
-
|
104 |
-
<?php case ServerMessage::ERROR : ?>
|
105 |
-
<li class="wp-ui-text-notification">
|
106 |
-
<span class="dashicons dashicons-dismiss"></span>
|
107 |
-
<div>
|
108 |
-
<?php echo esc_html( $message->getMessage() ); ?>
|
109 |
-
</div>
|
110 |
-
</li>
|
111 |
-
<?php break; ?>
|
112 |
-
|
113 |
-
<?php case ServerMessage::FATAL : ?>
|
114 |
-
<li class="wp-ui-text-notification">
|
115 |
-
<span class="dashicons dashicons-sos"></span>
|
116 |
-
<div>
|
117 |
-
<?php echo esc_html( $message->getMessage() ); ?>
|
118 |
-
</div>
|
119 |
-
</li>
|
120 |
-
<?php break; ?>
|
121 |
-
|
122 |
-
<?php default: ?>
|
123 |
-
<li class="wp-ui-text-highlight">
|
124 |
-
<span class="dashicons dashicons-info"></span>
|
125 |
-
<div>
|
126 |
-
<?php echo esc_html( $message->getMessage() ); ?>
|
127 |
-
</div>
|
128 |
-
</li>
|
129 |
-
|
130 |
-
<?php endswitch; ?>
|
131 |
-
|
132 |
-
<?php endforeach; ?>
|
133 |
-
</ul>
|
134 |
-
|
135 |
-
<?php endif; ?>
|
136 |
-
|
137 |
-
<?php else : ?>
|
138 |
-
|
139 |
-
<p>
|
140 |
-
<b>
|
141 |
-
<span class="dashicons dashicons-no-alt"></span>
|
142 |
-
Could not connect to your page. Please check the
|
143 |
-
<a href="<?php echo esc_url( $settings_page_href ); ?>">Instant Articles plugin settings</a>.
|
144 |
-
</b>
|
145 |
-
</p>
|
146 |
-
|
147 |
-
<?php endif; ?>
|
148 |
-
|
149 |
<hr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
<!-- Transformer messages -->
|
152 |
<?php if ( count( $adapter->transformer->getWarnings() ) > 0 ) : ?>
|
18 |
</a>
|
19 |
<?php endif; ?>
|
20 |
|
21 |
+
<?php if ( $adapter->should_submit_post() ) : ?>
|
22 |
+
<p>
|
23 |
+
<b>
|
24 |
+
<span class="dashicons dashicons-yes"></span>
|
25 |
+
This post will be available as an Instant Article.
|
26 |
+
</b>
|
27 |
+
</p>
|
28 |
+
<hr>
|
29 |
+
<?php elseif ( ! $instant_articles_should_submit_post_filter ) : ?>
|
30 |
<p>
|
31 |
<b>
|
32 |
<span class="dashicons dashicons-no-alt"></span>
|
33 |
This post will not be submitted to Instant Articles due to a rule created in your site.
|
34 |
</b>
|
35 |
</p>
|
36 |
+
<hr>
|
37 |
<?php elseif ( ! $published ) : ?>
|
38 |
<p>
|
39 |
<b>
|
40 |
<span class="dashicons dashicons-media-document"></span>
|
41 |
+
This post will be submitted to Instant Articles once it is published.
|
42 |
+
</b>
|
43 |
+
</p>
|
44 |
+
<hr>
|
45 |
+
<?php elseif ( ! $article->getHeader() || ! $article->getHeader()->getTitle() ) : ?>
|
46 |
+
<p>
|
47 |
+
<b>
|
48 |
+
<span class="dashicons dashicons-no-alt"></span>
|
49 |
+
This post will not be submitted to Instant Articles because it is missing a title.
|
50 |
+
</b>
|
51 |
+
</p>
|
52 |
+
<hr>
|
53 |
+
<?php elseif ( count( $article->getChildren() ) === 0 ) : ?>
|
54 |
+
<p>
|
55 |
+
<b>
|
56 |
+
<span class="dashicons dashicons-no-alt"></span>
|
57 |
+
This post will not be submitted to Instant Articles because it is missing content.
|
58 |
+
</b>
|
59 |
+
</p>
|
60 |
+
<hr>
|
61 |
+
<?php elseif ( ! $fb_page_settings[ "page_id" ] ) : ?>
|
62 |
+
<p>
|
63 |
+
<b>
|
64 |
+
<span class="dashicons dashicons-no-alt"></span>
|
65 |
+
No Facebook Page was selected. Please configure your page in the
|
66 |
+
<a href="<?php echo esc_url( $settings_page_href ); ?>">Instant Articles plugin settings</a>.
|
67 |
</b>
|
68 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
<hr>
|
70 |
+
<?php elseif ( count( $adapter->transformer->getWarnings() ) > 0 ) : ?>
|
71 |
+
<p>
|
72 |
+
<b>
|
73 |
+
<span class="dashicons dashicons-no-alt"></span>
|
74 |
+
This post will not be submitted to Instant Articles because the transformation raised some warnings.
|
75 |
+
</b>
|
76 |
+
</p>
|
77 |
+
<hr>
|
78 |
+
<?php endif; ?>
|
79 |
|
80 |
<!-- Transformer messages -->
|
81 |
<?php if ( count( $adapter->transformer->getWarnings() ) > 0 ) : ?>
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: trrine, olethomas, bjornjohansen, dekode, automattic, facebook
|
|
3 |
Tags: instant articles, facebook, mobile
|
4 |
Requires at least: 4.3
|
5 |
Tested up to: 4.6
|
6 |
-
Stable tag:
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
3 |
Tags: instant articles, facebook, mobile
|
4 |
Requires at least: 4.3
|
5 |
Tested up to: 4.6
|
6 |
+
Stable tag: 4.0.0
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
rules-configuration.json
CHANGED
@@ -26,6 +26,9 @@
|
|
26 |
}, {
|
27 |
"class": "ParagraphRule",
|
28 |
"selector": "p"
|
|
|
|
|
|
|
29 |
}, {
|
30 |
"class": "LineBreakRule",
|
31 |
"selector": "br"
|
26 |
}, {
|
27 |
"class": "ParagraphRule",
|
28 |
"selector": "p"
|
29 |
+
}, {
|
30 |
+
"class": "FooterSmallRule",
|
31 |
+
"selector": "small"
|
32 |
}, {
|
33 |
"class": "LineBreakRule",
|
34 |
"selector": "br"
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit36fdde57bb31390b63c9fa4f374d8837::getLoader();
|
vendor/bin/phpcbf
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env php
|
2 |
+
<?php
|
3 |
+
/**
|
4 |
+
* PHP Code Beautifier and Fixer
|
5 |
+
*
|
6 |
+
* PHP version 5
|
7 |
+
*
|
8 |
+
* @category PHP
|
9 |
+
* @package PHP_CodeSniffer
|
10 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
11 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
12 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
13 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
14 |
+
*/
|
15 |
+
|
16 |
+
if (is_file(dirname(__FILE__).'/../CodeSniffer/CLI.php') === true) {
|
17 |
+
include_once dirname(__FILE__).'/../CodeSniffer/CLI.php';
|
18 |
+
} else {
|
19 |
+
include_once 'PHP/CodeSniffer/CLI.php';
|
20 |
+
}
|
21 |
+
|
22 |
+
$cli = new PHP_CodeSniffer_CLI();
|
23 |
+
$cli->runphpcbf();
|
vendor/bin/phpcs
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env php
|
2 |
+
<?php
|
3 |
+
/**
|
4 |
+
* PHP_CodeSniffer tokenizes PHP code and detects violations of a
|
5 |
+
* defined set of coding standards.
|
6 |
+
*
|
7 |
+
* PHP version 5
|
8 |
+
*
|
9 |
+
* @category PHP
|
10 |
+
* @package PHP_CodeSniffer
|
11 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
12 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
13 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
14 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
15 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
16 |
+
*/
|
17 |
+
|
18 |
+
if (is_file(dirname(__FILE__).'/../CodeSniffer/CLI.php') === true) {
|
19 |
+
include_once dirname(__FILE__).'/../CodeSniffer/CLI.php';
|
20 |
+
} else {
|
21 |
+
include_once 'PHP/CodeSniffer/CLI.php';
|
22 |
+
}
|
23 |
+
|
24 |
+
$cli = new PHP_CodeSniffer_CLI();
|
25 |
+
$cli->runphpcs();
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -6,6 +6,68 @@ $vendorDir = dirname(dirname(__FILE__));
|
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
'Logger' => $vendorDir . '/apache/log4php/src/main/php/Logger.php',
|
10 |
'LoggerAppender' => $vendorDir . '/apache/log4php/src/main/php/LoggerAppender.php',
|
11 |
'LoggerAppenderConsole' => $vendorDir . '/apache/log4php/src/main/php/appenders/LoggerAppenderConsole.php',
|
@@ -85,4 +147,194 @@ return array(
|
|
85 |
'LoggerRoot' => $vendorDir . '/apache/log4php/src/main/php/LoggerRoot.php',
|
86 |
'LoggerThrowableInformation' => $vendorDir . '/apache/log4php/src/main/php/LoggerThrowableInformation.php',
|
87 |
'LoggerUtils' => $vendorDir . '/apache/log4php/src/main/php/helpers/LoggerUtils.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
);
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
9 |
+
'Generic_Sniffs_Arrays_DisallowLongArraySyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowLongArraySyntaxSniff.php',
|
10 |
+
'Generic_Sniffs_Arrays_DisallowShortArraySyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowShortArraySyntaxSniff.php',
|
11 |
+
'Generic_Sniffs_Classes_DuplicateClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php',
|
12 |
+
'Generic_Sniffs_Classes_OpeningBraceSameLineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/OpeningBraceSameLineSniff.php',
|
13 |
+
'Generic_Sniffs_CodeAnalysis_EmptyStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php',
|
14 |
+
'Generic_Sniffs_CodeAnalysis_ForLoopShouldBeWhileLoopSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php',
|
15 |
+
'Generic_Sniffs_CodeAnalysis_ForLoopWithTestFunctionCallSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php',
|
16 |
+
'Generic_Sniffs_CodeAnalysis_JumbledIncrementerSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php',
|
17 |
+
'Generic_Sniffs_CodeAnalysis_UnconditionalIfStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php',
|
18 |
+
'Generic_Sniffs_CodeAnalysis_UnnecessaryFinalModifierSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php',
|
19 |
+
'Generic_Sniffs_CodeAnalysis_UnusedFunctionParameterSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php',
|
20 |
+
'Generic_Sniffs_CodeAnalysis_UselessOverridingMethodSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php',
|
21 |
+
'Generic_Sniffs_Commenting_DocCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php',
|
22 |
+
'Generic_Sniffs_Commenting_FixmeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/FixmeSniff.php',
|
23 |
+
'Generic_Sniffs_Commenting_TodoSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php',
|
24 |
+
'Generic_Sniffs_ControlStructures_InlineControlStructureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php',
|
25 |
+
'Generic_Sniffs_Debug_CSSLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php',
|
26 |
+
'Generic_Sniffs_Debug_ClosureLinterSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php',
|
27 |
+
'Generic_Sniffs_Debug_ESLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ESLintSniff.php',
|
28 |
+
'Generic_Sniffs_Debug_JSHintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php',
|
29 |
+
'Generic_Sniffs_Files_ByteOrderMarkSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/ByteOrderMarkSniff.php',
|
30 |
+
'Generic_Sniffs_Files_EndFileNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNewlineSniff.php',
|
31 |
+
'Generic_Sniffs_Files_EndFileNoNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNoNewlineSniff.php',
|
32 |
+
'Generic_Sniffs_Files_InlineHTMLSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/InlineHTMLSniff.php',
|
33 |
+
'Generic_Sniffs_Files_LineEndingsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineEndingsSniff.php',
|
34 |
+
'Generic_Sniffs_Files_LineLengthSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineLengthSniff.php',
|
35 |
+
'Generic_Sniffs_Files_LowercasedFilenameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LowercasedFilenameSniff.php',
|
36 |
+
'Generic_Sniffs_Files_OneClassPerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneClassPerFileSniff.php',
|
37 |
+
'Generic_Sniffs_Files_OneInterfacePerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneInterfacePerFileSniff.php',
|
38 |
+
'Generic_Sniffs_Files_OneTraitPerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneTraitPerFileSniff.php',
|
39 |
+
'Generic_Sniffs_Formatting_DisallowMultipleStatementsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/DisallowMultipleStatementsSniff.php',
|
40 |
+
'Generic_Sniffs_Formatting_MultipleStatementAlignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php',
|
41 |
+
'Generic_Sniffs_Formatting_NoSpaceAfterCastSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/NoSpaceAfterCastSniff.php',
|
42 |
+
'Generic_Sniffs_Formatting_SpaceAfterCastSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterCastSniff.php',
|
43 |
+
'Generic_Sniffs_Formatting_SpaceAfterNotSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php',
|
44 |
+
'Generic_Sniffs_Functions_CallTimePassByReferenceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/CallTimePassByReferenceSniff.php',
|
45 |
+
'Generic_Sniffs_Functions_FunctionCallArgumentSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php',
|
46 |
+
'Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php',
|
47 |
+
'Generic_Sniffs_Functions_OpeningFunctionBraceKernighanRitchieSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php',
|
48 |
+
'Generic_Sniffs_Metrics_CyclomaticComplexitySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php',
|
49 |
+
'Generic_Sniffs_Metrics_NestingLevelSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/NestingLevelSniff.php',
|
50 |
+
'Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php',
|
51 |
+
'Generic_Sniffs_NamingConventions_ConstructorNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/ConstructorNameSniff.php',
|
52 |
+
'Generic_Sniffs_NamingConventions_UpperCaseConstantNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
|
53 |
+
'Generic_Sniffs_PHP_BacktickOperatorSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/BacktickOperatorSniff.php',
|
54 |
+
'Generic_Sniffs_PHP_CharacterBeforePHPOpeningTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/CharacterBeforePHPOpeningTagSniff.php',
|
55 |
+
'Generic_Sniffs_PHP_ClosingPHPTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ClosingPHPTagSniff.php',
|
56 |
+
'Generic_Sniffs_PHP_DeprecatedFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php',
|
57 |
+
'Generic_Sniffs_PHP_DisallowAlternativePHPTagsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php',
|
58 |
+
'Generic_Sniffs_PHP_DisallowShortOpenTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php',
|
59 |
+
'Generic_Sniffs_PHP_ForbiddenFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php',
|
60 |
+
'Generic_Sniffs_PHP_LowerCaseConstantSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseConstantSniff.php',
|
61 |
+
'Generic_Sniffs_PHP_LowerCaseKeywordSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseKeywordSniff.php',
|
62 |
+
'Generic_Sniffs_PHP_NoSilencedErrorsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/NoSilencedErrorsSniff.php',
|
63 |
+
'Generic_Sniffs_PHP_SAPIUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SAPIUsageSniff.php',
|
64 |
+
'Generic_Sniffs_PHP_SyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php',
|
65 |
+
'Generic_Sniffs_PHP_UpperCaseConstantSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/UpperCaseConstantSniff.php',
|
66 |
+
'Generic_Sniffs_Strings_UnnecessaryStringConcatSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Strings/UnnecessaryStringConcatSniff.php',
|
67 |
+
'Generic_Sniffs_VersionControl_SubversionPropertiesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/VersionControl/SubversionPropertiesSniff.php',
|
68 |
+
'Generic_Sniffs_WhiteSpace_DisallowSpaceIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowSpaceIndentSniff.php',
|
69 |
+
'Generic_Sniffs_WhiteSpace_DisallowTabIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
|
70 |
+
'Generic_Sniffs_WhiteSpace_ScopeIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/ScopeIndentSniff.php',
|
71 |
'Logger' => $vendorDir . '/apache/log4php/src/main/php/Logger.php',
|
72 |
'LoggerAppender' => $vendorDir . '/apache/log4php/src/main/php/LoggerAppender.php',
|
73 |
'LoggerAppenderConsole' => $vendorDir . '/apache/log4php/src/main/php/appenders/LoggerAppenderConsole.php',
|
147 |
'LoggerRoot' => $vendorDir . '/apache/log4php/src/main/php/LoggerRoot.php',
|
148 |
'LoggerThrowableInformation' => $vendorDir . '/apache/log4php/src/main/php/LoggerThrowableInformation.php',
|
149 |
'LoggerUtils' => $vendorDir . '/apache/log4php/src/main/php/helpers/LoggerUtils.php',
|
150 |
+
'MySource_Sniffs_CSS_BrowserSpecificStylesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/CSS/BrowserSpecificStylesSniff.php',
|
151 |
+
'MySource_Sniffs_Channels_DisallowSelfActionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/DisallowSelfActionsSniff.php',
|
152 |
+
'MySource_Sniffs_Channels_IncludeOwnSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeOwnSystemSniff.php',
|
153 |
+
'MySource_Sniffs_Channels_IncludeSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeSystemSniff.php',
|
154 |
+
'MySource_Sniffs_Channels_UnusedSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/UnusedSystemSniff.php',
|
155 |
+
'MySource_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Commenting/FunctionCommentSniff.php',
|
156 |
+
'MySource_Sniffs_Debug_DebugCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/DebugCodeSniff.php',
|
157 |
+
'MySource_Sniffs_Debug_FirebugConsoleSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/FirebugConsoleSniff.php',
|
158 |
+
'MySource_Sniffs_Objects_AssignThisSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/AssignThisSniff.php',
|
159 |
+
'MySource_Sniffs_Objects_CreateWidgetTypeCallbackSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/CreateWidgetTypeCallbackSniff.php',
|
160 |
+
'MySource_Sniffs_Objects_DisallowNewWidgetSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/DisallowNewWidgetSniff.php',
|
161 |
+
'MySource_Sniffs_PHP_AjaxNullComparisonSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/AjaxNullComparisonSniff.php',
|
162 |
+
'MySource_Sniffs_PHP_EvalObjectFactorySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/EvalObjectFactorySniff.php',
|
163 |
+
'MySource_Sniffs_PHP_GetRequestDataSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/GetRequestDataSniff.php',
|
164 |
+
'MySource_Sniffs_PHP_ReturnFunctionValueSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/ReturnFunctionValueSniff.php',
|
165 |
+
'MySource_Sniffs_Strings_JoinStringsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Strings/JoinStringsSniff.php',
|
166 |
+
'PEAR_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Classes/ClassDeclarationSniff.php',
|
167 |
+
'PEAR_Sniffs_Commenting_ClassCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/ClassCommentSniff.php',
|
168 |
+
'PEAR_Sniffs_Commenting_FileCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FileCommentSniff.php',
|
169 |
+
'PEAR_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php',
|
170 |
+
'PEAR_Sniffs_Commenting_InlineCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/InlineCommentSniff.php',
|
171 |
+
'PEAR_Sniffs_ControlStructures_ControlSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/ControlSignatureSniff.php',
|
172 |
+
'PEAR_Sniffs_ControlStructures_MultiLineConditionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/MultiLineConditionSniff.php',
|
173 |
+
'PEAR_Sniffs_Files_IncludingFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Files/IncludingFileSniff.php',
|
174 |
+
'PEAR_Sniffs_Formatting_MultiLineAssignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Formatting/MultiLineAssignmentSniff.php',
|
175 |
+
'PEAR_Sniffs_Functions_FunctionCallSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionCallSignatureSniff.php',
|
176 |
+
'PEAR_Sniffs_Functions_FunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php',
|
177 |
+
'PEAR_Sniffs_Functions_ValidDefaultValueSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/ValidDefaultValueSniff.php',
|
178 |
+
'PEAR_Sniffs_NamingConventions_ValidClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidClassNameSniff.php',
|
179 |
+
'PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
|
180 |
+
'PEAR_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
181 |
+
'PEAR_Sniffs_WhiteSpace_ObjectOperatorIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php',
|
182 |
+
'PEAR_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
|
183 |
+
'PEAR_Sniffs_WhiteSpace_ScopeIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeIndentSniff.php',
|
184 |
+
'PHP_CodeSniffer' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer.php',
|
185 |
+
'PHP_CodeSniffer_CLI' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/CLI.php',
|
186 |
+
'PHP_CodeSniffer_DocGenerators_Generator' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php',
|
187 |
+
'PHP_CodeSniffer_DocGenerators_HTML' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php',
|
188 |
+
'PHP_CodeSniffer_DocGenerators_Markdown' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php',
|
189 |
+
'PHP_CodeSniffer_DocGenerators_Text' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php',
|
190 |
+
'PHP_CodeSniffer_Exception' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Exception.php',
|
191 |
+
'PHP_CodeSniffer_File' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/File.php',
|
192 |
+
'PHP_CodeSniffer_Fixer' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Fixer.php',
|
193 |
+
'PHP_CodeSniffer_Report' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Report.php',
|
194 |
+
'PHP_CodeSniffer_Reporting' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reporting.php',
|
195 |
+
'PHP_CodeSniffer_Reports_Cbf' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Cbf.php',
|
196 |
+
'PHP_CodeSniffer_Reports_Checkstyle' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Checkstyle.php',
|
197 |
+
'PHP_CodeSniffer_Reports_Csv' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Csv.php',
|
198 |
+
'PHP_CodeSniffer_Reports_Diff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Diff.php',
|
199 |
+
'PHP_CodeSniffer_Reports_Emacs' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Emacs.php',
|
200 |
+
'PHP_CodeSniffer_Reports_Full' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Full.php',
|
201 |
+
'PHP_CodeSniffer_Reports_Gitblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Gitblame.php',
|
202 |
+
'PHP_CodeSniffer_Reports_Hgblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Hgblame.php',
|
203 |
+
'PHP_CodeSniffer_Reports_Info' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Info.php',
|
204 |
+
'PHP_CodeSniffer_Reports_Json' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Json.php',
|
205 |
+
'PHP_CodeSniffer_Reports_Junit' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Junit.php',
|
206 |
+
'PHP_CodeSniffer_Reports_Notifysend' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Notifysend.php',
|
207 |
+
'PHP_CodeSniffer_Reports_Source' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Source.php',
|
208 |
+
'PHP_CodeSniffer_Reports_Summary' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Summary.php',
|
209 |
+
'PHP_CodeSniffer_Reports_Svnblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Svnblame.php',
|
210 |
+
'PHP_CodeSniffer_Reports_VersionControl' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/VersionControl.php',
|
211 |
+
'PHP_CodeSniffer_Reports_Xml' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Xml.php',
|
212 |
+
'PHP_CodeSniffer_Sniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Sniff.php',
|
213 |
+
'PHP_CodeSniffer_Standards_AbstractPatternSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractPatternSniff.php',
|
214 |
+
'PHP_CodeSniffer_Standards_AbstractScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractScopeSniff.php',
|
215 |
+
'PHP_CodeSniffer_Standards_AbstractVariableSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractVariableSniff.php',
|
216 |
+
'PHP_CodeSniffer_Standards_IncorrectPatternException' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/IncorrectPatternException.php',
|
217 |
+
'PHP_CodeSniffer_Tokenizers_CSS' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/CSS.php',
|
218 |
+
'PHP_CodeSniffer_Tokenizers_Comment' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/Comment.php',
|
219 |
+
'PHP_CodeSniffer_Tokenizers_JS' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/JS.php',
|
220 |
+
'PHP_CodeSniffer_Tokenizers_PHP' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/PHP.php',
|
221 |
+
'PHP_CodeSniffer_Tokens' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokens.php',
|
222 |
+
'PSR1_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Classes/ClassDeclarationSniff.php',
|
223 |
+
'PSR1_Sniffs_Files_SideEffectsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Files/SideEffectsSniff.php',
|
224 |
+
'PSR1_Sniffs_Methods_CamelCapsMethodNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Methods/CamelCapsMethodNameSniff.php',
|
225 |
+
'PSR2_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/ClassDeclarationSniff.php',
|
226 |
+
'PSR2_Sniffs_Classes_PropertyDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php',
|
227 |
+
'PSR2_Sniffs_ControlStructures_ControlStructureSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ControlStructureSpacingSniff.php',
|
228 |
+
'PSR2_Sniffs_ControlStructures_ElseIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
|
229 |
+
'PSR2_Sniffs_ControlStructures_SwitchDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
|
230 |
+
'PSR2_Sniffs_Files_ClosingTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/ClosingTagSniff.php',
|
231 |
+
'PSR2_Sniffs_Files_EndFileNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/EndFileNewlineSniff.php',
|
232 |
+
'PSR2_Sniffs_Methods_FunctionCallSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionCallSignatureSniff.php',
|
233 |
+
'PSR2_Sniffs_Methods_FunctionClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionClosingBraceSniff.php',
|
234 |
+
'PSR2_Sniffs_Methods_MethodDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/MethodDeclarationSniff.php',
|
235 |
+
'PSR2_Sniffs_Namespaces_NamespaceDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/NamespaceDeclarationSniff.php',
|
236 |
+
'PSR2_Sniffs_Namespaces_UseDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/UseDeclarationSniff.php',
|
237 |
+
'Squiz_Sniffs_Arrays_ArrayBracketSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayBracketSpacingSniff.php',
|
238 |
+
'Squiz_Sniffs_Arrays_ArrayDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php',
|
239 |
+
'Squiz_Sniffs_CSS_ClassDefinitionClosingBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionClosingBraceSpaceSniff.php',
|
240 |
+
'Squiz_Sniffs_CSS_ClassDefinitionNameSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionNameSpacingSniff.php',
|
241 |
+
'Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionOpeningBraceSpaceSniff.php',
|
242 |
+
'Squiz_Sniffs_CSS_ColonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColonSpacingSniff.php',
|
243 |
+
'Squiz_Sniffs_CSS_ColourDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColourDefinitionSniff.php',
|
244 |
+
'Squiz_Sniffs_CSS_DisallowMultipleStyleDefinitionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DisallowMultipleStyleDefinitionsSniff.php',
|
245 |
+
'Squiz_Sniffs_CSS_DuplicateClassDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateClassDefinitionSniff.php',
|
246 |
+
'Squiz_Sniffs_CSS_DuplicateStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateStyleDefinitionSniff.php',
|
247 |
+
'Squiz_Sniffs_CSS_EmptyClassDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyClassDefinitionSniff.php',
|
248 |
+
'Squiz_Sniffs_CSS_EmptyStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyStyleDefinitionSniff.php',
|
249 |
+
'Squiz_Sniffs_CSS_ForbiddenStylesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ForbiddenStylesSniff.php',
|
250 |
+
'Squiz_Sniffs_CSS_IndentationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/IndentationSniff.php',
|
251 |
+
'Squiz_Sniffs_CSS_LowercaseStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/LowercaseStyleDefinitionSniff.php',
|
252 |
+
'Squiz_Sniffs_CSS_MissingColonSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/MissingColonSniff.php',
|
253 |
+
'Squiz_Sniffs_CSS_NamedColoursSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/NamedColoursSniff.php',
|
254 |
+
'Squiz_Sniffs_CSS_OpacitySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/OpacitySniff.php',
|
255 |
+
'Squiz_Sniffs_CSS_SemicolonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/SemicolonSpacingSniff.php',
|
256 |
+
'Squiz_Sniffs_CSS_ShorthandSizeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ShorthandSizeSniff.php',
|
257 |
+
'Squiz_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassDeclarationSniff.php',
|
258 |
+
'Squiz_Sniffs_Classes_ClassFileNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassFileNameSniff.php',
|
259 |
+
'Squiz_Sniffs_Classes_DuplicatePropertySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/DuplicatePropertySniff.php',
|
260 |
+
'Squiz_Sniffs_Classes_LowercaseClassKeywordsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/LowercaseClassKeywordsSniff.php',
|
261 |
+
'Squiz_Sniffs_Classes_SelfMemberReferenceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php',
|
262 |
+
'Squiz_Sniffs_Classes_ValidClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ValidClassNameSniff.php',
|
263 |
+
'Squiz_Sniffs_Commenting_BlockCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/BlockCommentSniff.php',
|
264 |
+
'Squiz_Sniffs_Commenting_ClassCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClassCommentSniff.php',
|
265 |
+
'Squiz_Sniffs_Commenting_ClosingDeclarationCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClosingDeclarationCommentSniff.php',
|
266 |
+
'Squiz_Sniffs_Commenting_DocCommentAlignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/DocCommentAlignmentSniff.php',
|
267 |
+
'Squiz_Sniffs_Commenting_EmptyCatchCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/EmptyCatchCommentSniff.php',
|
268 |
+
'Squiz_Sniffs_Commenting_FileCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FileCommentSniff.php',
|
269 |
+
'Squiz_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php',
|
270 |
+
'Squiz_Sniffs_Commenting_FunctionCommentThrowTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentThrowTagSniff.php',
|
271 |
+
'Squiz_Sniffs_Commenting_InlineCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/InlineCommentSniff.php',
|
272 |
+
'Squiz_Sniffs_Commenting_LongConditionClosingCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/LongConditionClosingCommentSniff.php',
|
273 |
+
'Squiz_Sniffs_Commenting_PostStatementCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/PostStatementCommentSniff.php',
|
274 |
+
'Squiz_Sniffs_Commenting_VariableCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/VariableCommentSniff.php',
|
275 |
+
'Squiz_Sniffs_ControlStructures_ControlSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ControlSignatureSniff.php',
|
276 |
+
'Squiz_Sniffs_ControlStructures_ElseIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
|
277 |
+
'Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php',
|
278 |
+
'Squiz_Sniffs_ControlStructures_ForLoopDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForLoopDeclarationSniff.php',
|
279 |
+
'Squiz_Sniffs_ControlStructures_InlineIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/InlineIfDeclarationSniff.php',
|
280 |
+
'Squiz_Sniffs_ControlStructures_LowercaseDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/LowercaseDeclarationSniff.php',
|
281 |
+
'Squiz_Sniffs_ControlStructures_SwitchDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
|
282 |
+
'Squiz_Sniffs_Debug_JSLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php',
|
283 |
+
'Squiz_Sniffs_Debug_JavaScriptLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php',
|
284 |
+
'Squiz_Sniffs_Files_FileExtensionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Files/FileExtensionSniff.php',
|
285 |
+
'Squiz_Sniffs_Formatting_OperatorBracketSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Formatting/OperatorBracketSniff.php',
|
286 |
+
'Squiz_Sniffs_Functions_FunctionDeclarationArgumentSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationArgumentSpacingSniff.php',
|
287 |
+
'Squiz_Sniffs_Functions_FunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationSniff.php',
|
288 |
+
'Squiz_Sniffs_Functions_FunctionDuplicateArgumentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDuplicateArgumentSniff.php',
|
289 |
+
'Squiz_Sniffs_Functions_GlobalFunctionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/GlobalFunctionSniff.php',
|
290 |
+
'Squiz_Sniffs_Functions_LowercaseFunctionKeywordsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/LowercaseFunctionKeywordsSniff.php',
|
291 |
+
'Squiz_Sniffs_Functions_MultiLineFunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php',
|
292 |
+
'Squiz_Sniffs_NamingConventions_ValidFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
|
293 |
+
'Squiz_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
294 |
+
'Squiz_Sniffs_Objects_DisallowObjectStringIndexSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/DisallowObjectStringIndexSniff.php',
|
295 |
+
'Squiz_Sniffs_Objects_ObjectInstantiationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectInstantiationSniff.php',
|
296 |
+
'Squiz_Sniffs_Objects_ObjectMemberCommaSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectMemberCommaSniff.php',
|
297 |
+
'Squiz_Sniffs_Operators_ComparisonOperatorUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php',
|
298 |
+
'Squiz_Sniffs_Operators_IncrementDecrementUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/IncrementDecrementUsageSniff.php',
|
299 |
+
'Squiz_Sniffs_Operators_ValidLogicalOperatorsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ValidLogicalOperatorsSniff.php',
|
300 |
+
'Squiz_Sniffs_PHP_CommentedOutCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/CommentedOutCodeSniff.php',
|
301 |
+
'Squiz_Sniffs_PHP_DisallowBooleanStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowBooleanStatementSniff.php',
|
302 |
+
'Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowComparisonAssignmentSniff.php',
|
303 |
+
'Squiz_Sniffs_PHP_DisallowInlineIfSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowInlineIfSniff.php',
|
304 |
+
'Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowMultipleAssignmentsSniff.php',
|
305 |
+
'Squiz_Sniffs_PHP_DisallowObEndFlushSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowObEndFlushSniff.php',
|
306 |
+
'Squiz_Sniffs_PHP_DisallowSizeFunctionsInLoopsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowSizeFunctionsInLoopsSniff.php',
|
307 |
+
'Squiz_Sniffs_PHP_DiscouragedFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DiscouragedFunctionsSniff.php',
|
308 |
+
'Squiz_Sniffs_PHP_EmbeddedPhpSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EmbeddedPhpSniff.php',
|
309 |
+
'Squiz_Sniffs_PHP_EvalSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EvalSniff.php',
|
310 |
+
'Squiz_Sniffs_PHP_ForbiddenFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/ForbiddenFunctionsSniff.php',
|
311 |
+
'Squiz_Sniffs_PHP_GlobalKeywordSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/GlobalKeywordSniff.php',
|
312 |
+
'Squiz_Sniffs_PHP_HeredocSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/HeredocSniff.php',
|
313 |
+
'Squiz_Sniffs_PHP_InnerFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php',
|
314 |
+
'Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/LowercasePHPFunctionsSniff.php',
|
315 |
+
'Squiz_Sniffs_PHP_NonExecutableCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/NonExecutableCodeSniff.php',
|
316 |
+
'Squiz_Sniffs_Scope_MemberVarScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MemberVarScopeSniff.php',
|
317 |
+
'Squiz_Sniffs_Scope_MethodScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MethodScopeSniff.php',
|
318 |
+
'Squiz_Sniffs_Scope_StaticThisUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/StaticThisUsageSniff.php',
|
319 |
+
'Squiz_Sniffs_Strings_ConcatenationSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/ConcatenationSpacingSniff.php',
|
320 |
+
'Squiz_Sniffs_Strings_DoubleQuoteUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/DoubleQuoteUsageSniff.php',
|
321 |
+
'Squiz_Sniffs_Strings_EchoedStringsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/EchoedStringsSniff.php',
|
322 |
+
'Squiz_Sniffs_WhiteSpace_CastSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/CastSpacingSniff.php',
|
323 |
+
'Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php',
|
324 |
+
'Squiz_Sniffs_WhiteSpace_FunctionClosingBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionClosingBraceSpaceSniff.php',
|
325 |
+
'Squiz_Sniffs_WhiteSpace_FunctionOpeningBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionOpeningBraceSpaceSniff.php',
|
326 |
+
'Squiz_Sniffs_WhiteSpace_FunctionSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionSpacingSniff.php',
|
327 |
+
'Squiz_Sniffs_WhiteSpace_LanguageConstructSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LanguageConstructSpacingSniff.php',
|
328 |
+
'Squiz_Sniffs_WhiteSpace_LogicalOperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LogicalOperatorSpacingSniff.php',
|
329 |
+
'Squiz_Sniffs_WhiteSpace_MemberVarSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/MemberVarSpacingSniff.php',
|
330 |
+
'Squiz_Sniffs_WhiteSpace_ObjectOperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ObjectOperatorSpacingSniff.php',
|
331 |
+
'Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php',
|
332 |
+
'Squiz_Sniffs_WhiteSpace_PropertyLabelSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/PropertyLabelSpacingSniff.php',
|
333 |
+
'Squiz_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
|
334 |
+
'Squiz_Sniffs_WhiteSpace_ScopeKeywordSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php',
|
335 |
+
'Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SemicolonSpacingSniff.php',
|
336 |
+
'Squiz_Sniffs_WhiteSpace_SuperfluousWhitespaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SuperfluousWhitespaceSniff.php',
|
337 |
+
'Zend_Sniffs_Debug_CodeAnalyzerSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php',
|
338 |
+
'Zend_Sniffs_Files_ClosingTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Files/ClosingTagSniff.php',
|
339 |
+
'Zend_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
340 |
);
|
vendor/composer/autoload_psr4.php
CHANGED
@@ -7,6 +7,6 @@ $baseDir = dirname($vendorDir);
|
|
7 |
|
8 |
return array(
|
9 |
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
|
10 |
-
'Facebook\\InstantArticles\\' => array($vendorDir . '/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles'),
|
11 |
'Facebook\\' => array($vendorDir . '/facebook/graph-sdk/src/Facebook'),
|
12 |
);
|
7 |
|
8 |
return array(
|
9 |
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
|
10 |
+
'Facebook\\InstantArticles\\' => array($vendorDir . '/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles', $vendorDir . '/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles'),
|
11 |
'Facebook\\' => array($vendorDir . '/facebook/graph-sdk/src/Facebook'),
|
12 |
);
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,15 +19,15 @@ class ComposerAutoloaderInitfa8bfc5d2717dd9298c7d3347cfeea3b
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
-
call_user_func(\Composer\Autoload\
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
@@ -48,19 +48,19 @@ class ComposerAutoloaderInitfa8bfc5d2717dd9298c7d3347cfeea3b
|
|
48 |
$loader->register(true);
|
49 |
|
50 |
if ($useStaticLoader) {
|
51 |
-
$includeFiles = Composer\Autoload\
|
52 |
} else {
|
53 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
54 |
}
|
55 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
56 |
-
|
57 |
}
|
58 |
|
59 |
return $loader;
|
60 |
}
|
61 |
}
|
62 |
|
63 |
-
function
|
64 |
{
|
65 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
66 |
require $file;
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit36fdde57bb31390b63c9fa4f374d8837
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit36fdde57bb31390b63c9fa4f374d8837', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit36fdde57bb31390b63c9fa4f374d8837', 'loadClassLoader'));
|
25 |
|
26 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
|
27 |
if ($useStaticLoader) {
|
28 |
require_once __DIR__ . '/autoload_static.php';
|
29 |
|
30 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit36fdde57bb31390b63c9fa4f374d8837::getInitializer($loader));
|
31 |
} else {
|
32 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
33 |
foreach ($map as $namespace => $path) {
|
48 |
$loader->register(true);
|
49 |
|
50 |
if ($useStaticLoader) {
|
51 |
+
$includeFiles = Composer\Autoload\ComposerStaticInit36fdde57bb31390b63c9fa4f374d8837::$files;
|
52 |
} else {
|
53 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
54 |
}
|
55 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
56 |
+
composerRequire36fdde57bb31390b63c9fa4f374d8837($fileIdentifier, $file);
|
57 |
}
|
58 |
|
59 |
return $loader;
|
60 |
}
|
61 |
}
|
62 |
|
63 |
+
function composerRequire36fdde57bb31390b63c9fa4f374d8837($fileIdentifier, $file)
|
64 |
{
|
65 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
66 |
require $file;
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'c65d09b6820da036953a371c8c73a9b1' => __DIR__ . '/..' . '/facebook/graph-sdk/src/Facebook/polyfills.php',
|
@@ -30,6 +30,7 @@ class ComposerStaticInitfa8bfc5d2717dd9298c7d3347cfeea3b
|
|
30 |
'Facebook\\InstantArticles\\' =>
|
31 |
array (
|
32 |
0 => __DIR__ . '/..' . '/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles',
|
|
|
33 |
),
|
34 |
'Facebook\\' =>
|
35 |
array (
|
@@ -38,6 +39,68 @@ class ComposerStaticInitfa8bfc5d2717dd9298c7d3347cfeea3b
|
|
38 |
);
|
39 |
|
40 |
public static $classMap = array (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
'Logger' => __DIR__ . '/..' . '/apache/log4php/src/main/php/Logger.php',
|
42 |
'LoggerAppender' => __DIR__ . '/..' . '/apache/log4php/src/main/php/LoggerAppender.php',
|
43 |
'LoggerAppenderConsole' => __DIR__ . '/..' . '/apache/log4php/src/main/php/appenders/LoggerAppenderConsole.php',
|
@@ -117,14 +180,204 @@ class ComposerStaticInitfa8bfc5d2717dd9298c7d3347cfeea3b
|
|
117 |
'LoggerRoot' => __DIR__ . '/..' . '/apache/log4php/src/main/php/LoggerRoot.php',
|
118 |
'LoggerThrowableInformation' => __DIR__ . '/..' . '/apache/log4php/src/main/php/LoggerThrowableInformation.php',
|
119 |
'LoggerUtils' => __DIR__ . '/..' . '/apache/log4php/src/main/php/helpers/LoggerUtils.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
);
|
121 |
|
122 |
public static function getInitializer(ClassLoader $loader)
|
123 |
{
|
124 |
return \Closure::bind(function () use ($loader) {
|
125 |
-
$loader->prefixLengthsPsr4 =
|
126 |
-
$loader->prefixDirsPsr4 =
|
127 |
-
$loader->classMap =
|
128 |
|
129 |
}, null, ClassLoader::class);
|
130 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit36fdde57bb31390b63c9fa4f374d8837
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'c65d09b6820da036953a371c8c73a9b1' => __DIR__ . '/..' . '/facebook/graph-sdk/src/Facebook/polyfills.php',
|
30 |
'Facebook\\InstantArticles\\' =>
|
31 |
array (
|
32 |
0 => __DIR__ . '/..' . '/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles',
|
33 |
+
1 => __DIR__ . '/..' . '/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles',
|
34 |
),
|
35 |
'Facebook\\' =>
|
36 |
array (
|
39 |
);
|
40 |
|
41 |
public static $classMap = array (
|
42 |
+
'Generic_Sniffs_Arrays_DisallowLongArraySyntaxSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowLongArraySyntaxSniff.php',
|
43 |
+
'Generic_Sniffs_Arrays_DisallowShortArraySyntaxSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowShortArraySyntaxSniff.php',
|
44 |
+
'Generic_Sniffs_Classes_DuplicateClassNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php',
|
45 |
+
'Generic_Sniffs_Classes_OpeningBraceSameLineSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/OpeningBraceSameLineSniff.php',
|
46 |
+
'Generic_Sniffs_CodeAnalysis_EmptyStatementSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php',
|
47 |
+
'Generic_Sniffs_CodeAnalysis_ForLoopShouldBeWhileLoopSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php',
|
48 |
+
'Generic_Sniffs_CodeAnalysis_ForLoopWithTestFunctionCallSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php',
|
49 |
+
'Generic_Sniffs_CodeAnalysis_JumbledIncrementerSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php',
|
50 |
+
'Generic_Sniffs_CodeAnalysis_UnconditionalIfStatementSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php',
|
51 |
+
'Generic_Sniffs_CodeAnalysis_UnnecessaryFinalModifierSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php',
|
52 |
+
'Generic_Sniffs_CodeAnalysis_UnusedFunctionParameterSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php',
|
53 |
+
'Generic_Sniffs_CodeAnalysis_UselessOverridingMethodSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php',
|
54 |
+
'Generic_Sniffs_Commenting_DocCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php',
|
55 |
+
'Generic_Sniffs_Commenting_FixmeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/FixmeSniff.php',
|
56 |
+
'Generic_Sniffs_Commenting_TodoSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php',
|
57 |
+
'Generic_Sniffs_ControlStructures_InlineControlStructureSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php',
|
58 |
+
'Generic_Sniffs_Debug_CSSLintSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php',
|
59 |
+
'Generic_Sniffs_Debug_ClosureLinterSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php',
|
60 |
+
'Generic_Sniffs_Debug_ESLintSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ESLintSniff.php',
|
61 |
+
'Generic_Sniffs_Debug_JSHintSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php',
|
62 |
+
'Generic_Sniffs_Files_ByteOrderMarkSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/ByteOrderMarkSniff.php',
|
63 |
+
'Generic_Sniffs_Files_EndFileNewlineSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNewlineSniff.php',
|
64 |
+
'Generic_Sniffs_Files_EndFileNoNewlineSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNoNewlineSniff.php',
|
65 |
+
'Generic_Sniffs_Files_InlineHTMLSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/InlineHTMLSniff.php',
|
66 |
+
'Generic_Sniffs_Files_LineEndingsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineEndingsSniff.php',
|
67 |
+
'Generic_Sniffs_Files_LineLengthSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineLengthSniff.php',
|
68 |
+
'Generic_Sniffs_Files_LowercasedFilenameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LowercasedFilenameSniff.php',
|
69 |
+
'Generic_Sniffs_Files_OneClassPerFileSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneClassPerFileSniff.php',
|
70 |
+
'Generic_Sniffs_Files_OneInterfacePerFileSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneInterfacePerFileSniff.php',
|
71 |
+
'Generic_Sniffs_Files_OneTraitPerFileSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneTraitPerFileSniff.php',
|
72 |
+
'Generic_Sniffs_Formatting_DisallowMultipleStatementsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/DisallowMultipleStatementsSniff.php',
|
73 |
+
'Generic_Sniffs_Formatting_MultipleStatementAlignmentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php',
|
74 |
+
'Generic_Sniffs_Formatting_NoSpaceAfterCastSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/NoSpaceAfterCastSniff.php',
|
75 |
+
'Generic_Sniffs_Formatting_SpaceAfterCastSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterCastSniff.php',
|
76 |
+
'Generic_Sniffs_Formatting_SpaceAfterNotSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php',
|
77 |
+
'Generic_Sniffs_Functions_CallTimePassByReferenceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/CallTimePassByReferenceSniff.php',
|
78 |
+
'Generic_Sniffs_Functions_FunctionCallArgumentSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php',
|
79 |
+
'Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php',
|
80 |
+
'Generic_Sniffs_Functions_OpeningFunctionBraceKernighanRitchieSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php',
|
81 |
+
'Generic_Sniffs_Metrics_CyclomaticComplexitySniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php',
|
82 |
+
'Generic_Sniffs_Metrics_NestingLevelSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/NestingLevelSniff.php',
|
83 |
+
'Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php',
|
84 |
+
'Generic_Sniffs_NamingConventions_ConstructorNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/ConstructorNameSniff.php',
|
85 |
+
'Generic_Sniffs_NamingConventions_UpperCaseConstantNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
|
86 |
+
'Generic_Sniffs_PHP_BacktickOperatorSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/BacktickOperatorSniff.php',
|
87 |
+
'Generic_Sniffs_PHP_CharacterBeforePHPOpeningTagSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/CharacterBeforePHPOpeningTagSniff.php',
|
88 |
+
'Generic_Sniffs_PHP_ClosingPHPTagSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ClosingPHPTagSniff.php',
|
89 |
+
'Generic_Sniffs_PHP_DeprecatedFunctionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php',
|
90 |
+
'Generic_Sniffs_PHP_DisallowAlternativePHPTagsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php',
|
91 |
+
'Generic_Sniffs_PHP_DisallowShortOpenTagSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php',
|
92 |
+
'Generic_Sniffs_PHP_ForbiddenFunctionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php',
|
93 |
+
'Generic_Sniffs_PHP_LowerCaseConstantSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseConstantSniff.php',
|
94 |
+
'Generic_Sniffs_PHP_LowerCaseKeywordSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseKeywordSniff.php',
|
95 |
+
'Generic_Sniffs_PHP_NoSilencedErrorsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/NoSilencedErrorsSniff.php',
|
96 |
+
'Generic_Sniffs_PHP_SAPIUsageSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SAPIUsageSniff.php',
|
97 |
+
'Generic_Sniffs_PHP_SyntaxSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php',
|
98 |
+
'Generic_Sniffs_PHP_UpperCaseConstantSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/UpperCaseConstantSniff.php',
|
99 |
+
'Generic_Sniffs_Strings_UnnecessaryStringConcatSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Strings/UnnecessaryStringConcatSniff.php',
|
100 |
+
'Generic_Sniffs_VersionControl_SubversionPropertiesSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/VersionControl/SubversionPropertiesSniff.php',
|
101 |
+
'Generic_Sniffs_WhiteSpace_DisallowSpaceIndentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowSpaceIndentSniff.php',
|
102 |
+
'Generic_Sniffs_WhiteSpace_DisallowTabIndentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
|
103 |
+
'Generic_Sniffs_WhiteSpace_ScopeIndentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/ScopeIndentSniff.php',
|
104 |
'Logger' => __DIR__ . '/..' . '/apache/log4php/src/main/php/Logger.php',
|
105 |
'LoggerAppender' => __DIR__ . '/..' . '/apache/log4php/src/main/php/LoggerAppender.php',
|
106 |
'LoggerAppenderConsole' => __DIR__ . '/..' . '/apache/log4php/src/main/php/appenders/LoggerAppenderConsole.php',
|
180 |
'LoggerRoot' => __DIR__ . '/..' . '/apache/log4php/src/main/php/LoggerRoot.php',
|
181 |
'LoggerThrowableInformation' => __DIR__ . '/..' . '/apache/log4php/src/main/php/LoggerThrowableInformation.php',
|
182 |
'LoggerUtils' => __DIR__ . '/..' . '/apache/log4php/src/main/php/helpers/LoggerUtils.php',
|
183 |
+
'MySource_Sniffs_CSS_BrowserSpecificStylesSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/CSS/BrowserSpecificStylesSniff.php',
|
184 |
+
'MySource_Sniffs_Channels_DisallowSelfActionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/DisallowSelfActionsSniff.php',
|
185 |
+
'MySource_Sniffs_Channels_IncludeOwnSystemSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeOwnSystemSniff.php',
|
186 |
+
'MySource_Sniffs_Channels_IncludeSystemSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeSystemSniff.php',
|
187 |
+
'MySource_Sniffs_Channels_UnusedSystemSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/UnusedSystemSniff.php',
|
188 |
+
'MySource_Sniffs_Commenting_FunctionCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Commenting/FunctionCommentSniff.php',
|
189 |
+
'MySource_Sniffs_Debug_DebugCodeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/DebugCodeSniff.php',
|
190 |
+
'MySource_Sniffs_Debug_FirebugConsoleSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/FirebugConsoleSniff.php',
|
191 |
+
'MySource_Sniffs_Objects_AssignThisSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/AssignThisSniff.php',
|
192 |
+
'MySource_Sniffs_Objects_CreateWidgetTypeCallbackSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/CreateWidgetTypeCallbackSniff.php',
|
193 |
+
'MySource_Sniffs_Objects_DisallowNewWidgetSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/DisallowNewWidgetSniff.php',
|
194 |
+
'MySource_Sniffs_PHP_AjaxNullComparisonSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/AjaxNullComparisonSniff.php',
|
195 |
+
'MySource_Sniffs_PHP_EvalObjectFactorySniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/EvalObjectFactorySniff.php',
|
196 |
+
'MySource_Sniffs_PHP_GetRequestDataSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/GetRequestDataSniff.php',
|
197 |
+
'MySource_Sniffs_PHP_ReturnFunctionValueSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/ReturnFunctionValueSniff.php',
|
198 |
+
'MySource_Sniffs_Strings_JoinStringsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Strings/JoinStringsSniff.php',
|
199 |
+
'PEAR_Sniffs_Classes_ClassDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Classes/ClassDeclarationSniff.php',
|
200 |
+
'PEAR_Sniffs_Commenting_ClassCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/ClassCommentSniff.php',
|
201 |
+
'PEAR_Sniffs_Commenting_FileCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FileCommentSniff.php',
|
202 |
+
'PEAR_Sniffs_Commenting_FunctionCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php',
|
203 |
+
'PEAR_Sniffs_Commenting_InlineCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/InlineCommentSniff.php',
|
204 |
+
'PEAR_Sniffs_ControlStructures_ControlSignatureSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/ControlSignatureSniff.php',
|
205 |
+
'PEAR_Sniffs_ControlStructures_MultiLineConditionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/MultiLineConditionSniff.php',
|
206 |
+
'PEAR_Sniffs_Files_IncludingFileSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Files/IncludingFileSniff.php',
|
207 |
+
'PEAR_Sniffs_Formatting_MultiLineAssignmentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Formatting/MultiLineAssignmentSniff.php',
|
208 |
+
'PEAR_Sniffs_Functions_FunctionCallSignatureSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionCallSignatureSniff.php',
|
209 |
+
'PEAR_Sniffs_Functions_FunctionDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php',
|
210 |
+
'PEAR_Sniffs_Functions_ValidDefaultValueSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/ValidDefaultValueSniff.php',
|
211 |
+
'PEAR_Sniffs_NamingConventions_ValidClassNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidClassNameSniff.php',
|
212 |
+
'PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
|
213 |
+
'PEAR_Sniffs_NamingConventions_ValidVariableNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
214 |
+
'PEAR_Sniffs_WhiteSpace_ObjectOperatorIndentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php',
|
215 |
+
'PEAR_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
|
216 |
+
'PEAR_Sniffs_WhiteSpace_ScopeIndentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeIndentSniff.php',
|
217 |
+
'PHP_CodeSniffer' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer.php',
|
218 |
+
'PHP_CodeSniffer_CLI' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/CLI.php',
|
219 |
+
'PHP_CodeSniffer_DocGenerators_Generator' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php',
|
220 |
+
'PHP_CodeSniffer_DocGenerators_HTML' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php',
|
221 |
+
'PHP_CodeSniffer_DocGenerators_Markdown' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php',
|
222 |
+
'PHP_CodeSniffer_DocGenerators_Text' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php',
|
223 |
+
'PHP_CodeSniffer_Exception' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Exception.php',
|
224 |
+
'PHP_CodeSniffer_File' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/File.php',
|
225 |
+
'PHP_CodeSniffer_Fixer' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Fixer.php',
|
226 |
+
'PHP_CodeSniffer_Report' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Report.php',
|
227 |
+
'PHP_CodeSniffer_Reporting' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reporting.php',
|
228 |
+
'PHP_CodeSniffer_Reports_Cbf' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Cbf.php',
|
229 |
+
'PHP_CodeSniffer_Reports_Checkstyle' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Checkstyle.php',
|
230 |
+
'PHP_CodeSniffer_Reports_Csv' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Csv.php',
|
231 |
+
'PHP_CodeSniffer_Reports_Diff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Diff.php',
|
232 |
+
'PHP_CodeSniffer_Reports_Emacs' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Emacs.php',
|
233 |
+
'PHP_CodeSniffer_Reports_Full' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Full.php',
|
234 |
+
'PHP_CodeSniffer_Reports_Gitblame' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Gitblame.php',
|
235 |
+
'PHP_CodeSniffer_Reports_Hgblame' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Hgblame.php',
|
236 |
+
'PHP_CodeSniffer_Reports_Info' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Info.php',
|
237 |
+
'PHP_CodeSniffer_Reports_Json' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Json.php',
|
238 |
+
'PHP_CodeSniffer_Reports_Junit' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Junit.php',
|
239 |
+
'PHP_CodeSniffer_Reports_Notifysend' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Notifysend.php',
|
240 |
+
'PHP_CodeSniffer_Reports_Source' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Source.php',
|
241 |
+
'PHP_CodeSniffer_Reports_Summary' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Summary.php',
|
242 |
+
'PHP_CodeSniffer_Reports_Svnblame' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Svnblame.php',
|
243 |
+
'PHP_CodeSniffer_Reports_VersionControl' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/VersionControl.php',
|
244 |
+
'PHP_CodeSniffer_Reports_Xml' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Xml.php',
|
245 |
+
'PHP_CodeSniffer_Sniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Sniff.php',
|
246 |
+
'PHP_CodeSniffer_Standards_AbstractPatternSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractPatternSniff.php',
|
247 |
+
'PHP_CodeSniffer_Standards_AbstractScopeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractScopeSniff.php',
|
248 |
+
'PHP_CodeSniffer_Standards_AbstractVariableSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractVariableSniff.php',
|
249 |
+
'PHP_CodeSniffer_Standards_IncorrectPatternException' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/IncorrectPatternException.php',
|
250 |
+
'PHP_CodeSniffer_Tokenizers_CSS' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/CSS.php',
|
251 |
+
'PHP_CodeSniffer_Tokenizers_Comment' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/Comment.php',
|
252 |
+
'PHP_CodeSniffer_Tokenizers_JS' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/JS.php',
|
253 |
+
'PHP_CodeSniffer_Tokenizers_PHP' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/PHP.php',
|
254 |
+
'PHP_CodeSniffer_Tokens' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Tokens.php',
|
255 |
+
'PSR1_Sniffs_Classes_ClassDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Classes/ClassDeclarationSniff.php',
|
256 |
+
'PSR1_Sniffs_Files_SideEffectsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Files/SideEffectsSniff.php',
|
257 |
+
'PSR1_Sniffs_Methods_CamelCapsMethodNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Methods/CamelCapsMethodNameSniff.php',
|
258 |
+
'PSR2_Sniffs_Classes_ClassDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/ClassDeclarationSniff.php',
|
259 |
+
'PSR2_Sniffs_Classes_PropertyDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php',
|
260 |
+
'PSR2_Sniffs_ControlStructures_ControlStructureSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ControlStructureSpacingSniff.php',
|
261 |
+
'PSR2_Sniffs_ControlStructures_ElseIfDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
|
262 |
+
'PSR2_Sniffs_ControlStructures_SwitchDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
|
263 |
+
'PSR2_Sniffs_Files_ClosingTagSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/ClosingTagSniff.php',
|
264 |
+
'PSR2_Sniffs_Files_EndFileNewlineSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/EndFileNewlineSniff.php',
|
265 |
+
'PSR2_Sniffs_Methods_FunctionCallSignatureSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionCallSignatureSniff.php',
|
266 |
+
'PSR2_Sniffs_Methods_FunctionClosingBraceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionClosingBraceSniff.php',
|
267 |
+
'PSR2_Sniffs_Methods_MethodDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/MethodDeclarationSniff.php',
|
268 |
+
'PSR2_Sniffs_Namespaces_NamespaceDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/NamespaceDeclarationSniff.php',
|
269 |
+
'PSR2_Sniffs_Namespaces_UseDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/UseDeclarationSniff.php',
|
270 |
+
'Squiz_Sniffs_Arrays_ArrayBracketSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayBracketSpacingSniff.php',
|
271 |
+
'Squiz_Sniffs_Arrays_ArrayDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php',
|
272 |
+
'Squiz_Sniffs_CSS_ClassDefinitionClosingBraceSpaceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionClosingBraceSpaceSniff.php',
|
273 |
+
'Squiz_Sniffs_CSS_ClassDefinitionNameSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionNameSpacingSniff.php',
|
274 |
+
'Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionOpeningBraceSpaceSniff.php',
|
275 |
+
'Squiz_Sniffs_CSS_ColonSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColonSpacingSniff.php',
|
276 |
+
'Squiz_Sniffs_CSS_ColourDefinitionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColourDefinitionSniff.php',
|
277 |
+
'Squiz_Sniffs_CSS_DisallowMultipleStyleDefinitionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DisallowMultipleStyleDefinitionsSniff.php',
|
278 |
+
'Squiz_Sniffs_CSS_DuplicateClassDefinitionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateClassDefinitionSniff.php',
|
279 |
+
'Squiz_Sniffs_CSS_DuplicateStyleDefinitionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateStyleDefinitionSniff.php',
|
280 |
+
'Squiz_Sniffs_CSS_EmptyClassDefinitionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyClassDefinitionSniff.php',
|
281 |
+
'Squiz_Sniffs_CSS_EmptyStyleDefinitionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyStyleDefinitionSniff.php',
|
282 |
+
'Squiz_Sniffs_CSS_ForbiddenStylesSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ForbiddenStylesSniff.php',
|
283 |
+
'Squiz_Sniffs_CSS_IndentationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/IndentationSniff.php',
|
284 |
+
'Squiz_Sniffs_CSS_LowercaseStyleDefinitionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/LowercaseStyleDefinitionSniff.php',
|
285 |
+
'Squiz_Sniffs_CSS_MissingColonSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/MissingColonSniff.php',
|
286 |
+
'Squiz_Sniffs_CSS_NamedColoursSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/NamedColoursSniff.php',
|
287 |
+
'Squiz_Sniffs_CSS_OpacitySniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/OpacitySniff.php',
|
288 |
+
'Squiz_Sniffs_CSS_SemicolonSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/SemicolonSpacingSniff.php',
|
289 |
+
'Squiz_Sniffs_CSS_ShorthandSizeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ShorthandSizeSniff.php',
|
290 |
+
'Squiz_Sniffs_Classes_ClassDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassDeclarationSniff.php',
|
291 |
+
'Squiz_Sniffs_Classes_ClassFileNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassFileNameSniff.php',
|
292 |
+
'Squiz_Sniffs_Classes_DuplicatePropertySniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/DuplicatePropertySniff.php',
|
293 |
+
'Squiz_Sniffs_Classes_LowercaseClassKeywordsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/LowercaseClassKeywordsSniff.php',
|
294 |
+
'Squiz_Sniffs_Classes_SelfMemberReferenceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php',
|
295 |
+
'Squiz_Sniffs_Classes_ValidClassNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ValidClassNameSniff.php',
|
296 |
+
'Squiz_Sniffs_Commenting_BlockCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/BlockCommentSniff.php',
|
297 |
+
'Squiz_Sniffs_Commenting_ClassCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClassCommentSniff.php',
|
298 |
+
'Squiz_Sniffs_Commenting_ClosingDeclarationCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClosingDeclarationCommentSniff.php',
|
299 |
+
'Squiz_Sniffs_Commenting_DocCommentAlignmentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/DocCommentAlignmentSniff.php',
|
300 |
+
'Squiz_Sniffs_Commenting_EmptyCatchCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/EmptyCatchCommentSniff.php',
|
301 |
+
'Squiz_Sniffs_Commenting_FileCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FileCommentSniff.php',
|
302 |
+
'Squiz_Sniffs_Commenting_FunctionCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php',
|
303 |
+
'Squiz_Sniffs_Commenting_FunctionCommentThrowTagSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentThrowTagSniff.php',
|
304 |
+
'Squiz_Sniffs_Commenting_InlineCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/InlineCommentSniff.php',
|
305 |
+
'Squiz_Sniffs_Commenting_LongConditionClosingCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/LongConditionClosingCommentSniff.php',
|
306 |
+
'Squiz_Sniffs_Commenting_PostStatementCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/PostStatementCommentSniff.php',
|
307 |
+
'Squiz_Sniffs_Commenting_VariableCommentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/VariableCommentSniff.php',
|
308 |
+
'Squiz_Sniffs_ControlStructures_ControlSignatureSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ControlSignatureSniff.php',
|
309 |
+
'Squiz_Sniffs_ControlStructures_ElseIfDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
|
310 |
+
'Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php',
|
311 |
+
'Squiz_Sniffs_ControlStructures_ForLoopDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForLoopDeclarationSniff.php',
|
312 |
+
'Squiz_Sniffs_ControlStructures_InlineIfDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/InlineIfDeclarationSniff.php',
|
313 |
+
'Squiz_Sniffs_ControlStructures_LowercaseDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/LowercaseDeclarationSniff.php',
|
314 |
+
'Squiz_Sniffs_ControlStructures_SwitchDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
|
315 |
+
'Squiz_Sniffs_Debug_JSLintSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php',
|
316 |
+
'Squiz_Sniffs_Debug_JavaScriptLintSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php',
|
317 |
+
'Squiz_Sniffs_Files_FileExtensionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Files/FileExtensionSniff.php',
|
318 |
+
'Squiz_Sniffs_Formatting_OperatorBracketSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Formatting/OperatorBracketSniff.php',
|
319 |
+
'Squiz_Sniffs_Functions_FunctionDeclarationArgumentSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationArgumentSpacingSniff.php',
|
320 |
+
'Squiz_Sniffs_Functions_FunctionDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationSniff.php',
|
321 |
+
'Squiz_Sniffs_Functions_FunctionDuplicateArgumentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDuplicateArgumentSniff.php',
|
322 |
+
'Squiz_Sniffs_Functions_GlobalFunctionSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/GlobalFunctionSniff.php',
|
323 |
+
'Squiz_Sniffs_Functions_LowercaseFunctionKeywordsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/LowercaseFunctionKeywordsSniff.php',
|
324 |
+
'Squiz_Sniffs_Functions_MultiLineFunctionDeclarationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php',
|
325 |
+
'Squiz_Sniffs_NamingConventions_ValidFunctionNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
|
326 |
+
'Squiz_Sniffs_NamingConventions_ValidVariableNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
327 |
+
'Squiz_Sniffs_Objects_DisallowObjectStringIndexSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/DisallowObjectStringIndexSniff.php',
|
328 |
+
'Squiz_Sniffs_Objects_ObjectInstantiationSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectInstantiationSniff.php',
|
329 |
+
'Squiz_Sniffs_Objects_ObjectMemberCommaSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectMemberCommaSniff.php',
|
330 |
+
'Squiz_Sniffs_Operators_ComparisonOperatorUsageSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php',
|
331 |
+
'Squiz_Sniffs_Operators_IncrementDecrementUsageSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/IncrementDecrementUsageSniff.php',
|
332 |
+
'Squiz_Sniffs_Operators_ValidLogicalOperatorsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ValidLogicalOperatorsSniff.php',
|
333 |
+
'Squiz_Sniffs_PHP_CommentedOutCodeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/CommentedOutCodeSniff.php',
|
334 |
+
'Squiz_Sniffs_PHP_DisallowBooleanStatementSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowBooleanStatementSniff.php',
|
335 |
+
'Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowComparisonAssignmentSniff.php',
|
336 |
+
'Squiz_Sniffs_PHP_DisallowInlineIfSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowInlineIfSniff.php',
|
337 |
+
'Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowMultipleAssignmentsSniff.php',
|
338 |
+
'Squiz_Sniffs_PHP_DisallowObEndFlushSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowObEndFlushSniff.php',
|
339 |
+
'Squiz_Sniffs_PHP_DisallowSizeFunctionsInLoopsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowSizeFunctionsInLoopsSniff.php',
|
340 |
+
'Squiz_Sniffs_PHP_DiscouragedFunctionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DiscouragedFunctionsSniff.php',
|
341 |
+
'Squiz_Sniffs_PHP_EmbeddedPhpSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EmbeddedPhpSniff.php',
|
342 |
+
'Squiz_Sniffs_PHP_EvalSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EvalSniff.php',
|
343 |
+
'Squiz_Sniffs_PHP_ForbiddenFunctionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/ForbiddenFunctionsSniff.php',
|
344 |
+
'Squiz_Sniffs_PHP_GlobalKeywordSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/GlobalKeywordSniff.php',
|
345 |
+
'Squiz_Sniffs_PHP_HeredocSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/HeredocSniff.php',
|
346 |
+
'Squiz_Sniffs_PHP_InnerFunctionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php',
|
347 |
+
'Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/LowercasePHPFunctionsSniff.php',
|
348 |
+
'Squiz_Sniffs_PHP_NonExecutableCodeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/NonExecutableCodeSniff.php',
|
349 |
+
'Squiz_Sniffs_Scope_MemberVarScopeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MemberVarScopeSniff.php',
|
350 |
+
'Squiz_Sniffs_Scope_MethodScopeSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MethodScopeSniff.php',
|
351 |
+
'Squiz_Sniffs_Scope_StaticThisUsageSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/StaticThisUsageSniff.php',
|
352 |
+
'Squiz_Sniffs_Strings_ConcatenationSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/ConcatenationSpacingSniff.php',
|
353 |
+
'Squiz_Sniffs_Strings_DoubleQuoteUsageSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/DoubleQuoteUsageSniff.php',
|
354 |
+
'Squiz_Sniffs_Strings_EchoedStringsSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/EchoedStringsSniff.php',
|
355 |
+
'Squiz_Sniffs_WhiteSpace_CastSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/CastSpacingSniff.php',
|
356 |
+
'Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php',
|
357 |
+
'Squiz_Sniffs_WhiteSpace_FunctionClosingBraceSpaceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionClosingBraceSpaceSniff.php',
|
358 |
+
'Squiz_Sniffs_WhiteSpace_FunctionOpeningBraceSpaceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionOpeningBraceSpaceSniff.php',
|
359 |
+
'Squiz_Sniffs_WhiteSpace_FunctionSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionSpacingSniff.php',
|
360 |
+
'Squiz_Sniffs_WhiteSpace_LanguageConstructSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LanguageConstructSpacingSniff.php',
|
361 |
+
'Squiz_Sniffs_WhiteSpace_LogicalOperatorSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LogicalOperatorSpacingSniff.php',
|
362 |
+
'Squiz_Sniffs_WhiteSpace_MemberVarSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/MemberVarSpacingSniff.php',
|
363 |
+
'Squiz_Sniffs_WhiteSpace_ObjectOperatorSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ObjectOperatorSpacingSniff.php',
|
364 |
+
'Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php',
|
365 |
+
'Squiz_Sniffs_WhiteSpace_PropertyLabelSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/PropertyLabelSpacingSniff.php',
|
366 |
+
'Squiz_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
|
367 |
+
'Squiz_Sniffs_WhiteSpace_ScopeKeywordSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php',
|
368 |
+
'Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SemicolonSpacingSniff.php',
|
369 |
+
'Squiz_Sniffs_WhiteSpace_SuperfluousWhitespaceSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SuperfluousWhitespaceSniff.php',
|
370 |
+
'Zend_Sniffs_Debug_CodeAnalyzerSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php',
|
371 |
+
'Zend_Sniffs_Files_ClosingTagSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Files/ClosingTagSniff.php',
|
372 |
+
'Zend_Sniffs_NamingConventions_ValidVariableNameSniff' => __DIR__ . '/..' . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/NamingConventions/ValidVariableNameSniff.php',
|
373 |
);
|
374 |
|
375 |
public static function getInitializer(ClassLoader $loader)
|
376 |
{
|
377 |
return \Closure::bind(function () use ($loader) {
|
378 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit36fdde57bb31390b63c9fa4f374d8837::$prefixLengthsPsr4;
|
379 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit36fdde57bb31390b63c9fa4f374d8837::$prefixDirsPsr4;
|
380 |
+
$loader->classMap = ComposerStaticInit36fdde57bb31390b63c9fa4f374d8837::$classMap;
|
381 |
|
382 |
}, null, ClassLoader::class);
|
383 |
}
|
vendor/composer/installed.json
CHANGED
@@ -1,4 +1,64 @@
|
|
1 |
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
{
|
3 |
"name": "apache/log4php",
|
4 |
"version": "2.3.0",
|
@@ -6,7 +66,7 @@
|
|
6 |
"source": {
|
7 |
"type": "git",
|
8 |
"url": "https://git-wip-us.apache.org/repos/asf/logging-log4php.git",
|
9 |
-
"reference": "
|
10 |
},
|
11 |
"require": {
|
12 |
"php": ">=5.2.7"
|
@@ -32,88 +92,146 @@
|
|
32 |
]
|
33 |
},
|
34 |
{
|
35 |
-
"name": "
|
36 |
-
"version": "
|
37 |
-
"version_normalized": "
|
38 |
"source": {
|
39 |
"type": "git",
|
40 |
-
"url": "https://github.com/
|
41 |
-
"reference": "
|
42 |
},
|
43 |
"dist": {
|
44 |
"type": "zip",
|
45 |
-
"url": "https://api.github.com/repos/
|
46 |
-
"reference": "
|
47 |
"shasum": ""
|
48 |
},
|
49 |
"require": {
|
50 |
-
"
|
|
|
|
|
|
|
51 |
},
|
52 |
"require-dev": {
|
53 |
-
"guzzlehttp/guzzle": "~5.0",
|
54 |
-
"mockery/mockery": "~0.8",
|
55 |
"phpunit/phpunit": "~4.0"
|
56 |
},
|
57 |
-
"
|
58 |
-
|
59 |
-
"
|
60 |
-
|
61 |
-
|
62 |
"type": "library",
|
63 |
"extra": {
|
64 |
"branch-alias": {
|
65 |
-
"dev-master": "
|
66 |
}
|
67 |
},
|
68 |
"installation-source": "dist",
|
69 |
"autoload": {
|
70 |
-
"
|
71 |
-
"
|
72 |
-
|
73 |
-
|
74 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
]
|
76 |
},
|
77 |
"notification-url": "https://packagist.org/downloads/",
|
78 |
"license": [
|
79 |
-
"
|
80 |
],
|
81 |
"authors": [
|
82 |
{
|
83 |
-
"name": "
|
84 |
-
"
|
85 |
}
|
86 |
],
|
87 |
-
"description": "
|
88 |
-
"homepage": "
|
89 |
"keywords": [
|
90 |
-
"
|
91 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
]
|
93 |
},
|
94 |
{
|
95 |
"name": "symfony/css-selector",
|
96 |
-
"version": "
|
97 |
-
"version_normalized": "
|
98 |
"source": {
|
99 |
"type": "git",
|
100 |
"url": "https://github.com/symfony/css-selector.git",
|
101 |
-
"reference": "
|
102 |
},
|
103 |
"dist": {
|
104 |
"type": "zip",
|
105 |
-
"url": "https://api.github.com/repos/symfony/css-selector/zipball/
|
106 |
-
"reference": "
|
107 |
"shasum": ""
|
108 |
},
|
109 |
"require": {
|
110 |
-
"php": ">=5.
|
111 |
},
|
112 |
-
"time": "2017-05-01 14:55
|
113 |
"type": "library",
|
114 |
"extra": {
|
115 |
"branch-alias": {
|
116 |
-
"dev-master": "
|
117 |
}
|
118 |
},
|
119 |
"installation-source": "dist",
|
@@ -148,17 +266,17 @@
|
|
148 |
},
|
149 |
{
|
150 |
"name": "facebook/facebook-instant-articles-sdk-php",
|
151 |
-
"version": "v1.
|
152 |
-
"version_normalized": "1.
|
153 |
"source": {
|
154 |
"type": "git",
|
155 |
"url": "https://github.com/facebook/facebook-instant-articles-sdk-php.git",
|
156 |
-
"reference": "
|
157 |
},
|
158 |
"dist": {
|
159 |
"type": "zip",
|
160 |
-
"url": "https://api.github.com/repos/facebook/facebook-instant-articles-sdk-php/zipball/
|
161 |
-
"reference": "
|
162 |
"shasum": ""
|
163 |
},
|
164 |
"require": {
|
@@ -172,7 +290,7 @@
|
|
172 |
"phpunit/phpunit": "^4.8",
|
173 |
"squizlabs/php_codesniffer": "^2.6.0"
|
174 |
},
|
175 |
-
"time": "2017-
|
176 |
"type": "library",
|
177 |
"installation-source": "dist",
|
178 |
"autoload": {
|
@@ -198,5 +316,57 @@
|
|
198 |
"instant",
|
199 |
"sdk"
|
200 |
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
}
|
202 |
]
|
1 |
[
|
2 |
+
{
|
3 |
+
"name": "facebook/graph-sdk",
|
4 |
+
"version": "5.5.0",
|
5 |
+
"version_normalized": "5.5.0.0",
|
6 |
+
"source": {
|
7 |
+
"type": "git",
|
8 |
+
"url": "https://github.com/facebook/php-graph-sdk.git",
|
9 |
+
"reference": "93d7dc87e55a541d2e27d38f3aed40abbffdf6e1"
|
10 |
+
},
|
11 |
+
"dist": {
|
12 |
+
"type": "zip",
|
13 |
+
"url": "https://api.github.com/repos/facebook/php-graph-sdk/zipball/93d7dc87e55a541d2e27d38f3aed40abbffdf6e1",
|
14 |
+
"reference": "93d7dc87e55a541d2e27d38f3aed40abbffdf6e1",
|
15 |
+
"shasum": ""
|
16 |
+
},
|
17 |
+
"require": {
|
18 |
+
"php": "^5.4|^7.0"
|
19 |
+
},
|
20 |
+
"require-dev": {
|
21 |
+
"guzzlehttp/guzzle": "~5.0",
|
22 |
+
"mockery/mockery": "~0.8",
|
23 |
+
"phpunit/phpunit": "~4.0"
|
24 |
+
},
|
25 |
+
"suggest": {
|
26 |
+
"guzzlehttp/guzzle": "Allows for implementation of the Guzzle HTTP client",
|
27 |
+
"paragonie/random_compat": "Provides a better CSPRNG option in PHP 5"
|
28 |
+
},
|
29 |
+
"time": "2017-04-20 14:15:02",
|
30 |
+
"type": "library",
|
31 |
+
"extra": {
|
32 |
+
"branch-alias": {
|
33 |
+
"dev-master": "5.x-dev"
|
34 |
+
}
|
35 |
+
},
|
36 |
+
"installation-source": "dist",
|
37 |
+
"autoload": {
|
38 |
+
"psr-4": {
|
39 |
+
"Facebook\\": "src/Facebook/"
|
40 |
+
},
|
41 |
+
"files": [
|
42 |
+
"src/Facebook/polyfills.php"
|
43 |
+
]
|
44 |
+
},
|
45 |
+
"notification-url": "https://packagist.org/downloads/",
|
46 |
+
"license": [
|
47 |
+
"Facebook Platform"
|
48 |
+
],
|
49 |
+
"authors": [
|
50 |
+
{
|
51 |
+
"name": "Facebook",
|
52 |
+
"homepage": "https://github.com/facebook/php-graph-sdk/contributors"
|
53 |
+
}
|
54 |
+
],
|
55 |
+
"description": "Facebook SDK for PHP",
|
56 |
+
"homepage": "https://github.com/facebook/php-graph-sdk",
|
57 |
+
"keywords": [
|
58 |
+
"facebook",
|
59 |
+
"sdk"
|
60 |
+
]
|
61 |
+
},
|
62 |
{
|
63 |
"name": "apache/log4php",
|
64 |
"version": "2.3.0",
|
66 |
"source": {
|
67 |
"type": "git",
|
68 |
"url": "https://git-wip-us.apache.org/repos/asf/logging-log4php.git",
|
69 |
+
"reference": "cac428b6f67d2035af39784da1d1a299ef42fcf2"
|
70 |
},
|
71 |
"require": {
|
72 |
"php": ">=5.2.7"
|
92 |
]
|
93 |
},
|
94 |
{
|
95 |
+
"name": "squizlabs/php_codesniffer",
|
96 |
+
"version": "2.9.1",
|
97 |
+
"version_normalized": "2.9.1.0",
|
98 |
"source": {
|
99 |
"type": "git",
|
100 |
+
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
101 |
+
"reference": "dcbed1074f8244661eecddfc2a675430d8d33f62"
|
102 |
},
|
103 |
"dist": {
|
104 |
"type": "zip",
|
105 |
+
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dcbed1074f8244661eecddfc2a675430d8d33f62",
|
106 |
+
"reference": "dcbed1074f8244661eecddfc2a675430d8d33f62",
|
107 |
"shasum": ""
|
108 |
},
|
109 |
"require": {
|
110 |
+
"ext-simplexml": "*",
|
111 |
+
"ext-tokenizer": "*",
|
112 |
+
"ext-xmlwriter": "*",
|
113 |
+
"php": ">=5.1.2"
|
114 |
},
|
115 |
"require-dev": {
|
|
|
|
|
116 |
"phpunit/phpunit": "~4.0"
|
117 |
},
|
118 |
+
"time": "2017-05-22 02:43:20",
|
119 |
+
"bin": [
|
120 |
+
"scripts/phpcs",
|
121 |
+
"scripts/phpcbf"
|
122 |
+
],
|
123 |
"type": "library",
|
124 |
"extra": {
|
125 |
"branch-alias": {
|
126 |
+
"dev-master": "2.x-dev"
|
127 |
}
|
128 |
},
|
129 |
"installation-source": "dist",
|
130 |
"autoload": {
|
131 |
+
"classmap": [
|
132 |
+
"CodeSniffer.php",
|
133 |
+
"CodeSniffer/CLI.php",
|
134 |
+
"CodeSniffer/Exception.php",
|
135 |
+
"CodeSniffer/File.php",
|
136 |
+
"CodeSniffer/Fixer.php",
|
137 |
+
"CodeSniffer/Report.php",
|
138 |
+
"CodeSniffer/Reporting.php",
|
139 |
+
"CodeSniffer/Sniff.php",
|
140 |
+
"CodeSniffer/Tokens.php",
|
141 |
+
"CodeSniffer/Reports/",
|
142 |
+
"CodeSniffer/Tokenizers/",
|
143 |
+
"CodeSniffer/DocGenerators/",
|
144 |
+
"CodeSniffer/Standards/AbstractPatternSniff.php",
|
145 |
+
"CodeSniffer/Standards/AbstractScopeSniff.php",
|
146 |
+
"CodeSniffer/Standards/AbstractVariableSniff.php",
|
147 |
+
"CodeSniffer/Standards/IncorrectPatternException.php",
|
148 |
+
"CodeSniffer/Standards/Generic/Sniffs/",
|
149 |
+
"CodeSniffer/Standards/MySource/Sniffs/",
|
150 |
+
"CodeSniffer/Standards/PEAR/Sniffs/",
|
151 |
+
"CodeSniffer/Standards/PSR1/Sniffs/",
|
152 |
+
"CodeSniffer/Standards/PSR2/Sniffs/",
|
153 |
+
"CodeSniffer/Standards/Squiz/Sniffs/",
|
154 |
+
"CodeSniffer/Standards/Zend/Sniffs/"
|
155 |
]
|
156 |
},
|
157 |
"notification-url": "https://packagist.org/downloads/",
|
158 |
"license": [
|
159 |
+
"BSD-3-Clause"
|
160 |
],
|
161 |
"authors": [
|
162 |
{
|
163 |
+
"name": "Greg Sherwood",
|
164 |
+
"role": "lead"
|
165 |
}
|
166 |
],
|
167 |
+
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
168 |
+
"homepage": "http://www.squizlabs.com/php-codesniffer",
|
169 |
"keywords": [
|
170 |
+
"phpcs",
|
171 |
+
"standards"
|
172 |
+
]
|
173 |
+
},
|
174 |
+
{
|
175 |
+
"name": "wp-coding-standards/wpcs",
|
176 |
+
"version": "0.11.0",
|
177 |
+
"version_normalized": "0.11.0.0",
|
178 |
+
"source": {
|
179 |
+
"type": "git",
|
180 |
+
"url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git",
|
181 |
+
"reference": "407e4b85f547a5251185f89ceae6599917343388"
|
182 |
+
},
|
183 |
+
"dist": {
|
184 |
+
"type": "zip",
|
185 |
+
"url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/407e4b85f547a5251185f89ceae6599917343388",
|
186 |
+
"reference": "407e4b85f547a5251185f89ceae6599917343388",
|
187 |
+
"shasum": ""
|
188 |
+
},
|
189 |
+
"require": {
|
190 |
+
"squizlabs/php_codesniffer": "^2.8.1"
|
191 |
+
},
|
192 |
+
"time": "2017-03-20 23:17:58",
|
193 |
+
"type": "library",
|
194 |
+
"installation-source": "dist",
|
195 |
+
"notification-url": "https://packagist.org/downloads/",
|
196 |
+
"license": [
|
197 |
+
"MIT"
|
198 |
+
],
|
199 |
+
"authors": [
|
200 |
+
{
|
201 |
+
"name": "Contributors",
|
202 |
+
"homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
|
203 |
+
}
|
204 |
+
],
|
205 |
+
"description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
|
206 |
+
"keywords": [
|
207 |
+
"phpcs",
|
208 |
+
"standards",
|
209 |
+
"wordpress"
|
210 |
]
|
211 |
},
|
212 |
{
|
213 |
"name": "symfony/css-selector",
|
214 |
+
"version": "v2.8.22",
|
215 |
+
"version_normalized": "2.8.22.0",
|
216 |
"source": {
|
217 |
"type": "git",
|
218 |
"url": "https://github.com/symfony/css-selector.git",
|
219 |
+
"reference": "ba3204654efa779691fac9e948a96b4a7067e4ab"
|
220 |
},
|
221 |
"dist": {
|
222 |
"type": "zip",
|
223 |
+
"url": "https://api.github.com/repos/symfony/css-selector/zipball/ba3204654efa779691fac9e948a96b4a7067e4ab",
|
224 |
+
"reference": "ba3204654efa779691fac9e948a96b4a7067e4ab",
|
225 |
"shasum": ""
|
226 |
},
|
227 |
"require": {
|
228 |
+
"php": ">=5.3.9"
|
229 |
},
|
230 |
+
"time": "2017-05-01 14:31:55",
|
231 |
"type": "library",
|
232 |
"extra": {
|
233 |
"branch-alias": {
|
234 |
+
"dev-master": "2.8-dev"
|
235 |
}
|
236 |
},
|
237 |
"installation-source": "dist",
|
266 |
},
|
267 |
{
|
268 |
"name": "facebook/facebook-instant-articles-sdk-php",
|
269 |
+
"version": "v1.6.1",
|
270 |
+
"version_normalized": "1.6.1.0",
|
271 |
"source": {
|
272 |
"type": "git",
|
273 |
"url": "https://github.com/facebook/facebook-instant-articles-sdk-php.git",
|
274 |
+
"reference": "511d15d741796c7da68742e565d98f97464d2d6b"
|
275 |
},
|
276 |
"dist": {
|
277 |
"type": "zip",
|
278 |
+
"url": "https://api.github.com/repos/facebook/facebook-instant-articles-sdk-php/zipball/511d15d741796c7da68742e565d98f97464d2d6b",
|
279 |
+
"reference": "511d15d741796c7da68742e565d98f97464d2d6b",
|
280 |
"shasum": ""
|
281 |
},
|
282 |
"require": {
|
290 |
"phpunit/phpunit": "^4.8",
|
291 |
"squizlabs/php_codesniffer": "^2.6.0"
|
292 |
},
|
293 |
+
"time": "2017-06-20 13:45:09",
|
294 |
"type": "library",
|
295 |
"installation-source": "dist",
|
296 |
"autoload": {
|
316 |
"instant",
|
317 |
"sdk"
|
318 |
]
|
319 |
+
},
|
320 |
+
{
|
321 |
+
"name": "facebook/facebook-instant-articles-sdk-extensions-in-php",
|
322 |
+
"version": "v0.1.1",
|
323 |
+
"version_normalized": "0.1.1.0",
|
324 |
+
"source": {
|
325 |
+
"type": "git",
|
326 |
+
"url": "https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php.git",
|
327 |
+
"reference": "f574ad6230ced8d8159b7b59a41ac6238d8d6353"
|
328 |
+
},
|
329 |
+
"dist": {
|
330 |
+
"type": "zip",
|
331 |
+
"url": "https://api.github.com/repos/facebook/facebook-instant-articles-sdk-extensions-in-php/zipball/f574ad6230ced8d8159b7b59a41ac6238d8d6353",
|
332 |
+
"reference": "f574ad6230ced8d8159b7b59a41ac6238d8d6353",
|
333 |
+
"shasum": ""
|
334 |
+
},
|
335 |
+
"require": {
|
336 |
+
"facebook/facebook-instant-articles-sdk-php": "^1.6",
|
337 |
+
"php": "^5.4 || ^7.0"
|
338 |
+
},
|
339 |
+
"require-dev": {
|
340 |
+
"phpunit/phpunit": "^4.8"
|
341 |
+
},
|
342 |
+
"time": "2017-06-26 19:59:19",
|
343 |
+
"type": "library",
|
344 |
+
"installation-source": "dist",
|
345 |
+
"autoload": {
|
346 |
+
"psr-4": {
|
347 |
+
"Facebook\\InstantArticles\\": "src/Facebook/InstantArticles/"
|
348 |
+
}
|
349 |
+
},
|
350 |
+
"notification-url": "https://packagist.org/downloads/",
|
351 |
+
"license": [
|
352 |
+
"proprietary"
|
353 |
+
],
|
354 |
+
"authors": [
|
355 |
+
{
|
356 |
+
"name": "Facebook",
|
357 |
+
"homepage": "https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/contributors"
|
358 |
+
}
|
359 |
+
],
|
360 |
+
"description": "Facebook Instant Articles SDK Extensions in PHP to transform Instant Articles markup file into AMP",
|
361 |
+
"homepage": "https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php",
|
362 |
+
"keywords": [
|
363 |
+
"amp",
|
364 |
+
"articles",
|
365 |
+
"extensions",
|
366 |
+
"facebook",
|
367 |
+
"instant",
|
368 |
+
"instantarticles",
|
369 |
+
"sdk"
|
370 |
+
]
|
371 |
}
|
372 |
]
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/.gitignore
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
composer.phar
|
2 |
+
/vendor/
|
3 |
+
*.ignored
|
4 |
+
**/IgnoredTest.php
|
5 |
+
.DS_Store
|
6 |
+
.vscode
|
7 |
+
**/ignored-*
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/.travis.yml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
language: php
|
2 |
+
|
3 |
+
php:
|
4 |
+
- '5.5'
|
5 |
+
- '5.6'
|
6 |
+
- '7.0'
|
7 |
+
- '7.1'
|
8 |
+
- hhvm
|
9 |
+
|
10 |
+
dist: trusty
|
11 |
+
sudo: false
|
12 |
+
|
13 |
+
cache:
|
14 |
+
directories:
|
15 |
+
- $HOME/.composer/cache
|
16 |
+
|
17 |
+
before_install:
|
18 |
+
- if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi
|
19 |
+
- travis_retry composer self-update
|
20 |
+
- composer validate
|
21 |
+
- composer config github-oauth.github.com $GITHUB_TOKEN
|
22 |
+
|
23 |
+
install:
|
24 |
+
- travis_retry composer install --no-interaction --prefer-dist
|
25 |
+
|
26 |
+
script:
|
27 |
+
- vendor/bin/phpunit
|
28 |
+
- if [[ "$WITH_CS" == "true" ]]; then vendor/bin/phpcs --standard=phpcs.xml -p; fi
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/CONTRIBUTING.md
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributing to Facebook Instant Articles SDK Extensions in PHP
|
2 |
+
We want to make contributing to this project as easy and transparent as possible.
|
3 |
+
|
4 |
+
We accept contributions via pull requests on [GitHub](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php).
|
5 |
+
|
6 |
+
## Pull Requests
|
7 |
+
- **Sign the CLA** - In order to accept your pull request, we need you to submit a [Contributor License Agreement](https://code.facebook.com/cla). You only need to do this once to work on any of Facebook's open source projects.
|
8 |
+
|
9 |
+
- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to run [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) as you code.
|
10 |
+
|
11 |
+
- **Add tests** - If you've added code that can be tested, add tests.
|
12 |
+
|
13 |
+
- **Document any change in behaviour** - Make sure the README file is updated in your PR. Include any notes for documentation items which needs to be updated on the main [docs on Facebook's Developer site](https://developers.facebook.com/docs/instant-articles/sdk/).
|
14 |
+
|
15 |
+
- **Consider our release cycle** - We try to follow [SemVer](http://semver.org/). Randomly breaking public APIs is not an option.
|
16 |
+
|
17 |
+
- **Create topic branches** - Don't ask us to pull from your master branch.
|
18 |
+
|
19 |
+
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
|
20 |
+
|
21 |
+
- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
|
22 |
+
|
23 |
+
- **Ensure tests pass!** - Please [run the tests](https://github.com/facebook/facebook-instant-articles-sdk-extensions-php#testing-and-developing) before submitting your pull request, and make sure they pass. We won't accept a patch until all tests pass.
|
24 |
+
|
25 |
+
- **Ensure no coding standards violations** - Please run [PHP Code Sniffer](https://github.com/squizlabs/PHP_CodeSniffer) using the PSR-2 standard before submitting your pull request. A violation will cause the build to fail, so please make sure there are no violations. We can't accept a patch if the build fails.
|
26 |
+
|
27 |
+
|
28 |
+
## Issues
|
29 |
+
We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue.
|
30 |
+
|
31 |
+
|
32 |
+
## Running Tests
|
33 |
+
|
34 |
+
``` bash
|
35 |
+
$ ./vendor/bin/phpunit
|
36 |
+
```
|
37 |
+
|
38 |
+
When doing a pull request, consider if this diff has a testcase that was covered in a wrong way or if it needs a new test case.
|
39 |
+
|
40 |
+
|
41 |
+
## Running PHP Code Sniffer
|
42 |
+
|
43 |
+
Run Code Sniffer against the `src/` and `tests/` directories.
|
44 |
+
|
45 |
+
``` bash
|
46 |
+
$ vendor/bin/phpcs --standard=phpcs.xml -p
|
47 |
+
```
|
48 |
+
|
49 |
+
Give a try for the autofixer for code style
|
50 |
+
|
51 |
+
``` bash
|
52 |
+
$ vendor/bin/phpcbf --standard-phpcs.xml -p
|
53 |
+
```
|
54 |
+
**Happy coding**!
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
|
2 |
+
|
3 |
+
You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
4 |
+
use, copy, modify, and distribute this software in source code or binary
|
5 |
+
form for use in connection with the web services and APIs provided by
|
6 |
+
Facebook.
|
7 |
+
|
8 |
+
As with any software that integrates with the Facebook platform, your use
|
9 |
+
of this software is subject to the Facebook Developer Principles and
|
10 |
+
Policies [http://developers.facebook.com/policy/]. This copyright notice
|
11 |
+
shall be included in all 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
|
16 |
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
18 |
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
19 |
+
DEALINGS IN THE SOFTWARE.
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Facebook Instant Articles SDK Extensions in PHP #
|
2 |
+
|
3 |
+
[![Build Status](https://travis-ci.org/facebook/facebook-instant-articles-sdk-extensions-in-php.svg?branch=master)](https://travis-ci.org/facebook/facebook-instant-articles-sdk-extensions-in-php)
|
4 |
+
[![Latest Stable Version](https://poser.pugx.org/facebook/facebook-instant-articles-sdk-extensions-in-php/v/stable)](https://packagist.org/packages/facebook/facebook-instant-articles-sdk-extensions-in-php)
|
5 |
+
|
6 |
+
The Facebook Instant Articles SDK Extensions in PHP provides a native PHP interface for converting valid Instant Articles into AMP. This gives developers the ability to have AMP content right after getting his own Instant Article markup format ready.
|
7 |
+
|
8 |
+
The Extension package consists of:
|
9 |
+
- **Environment**: PHP >= 5.4 or HHVM
|
10 |
+
- **Dependencies**: It relies solely on the [Instant Articles SDK](https://github.com/Facebook/facebook-instant-articles-sdk-php) and its dependencies to get the Instant Article markup format available into the Elements object tree structure. It also depends on [Composer](https://getcomposer.org/) dependency manager.
|
11 |
+
- **AMP**: The AMP transformation was based on the current implementation and definition from [AMP project](https://www.ampproject.org/).
|
12 |
+
|
13 |
+
## Quick Start
|
14 |
+
|
15 |
+
```sh
|
16 |
+
$ composer require facebook/facebook-instant-articles-sdk-extensions-in-php
|
17 |
+
```
|
18 |
+
|
19 |
+
After the installation, you can include the auto loader script in your source with:
|
20 |
+
|
21 |
+
```PHP
|
22 |
+
require_once('vendor/autoload.php');
|
23 |
+
```
|
24 |
+
|
25 |
+
Also be sure to check [the quick start example](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/examples/example-quick-start.php).
|
26 |
+
|
27 |
+
## Official Documentation
|
28 |
+
|
29 |
+
You can find examples on how to use the different components of this SDK to integrate with your CMS in the [Quick Start Guide](https://developers.facebook.com/docs/instant-articles/other-formats/#quickstart) of the [documentation](https://developers.facebook.com/docs/instant-articles/other-formats/).
|
30 |
+
|
31 |
+
## Contributing
|
32 |
+
|
33 |
+
Clone the repository
|
34 |
+
```sh
|
35 |
+
$ git clone https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php.git
|
36 |
+
```
|
37 |
+
|
38 |
+
[Composer](https://getcomposer.org/) is a prerequisite for testing and developing. [Install composer globally](https://getcomposer.org/doc/00-intro.md#globally), then install project dependencies by running this command in the project's root directory:
|
39 |
+
|
40 |
+
```sh
|
41 |
+
$ composer install
|
42 |
+
```
|
43 |
+
|
44 |
+
To run the tests:
|
45 |
+
|
46 |
+
```sh
|
47 |
+
$ composer test
|
48 |
+
```
|
49 |
+
|
50 |
+
To fix and check for coding style issues:
|
51 |
+
|
52 |
+
```sh
|
53 |
+
$ composer cs
|
54 |
+
```
|
55 |
+
|
56 |
+
Extra lazy? Run
|
57 |
+
|
58 |
+
```sh
|
59 |
+
$ composer all
|
60 |
+
```
|
61 |
+
|
62 |
+
to fix and check for coding style issues, and run the tests.
|
63 |
+
|
64 |
+
If you change structure, paths, namespaces, etc., make sure you run the [autoload generator](https://getcomposer.org/doc/03-cli.md#dump-autoload):
|
65 |
+
```sh
|
66 |
+
$ composer dump-autoload
|
67 |
+
```
|
68 |
+
|
69 |
+
___
|
70 |
+
**For us to accept contributions you will have to first sign the [Contributor License Agreement](https://code.facebook.com/cla). Please see [CONTRIBUTING](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/CONTRIBUTING.md) for details.**
|
71 |
+
___
|
72 |
+
|
73 |
+
## Troubleshooting
|
74 |
+
|
75 |
+
If you are encountering problems, the following tips may help in troubleshooting issues:
|
76 |
+
|
77 |
+
- Set the `threshold` in the [configuration of the Logger](https://logging.apache.org/log4php/docs/configuration.html#PHP) to `DEBUG` to expose more details about the items processed by the Transformer, conversely, to make it more quiet set it to `INFO`, check [this script](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/examples/quiet_logger.php) for details.
|
78 |
+
- If your images are having dimension/aspect ratio problems, please check the [the quick start example](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/examples/example-quick-start.php) for more information.
|
79 |
+
- At the moment, we have no way to determine a video's width and height, you need to explicitly pass that information via properties, see how to do it [here](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/examples/example-quick-start.php).
|
80 |
+
|
81 |
+
### Filing an issue
|
82 |
+
|
83 |
+
- Be sure you've looked for the similar issue into the [Issues list](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/issues)
|
84 |
+
|
85 |
+
- Inform the Canonical URL of your Instant Article being converted
|
86 |
+
|
87 |
+
- Inform the [exported JSON from the style editor](https://developers.facebook.com/docs/instant-articles/other-formats#style)
|
88 |
+
|
89 |
+
Issue template:
|
90 |
+
```
|
91 |
+
# Issue Data
|
92 |
+
Instant Article Canonical URL: `http://yourdomain.com/path/article.html`
|
93 |
+
Exported Style JSON: `{...}`
|
94 |
+
Page ID: `12345`
|
95 |
+
|
96 |
+
# Problem noticed
|
97 |
+
1. Image XYZ missing
|
98 |
+
|
99 |
+
# Expected result
|
100 |
+
1. The Image XYZ should be present.
|
101 |
+
```
|
102 |
+
|
103 |
+
## License
|
104 |
+
|
105 |
+
Please see the [license file](https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/blob/master/LICENSE) for more information.
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/composer.json
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "facebook/facebook-instant-articles-sdk-extensions-in-php",
|
3 |
+
"description": "Facebook Instant Articles SDK Extensions in PHP to transform Instant Articles markup file into AMP",
|
4 |
+
"keywords": ["facebook", "sdk", "instant", "articles", "instantarticles", "amp", "extensions"],
|
5 |
+
"type": "library",
|
6 |
+
"homepage": "https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php",
|
7 |
+
"license": "proprietary",
|
8 |
+
"authors": [{
|
9 |
+
"name": "Facebook",
|
10 |
+
"homepage": "https://github.com/facebook/facebook-instant-articles-sdk-extensions-in-php/contributors"
|
11 |
+
}],
|
12 |
+
"require": {
|
13 |
+
"php": "^5.4 || ^7.0",
|
14 |
+
"facebook/facebook-instant-articles-sdk-php": "^1.6"
|
15 |
+
},
|
16 |
+
"require-dev": {
|
17 |
+
"phpunit/phpunit": "^4.8"
|
18 |
+
},
|
19 |
+
"autoload": {
|
20 |
+
"psr-4": {
|
21 |
+
"Facebook\\InstantArticles\\": "src/Facebook/InstantArticles/"
|
22 |
+
}
|
23 |
+
},
|
24 |
+
"autoload-dev": {
|
25 |
+
"psr-4": {
|
26 |
+
"Facebook\\InstantArticles\\": "tests/Facebook/InstantArticles/"
|
27 |
+
}
|
28 |
+
},
|
29 |
+
"scripts": {
|
30 |
+
"all": [
|
31 |
+
"@cs",
|
32 |
+
"@test"
|
33 |
+
],
|
34 |
+
"cs": [
|
35 |
+
"composer install",
|
36 |
+
"phpcbf --standard=phpcs.xml -p || phpcs --standard=phpcs.xml -p"
|
37 |
+
],
|
38 |
+
"test": [
|
39 |
+
"composer install",
|
40 |
+
"phpunit"
|
41 |
+
]
|
42 |
+
}
|
43 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/composer.lock
ADDED
@@ -0,0 +1,1329 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_readme": [
|
3 |
+
"This file locks the dependencies of your project to a known state",
|
4 |
+
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
5 |
+
"This file is @generated automatically"
|
6 |
+
],
|
7 |
+
"content-hash": "b5add67aa5284f095c0e347b2a704d1b",
|
8 |
+
"packages": [
|
9 |
+
{
|
10 |
+
"name": "apache/log4php",
|
11 |
+
"version": "2.3.0",
|
12 |
+
"source": {
|
13 |
+
"type": "git",
|
14 |
+
"url": "https://git-wip-us.apache.org/repos/asf/logging-log4php.git",
|
15 |
+
"reference": "cac428b6f67d2035af39784da1d1a299ef42fcf2"
|
16 |
+
},
|
17 |
+
"require": {
|
18 |
+
"php": ">=5.2.7"
|
19 |
+
},
|
20 |
+
"type": "library",
|
21 |
+
"autoload": {
|
22 |
+
"classmap": [
|
23 |
+
"src/main/php/"
|
24 |
+
]
|
25 |
+
},
|
26 |
+
"notification-url": "https://packagist.org/downloads/",
|
27 |
+
"license": [
|
28 |
+
"Apache-2.0"
|
29 |
+
],
|
30 |
+
"description": "A versatile logging framework for PHP",
|
31 |
+
"homepage": "http://logging.apache.org/log4php/",
|
32 |
+
"keywords": [
|
33 |
+
"log",
|
34 |
+
"logging",
|
35 |
+
"php"
|
36 |
+
],
|
37 |
+
"time": "2012-10-26T09:13:25+00:00"
|
38 |
+
},
|
39 |
+
{
|
40 |
+
"name": "facebook/facebook-instant-articles-sdk-php",
|
41 |
+
"version": "v1.6.0",
|
42 |
+
"source": {
|
43 |
+
"type": "git",
|
44 |
+
"url": "https://github.com/facebook/facebook-instant-articles-sdk-php.git",
|
45 |
+
"reference": "c0d9491ad7c44ae1e96fa7d5f7f54262b9f8186d"
|
46 |
+
},
|
47 |
+
"dist": {
|
48 |
+
"type": "zip",
|
49 |
+
"url": "https://api.github.com/repos/facebook/facebook-instant-articles-sdk-php/zipball/c0d9491ad7c44ae1e96fa7d5f7f54262b9f8186d",
|
50 |
+
"reference": "c0d9491ad7c44ae1e96fa7d5f7f54262b9f8186d",
|
51 |
+
"shasum": ""
|
52 |
+
},
|
53 |
+
"require": {
|
54 |
+
"apache/log4php": "2.3.0",
|
55 |
+
"facebook/graph-sdk": "~5.0",
|
56 |
+
"php": "^5.4 || ^7.0",
|
57 |
+
"symfony/css-selector": "2.8.* || ^3.0"
|
58 |
+
},
|
59 |
+
"require-dev": {
|
60 |
+
"fzaninotto/faker": "^1.6.0",
|
61 |
+
"phpunit/phpunit": "^4.8",
|
62 |
+
"squizlabs/php_codesniffer": "^2.6.0"
|
63 |
+
},
|
64 |
+
"type": "library",
|
65 |
+
"autoload": {
|
66 |
+
"psr-4": {
|
67 |
+
"Facebook\\InstantArticles\\": "src/Facebook/InstantArticles/"
|
68 |
+
}
|
69 |
+
},
|
70 |
+
"notification-url": "https://packagist.org/downloads/",
|
71 |
+
"license": [
|
72 |
+
"proprietary"
|
73 |
+
],
|
74 |
+
"authors": [
|
75 |
+
{
|
76 |
+
"name": "Facebook",
|
77 |
+
"homepage": "https://github.com/facebook/facebook-instant-articles-sdk-php/contributors"
|
78 |
+
}
|
79 |
+
],
|
80 |
+
"description": "Facebook Instant Articles SDK for PHP",
|
81 |
+
"homepage": "https://github.com/facebook/facebook-instant-articles-sdk-php",
|
82 |
+
"keywords": [
|
83 |
+
"articles",
|
84 |
+
"facebook",
|
85 |
+
"instant",
|
86 |
+
"sdk"
|
87 |
+
],
|
88 |
+
"time": "2017-05-24T22:31:08+00:00"
|
89 |
+
},
|
90 |
+
{
|
91 |
+
"name": "facebook/graph-sdk",
|
92 |
+
"version": "5.5.0",
|
93 |
+
"source": {
|
94 |
+
"type": "git",
|
95 |
+
"url": "https://github.com/facebook/php-graph-sdk.git",
|
96 |
+
"reference": "93d7dc87e55a541d2e27d38f3aed40abbffdf6e1"
|
97 |
+
},
|
98 |
+
"dist": {
|
99 |
+
"type": "zip",
|
100 |
+
"url": "https://api.github.com/repos/facebook/php-graph-sdk/zipball/93d7dc87e55a541d2e27d38f3aed40abbffdf6e1",
|
101 |
+
"reference": "93d7dc87e55a541d2e27d38f3aed40abbffdf6e1",
|
102 |
+
"shasum": ""
|
103 |
+
},
|
104 |
+
"require": {
|
105 |
+
"php": "^5.4|^7.0"
|
106 |
+
},
|
107 |
+
"require-dev": {
|
108 |
+
"guzzlehttp/guzzle": "~5.0",
|
109 |
+
"mockery/mockery": "~0.8",
|
110 |
+
"phpunit/phpunit": "~4.0"
|
111 |
+
},
|
112 |
+
"suggest": {
|
113 |
+
"guzzlehttp/guzzle": "Allows for implementation of the Guzzle HTTP client",
|
114 |
+
"paragonie/random_compat": "Provides a better CSPRNG option in PHP 5"
|
115 |
+
},
|
116 |
+
"type": "library",
|
117 |
+
"extra": {
|
118 |
+
"branch-alias": {
|
119 |
+
"dev-master": "5.x-dev"
|
120 |
+
}
|
121 |
+
},
|
122 |
+
"autoload": {
|
123 |
+
"psr-4": {
|
124 |
+
"Facebook\\": "src/Facebook/"
|
125 |
+
},
|
126 |
+
"files": [
|
127 |
+
"src/Facebook/polyfills.php"
|
128 |
+
]
|
129 |
+
},
|
130 |
+
"notification-url": "https://packagist.org/downloads/",
|
131 |
+
"license": [
|
132 |
+
"Facebook Platform"
|
133 |
+
],
|
134 |
+
"authors": [
|
135 |
+
{
|
136 |
+
"name": "Facebook",
|
137 |
+
"homepage": "https://github.com/facebook/php-graph-sdk/contributors"
|
138 |
+
}
|
139 |
+
],
|
140 |
+
"description": "Facebook SDK for PHP",
|
141 |
+
"homepage": "https://github.com/facebook/php-graph-sdk",
|
142 |
+
"keywords": [
|
143 |
+
"facebook",
|
144 |
+
"sdk"
|
145 |
+
],
|
146 |
+
"time": "2017-04-20T14:15:02+00:00"
|
147 |
+
},
|
148 |
+
{
|
149 |
+
"name": "symfony/css-selector",
|
150 |
+
"version": "v3.2.8",
|
151 |
+
"source": {
|
152 |
+
"type": "git",
|
153 |
+
"url": "https://github.com/symfony/css-selector.git",
|
154 |
+
"reference": "02983c144038e697c959e6b06ef6666de759ccbc"
|
155 |
+
},
|
156 |
+
"dist": {
|
157 |
+
"type": "zip",
|
158 |
+
"url": "https://api.github.com/repos/symfony/css-selector/zipball/02983c144038e697c959e6b06ef6666de759ccbc",
|
159 |
+
"reference": "02983c144038e697c959e6b06ef6666de759ccbc",
|
160 |
+
"shasum": ""
|
161 |
+
},
|
162 |
+
"require": {
|
163 |
+
"php": ">=5.5.9"
|
164 |
+
},
|
165 |
+
"type": "library",
|
166 |
+
"extra": {
|
167 |
+
"branch-alias": {
|
168 |
+
"dev-master": "3.2-dev"
|
169 |
+
}
|
170 |
+
},
|
171 |
+
"autoload": {
|
172 |
+
"psr-4": {
|
173 |
+
"Symfony\\Component\\CssSelector\\": ""
|
174 |
+
},
|
175 |
+
"exclude-from-classmap": [
|
176 |
+
"/Tests/"
|
177 |
+
]
|
178 |
+
},
|
179 |
+
"notification-url": "https://packagist.org/downloads/",
|
180 |
+
"license": [
|
181 |
+
"MIT"
|
182 |
+
],
|
183 |
+
"authors": [
|
184 |
+
{
|
185 |
+
"name": "Jean-François Simon",
|
186 |
+
"email": "jeanfrancois.simon@sensiolabs.com"
|
187 |
+
},
|
188 |
+
{
|
189 |
+
"name": "Fabien Potencier",
|
190 |
+
"email": "fabien@symfony.com"
|
191 |
+
},
|
192 |
+
{
|
193 |
+
"name": "Symfony Community",
|
194 |
+
"homepage": "https://symfony.com/contributors"
|
195 |
+
}
|
196 |
+
],
|
197 |
+
"description": "Symfony CssSelector Component",
|
198 |
+
"homepage": "https://symfony.com",
|
199 |
+
"time": "2017-05-01T14:55:58+00:00"
|
200 |
+
}
|
201 |
+
],
|
202 |
+
"packages-dev": [
|
203 |
+
{
|
204 |
+
"name": "doctrine/instantiator",
|
205 |
+
"version": "1.0.5",
|
206 |
+
"source": {
|
207 |
+
"type": "git",
|
208 |
+
"url": "https://github.com/doctrine/instantiator.git",
|
209 |
+
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
|
210 |
+
},
|
211 |
+
"dist": {
|
212 |
+
"type": "zip",
|
213 |
+
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
|
214 |
+
"reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
|
215 |
+
"shasum": ""
|
216 |
+
},
|
217 |
+
"require": {
|
218 |
+
"php": ">=5.3,<8.0-DEV"
|
219 |
+
},
|
220 |
+
"require-dev": {
|
221 |
+
"athletic/athletic": "~0.1.8",
|
222 |
+
"ext-pdo": "*",
|
223 |
+
"ext-phar": "*",
|
224 |
+
"phpunit/phpunit": "~4.0",
|
225 |
+
"squizlabs/php_codesniffer": "~2.0"
|
226 |
+
},
|
227 |
+
"type": "library",
|
228 |
+
"extra": {
|
229 |
+
"branch-alias": {
|
230 |
+
"dev-master": "1.0.x-dev"
|
231 |
+
}
|
232 |
+
},
|
233 |
+
"autoload": {
|
234 |
+
"psr-4": {
|
235 |
+
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
|
236 |
+
}
|
237 |
+
},
|
238 |
+
"notification-url": "https://packagist.org/downloads/",
|
239 |
+
"license": [
|
240 |
+
"MIT"
|
241 |
+
],
|
242 |
+
"authors": [
|
243 |
+
{
|
244 |
+
"name": "Marco Pivetta",
|
245 |
+
"email": "ocramius@gmail.com",
|
246 |
+
"homepage": "http://ocramius.github.com/"
|
247 |
+
}
|
248 |
+
],
|
249 |
+
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
|
250 |
+
"homepage": "https://github.com/doctrine/instantiator",
|
251 |
+
"keywords": [
|
252 |
+
"constructor",
|
253 |
+
"instantiate"
|
254 |
+
],
|
255 |
+
"time": "2015-06-14T21:17:01+00:00"
|
256 |
+
},
|
257 |
+
{
|
258 |
+
"name": "phpdocumentor/reflection-common",
|
259 |
+
"version": "1.0",
|
260 |
+
"source": {
|
261 |
+
"type": "git",
|
262 |
+
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
|
263 |
+
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
|
264 |
+
},
|
265 |
+
"dist": {
|
266 |
+
"type": "zip",
|
267 |
+
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
|
268 |
+
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
|
269 |
+
"shasum": ""
|
270 |
+
},
|
271 |
+
"require": {
|
272 |
+
"php": ">=5.5"
|
273 |
+
},
|
274 |
+
"require-dev": {
|
275 |
+
"phpunit/phpunit": "^4.6"
|
276 |
+
},
|
277 |
+
"type": "library",
|
278 |
+
"extra": {
|
279 |
+
"branch-alias": {
|
280 |
+
"dev-master": "1.0.x-dev"
|
281 |
+
}
|
282 |
+
},
|
283 |
+
"autoload": {
|
284 |
+
"psr-4": {
|
285 |
+
"phpDocumentor\\Reflection\\": [
|
286 |
+
"src"
|
287 |
+
]
|
288 |
+
}
|
289 |
+
},
|
290 |
+
"notification-url": "https://packagist.org/downloads/",
|
291 |
+
"license": [
|
292 |
+
"MIT"
|
293 |
+
],
|
294 |
+
"authors": [
|
295 |
+
{
|
296 |
+
"name": "Jaap van Otterdijk",
|
297 |
+
"email": "opensource@ijaap.nl"
|
298 |
+
}
|
299 |
+
],
|
300 |
+
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
|
301 |
+
"homepage": "http://www.phpdoc.org",
|
302 |
+
"keywords": [
|
303 |
+
"FQSEN",
|
304 |
+
"phpDocumentor",
|
305 |
+
"phpdoc",
|
306 |
+
"reflection",
|
307 |
+
"static analysis"
|
308 |
+
],
|
309 |
+
"time": "2015-12-27T11:43:31+00:00"
|
310 |
+
},
|
311 |
+
{
|
312 |
+
"name": "phpdocumentor/reflection-docblock",
|
313 |
+
"version": "3.1.1",
|
314 |
+
"source": {
|
315 |
+
"type": "git",
|
316 |
+
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
317 |
+
"reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
|
318 |
+
},
|
319 |
+
"dist": {
|
320 |
+
"type": "zip",
|
321 |
+
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
|
322 |
+
"reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
|
323 |
+
"shasum": ""
|
324 |
+
},
|
325 |
+
"require": {
|
326 |
+
"php": ">=5.5",
|
327 |
+
"phpdocumentor/reflection-common": "^1.0@dev",
|
328 |
+
"phpdocumentor/type-resolver": "^0.2.0",
|
329 |
+
"webmozart/assert": "^1.0"
|
330 |
+
},
|
331 |
+
"require-dev": {
|
332 |
+
"mockery/mockery": "^0.9.4",
|
333 |
+
"phpunit/phpunit": "^4.4"
|
334 |
+
},
|
335 |
+
"type": "library",
|
336 |
+
"autoload": {
|
337 |
+
"psr-4": {
|
338 |
+
"phpDocumentor\\Reflection\\": [
|
339 |
+
"src/"
|
340 |
+
]
|
341 |
+
}
|
342 |
+
},
|
343 |
+
"notification-url": "https://packagist.org/downloads/",
|
344 |
+
"license": [
|
345 |
+
"MIT"
|
346 |
+
],
|
347 |
+
"authors": [
|
348 |
+
{
|
349 |
+
"name": "Mike van Riel",
|
350 |
+
"email": "me@mikevanriel.com"
|
351 |
+
}
|
352 |
+
],
|
353 |
+
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
354 |
+
"time": "2016-09-30T07:12:33+00:00"
|
355 |
+
},
|
356 |
+
{
|
357 |
+
"name": "phpdocumentor/type-resolver",
|
358 |
+
"version": "0.2.1",
|
359 |
+
"source": {
|
360 |
+
"type": "git",
|
361 |
+
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
362 |
+
"reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
|
363 |
+
},
|
364 |
+
"dist": {
|
365 |
+
"type": "zip",
|
366 |
+
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
|
367 |
+
"reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
|
368 |
+
"shasum": ""
|
369 |
+
},
|
370 |
+
"require": {
|
371 |
+
"php": ">=5.5",
|
372 |
+
"phpdocumentor/reflection-common": "^1.0"
|
373 |
+
},
|
374 |
+
"require-dev": {
|
375 |
+
"mockery/mockery": "^0.9.4",
|
376 |
+
"phpunit/phpunit": "^5.2||^4.8.24"
|
377 |
+
},
|
378 |
+
"type": "library",
|
379 |
+
"extra": {
|
380 |
+
"branch-alias": {
|
381 |
+
"dev-master": "1.0.x-dev"
|
382 |
+
}
|
383 |
+
},
|
384 |
+
"autoload": {
|
385 |
+
"psr-4": {
|
386 |
+
"phpDocumentor\\Reflection\\": [
|
387 |
+
"src/"
|
388 |
+
]
|
389 |
+
}
|
390 |
+
},
|
391 |
+
"notification-url": "https://packagist.org/downloads/",
|
392 |
+
"license": [
|
393 |
+
"MIT"
|
394 |
+
],
|
395 |
+
"authors": [
|
396 |
+
{
|
397 |
+
"name": "Mike van Riel",
|
398 |
+
"email": "me@mikevanriel.com"
|
399 |
+
}
|
400 |
+
],
|
401 |
+
"time": "2016-11-25T06:54:22+00:00"
|
402 |
+
},
|
403 |
+
{
|
404 |
+
"name": "phpspec/prophecy",
|
405 |
+
"version": "v1.7.0",
|
406 |
+
"source": {
|
407 |
+
"type": "git",
|
408 |
+
"url": "https://github.com/phpspec/prophecy.git",
|
409 |
+
"reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
|
410 |
+
},
|
411 |
+
"dist": {
|
412 |
+
"type": "zip",
|
413 |
+
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
|
414 |
+
"reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
|
415 |
+
"shasum": ""
|
416 |
+
},
|
417 |
+
"require": {
|
418 |
+
"doctrine/instantiator": "^1.0.2",
|
419 |
+
"php": "^5.3|^7.0",
|
420 |
+
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
|
421 |
+
"sebastian/comparator": "^1.1|^2.0",
|
422 |
+
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
|
423 |
+
},
|
424 |
+
"require-dev": {
|
425 |
+
"phpspec/phpspec": "^2.5|^3.2",
|
426 |
+
"phpunit/phpunit": "^4.8 || ^5.6.5"
|
427 |
+
},
|
428 |
+
"type": "library",
|
429 |
+
"extra": {
|
430 |
+
"branch-alias": {
|
431 |
+
"dev-master": "1.6.x-dev"
|
432 |
+
}
|
433 |
+
},
|
434 |
+
"autoload": {
|
435 |
+
"psr-0": {
|
436 |
+
"Prophecy\\": "src/"
|
437 |
+
}
|
438 |
+
},
|
439 |
+
"notification-url": "https://packagist.org/downloads/",
|
440 |
+
"license": [
|
441 |
+
"MIT"
|
442 |
+
],
|
443 |
+
"authors": [
|
444 |
+
{
|
445 |
+
"name": "Konstantin Kudryashov",
|
446 |
+
"email": "ever.zet@gmail.com",
|
447 |
+
"homepage": "http://everzet.com"
|
448 |
+
},
|
449 |
+
{
|
450 |
+
"name": "Marcello Duarte",
|
451 |
+
"email": "marcello.duarte@gmail.com"
|
452 |
+
}
|
453 |
+
],
|
454 |
+
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
455 |
+
"homepage": "https://github.com/phpspec/prophecy",
|
456 |
+
"keywords": [
|
457 |
+
"Double",
|
458 |
+
"Dummy",
|
459 |
+
"fake",
|
460 |
+
"mock",
|
461 |
+
"spy",
|
462 |
+
"stub"
|
463 |
+
],
|
464 |
+
"time": "2017-03-02T20:05:34+00:00"
|
465 |
+
},
|
466 |
+
{
|
467 |
+
"name": "phpunit/php-code-coverage",
|
468 |
+
"version": "2.2.4",
|
469 |
+
"source": {
|
470 |
+
"type": "git",
|
471 |
+
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
472 |
+
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
|
473 |
+
},
|
474 |
+
"dist": {
|
475 |
+
"type": "zip",
|
476 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
|
477 |
+
"reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
|
478 |
+
"shasum": ""
|
479 |
+
},
|
480 |
+
"require": {
|
481 |
+
"php": ">=5.3.3",
|
482 |
+
"phpunit/php-file-iterator": "~1.3",
|
483 |
+
"phpunit/php-text-template": "~1.2",
|
484 |
+
"phpunit/php-token-stream": "~1.3",
|
485 |
+
"sebastian/environment": "^1.3.2",
|
486 |
+
"sebastian/version": "~1.0"
|
487 |
+
},
|
488 |
+
"require-dev": {
|
489 |
+
"ext-xdebug": ">=2.1.4",
|
490 |
+
"phpunit/phpunit": "~4"
|
491 |
+
},
|
492 |
+
"suggest": {
|
493 |
+
"ext-dom": "*",
|
494 |
+
"ext-xdebug": ">=2.2.1",
|
495 |
+
"ext-xmlwriter": "*"
|
496 |
+
},
|
497 |
+
"type": "library",
|
498 |
+
"extra": {
|
499 |
+
"branch-alias": {
|
500 |
+
"dev-master": "2.2.x-dev"
|
501 |
+
}
|
502 |
+
},
|
503 |
+
"autoload": {
|
504 |
+
"classmap": [
|
505 |
+
"src/"
|
506 |
+
]
|
507 |
+
},
|
508 |
+
"notification-url": "https://packagist.org/downloads/",
|
509 |
+
"license": [
|
510 |
+
"BSD-3-Clause"
|
511 |
+
],
|
512 |
+
"authors": [
|
513 |
+
{
|
514 |
+
"name": "Sebastian Bergmann",
|
515 |
+
"email": "sb@sebastian-bergmann.de",
|
516 |
+
"role": "lead"
|
517 |
+
}
|
518 |
+
],
|
519 |
+
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
|
520 |
+
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
|
521 |
+
"keywords": [
|
522 |
+
"coverage",
|
523 |
+
"testing",
|
524 |
+
"xunit"
|
525 |
+
],
|
526 |
+
"time": "2015-10-06T15:47:00+00:00"
|
527 |
+
},
|
528 |
+
{
|
529 |
+
"name": "phpunit/php-file-iterator",
|
530 |
+
"version": "1.4.2",
|
531 |
+
"source": {
|
532 |
+
"type": "git",
|
533 |
+
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
534 |
+
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
|
535 |
+
},
|
536 |
+
"dist": {
|
537 |
+
"type": "zip",
|
538 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
|
539 |
+
"reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
|
540 |
+
"shasum": ""
|
541 |
+
},
|
542 |
+
"require": {
|
543 |
+
"php": ">=5.3.3"
|
544 |
+
},
|
545 |
+
"type": "library",
|
546 |
+
"extra": {
|
547 |
+
"branch-alias": {
|
548 |
+
"dev-master": "1.4.x-dev"
|
549 |
+
}
|
550 |
+
},
|
551 |
+
"autoload": {
|
552 |
+
"classmap": [
|
553 |
+
"src/"
|
554 |
+
]
|
555 |
+
},
|
556 |
+
"notification-url": "https://packagist.org/downloads/",
|
557 |
+
"license": [
|
558 |
+
"BSD-3-Clause"
|
559 |
+
],
|
560 |
+
"authors": [
|
561 |
+
{
|
562 |
+
"name": "Sebastian Bergmann",
|
563 |
+
"email": "sb@sebastian-bergmann.de",
|
564 |
+
"role": "lead"
|
565 |
+
}
|
566 |
+
],
|
567 |
+
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
|
568 |
+
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
|
569 |
+
"keywords": [
|
570 |
+
"filesystem",
|
571 |
+
"iterator"
|
572 |
+
],
|
573 |
+
"time": "2016-10-03T07:40:28+00:00"
|
574 |
+
},
|
575 |
+
{
|
576 |
+
"name": "phpunit/php-text-template",
|
577 |
+
"version": "1.2.1",
|
578 |
+
"source": {
|
579 |
+
"type": "git",
|
580 |
+
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
581 |
+
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
|
582 |
+
},
|
583 |
+
"dist": {
|
584 |
+
"type": "zip",
|
585 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
586 |
+
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
587 |
+
"shasum": ""
|
588 |
+
},
|
589 |
+
"require": {
|
590 |
+
"php": ">=5.3.3"
|
591 |
+
},
|
592 |
+
"type": "library",
|
593 |
+
"autoload": {
|
594 |
+
"classmap": [
|
595 |
+
"src/"
|
596 |
+
]
|
597 |
+
},
|
598 |
+
"notification-url": "https://packagist.org/downloads/",
|
599 |
+
"license": [
|
600 |
+
"BSD-3-Clause"
|
601 |
+
],
|
602 |
+
"authors": [
|
603 |
+
{
|
604 |
+
"name": "Sebastian Bergmann",
|
605 |
+
"email": "sebastian@phpunit.de",
|
606 |
+
"role": "lead"
|
607 |
+
}
|
608 |
+
],
|
609 |
+
"description": "Simple template engine.",
|
610 |
+
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
|
611 |
+
"keywords": [
|
612 |
+
"template"
|
613 |
+
],
|
614 |
+
"time": "2015-06-21T13:50:34+00:00"
|
615 |
+
},
|
616 |
+
{
|
617 |
+
"name": "phpunit/php-timer",
|
618 |
+
"version": "1.0.9",
|
619 |
+
"source": {
|
620 |
+
"type": "git",
|
621 |
+
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
622 |
+
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
|
623 |
+
},
|
624 |
+
"dist": {
|
625 |
+
"type": "zip",
|
626 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
|
627 |
+
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
|
628 |
+
"shasum": ""
|
629 |
+
},
|
630 |
+
"require": {
|
631 |
+
"php": "^5.3.3 || ^7.0"
|
632 |
+
},
|
633 |
+
"require-dev": {
|
634 |
+
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
|
635 |
+
},
|
636 |
+
"type": "library",
|
637 |
+
"extra": {
|
638 |
+
"branch-alias": {
|
639 |
+
"dev-master": "1.0-dev"
|
640 |
+
}
|
641 |
+
},
|
642 |
+
"autoload": {
|
643 |
+
"classmap": [
|
644 |
+
"src/"
|
645 |
+
]
|
646 |
+
},
|
647 |
+
"notification-url": "https://packagist.org/downloads/",
|
648 |
+
"license": [
|
649 |
+
"BSD-3-Clause"
|
650 |
+
],
|
651 |
+
"authors": [
|
652 |
+
{
|
653 |
+
"name": "Sebastian Bergmann",
|
654 |
+
"email": "sb@sebastian-bergmann.de",
|
655 |
+
"role": "lead"
|
656 |
+
}
|
657 |
+
],
|
658 |
+
"description": "Utility class for timing",
|
659 |
+
"homepage": "https://github.com/sebastianbergmann/php-timer/",
|
660 |
+
"keywords": [
|
661 |
+
"timer"
|
662 |
+
],
|
663 |
+
"time": "2017-02-26T11:10:40+00:00"
|
664 |
+
},
|
665 |
+
{
|
666 |
+
"name": "phpunit/php-token-stream",
|
667 |
+
"version": "1.4.11",
|
668 |
+
"source": {
|
669 |
+
"type": "git",
|
670 |
+
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
671 |
+
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
|
672 |
+
},
|
673 |
+
"dist": {
|
674 |
+
"type": "zip",
|
675 |
+
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
|
676 |
+
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
|
677 |
+
"shasum": ""
|
678 |
+
},
|
679 |
+
"require": {
|
680 |
+
"ext-tokenizer": "*",
|
681 |
+
"php": ">=5.3.3"
|
682 |
+
},
|
683 |
+
"require-dev": {
|
684 |
+
"phpunit/phpunit": "~4.2"
|
685 |
+
},
|
686 |
+
"type": "library",
|
687 |
+
"extra": {
|
688 |
+
"branch-alias": {
|
689 |
+
"dev-master": "1.4-dev"
|
690 |
+
}
|
691 |
+
},
|
692 |
+
"autoload": {
|
693 |
+
"classmap": [
|
694 |
+
"src/"
|
695 |
+
]
|
696 |
+
},
|
697 |
+
"notification-url": "https://packagist.org/downloads/",
|
698 |
+
"license": [
|
699 |
+
"BSD-3-Clause"
|
700 |
+
],
|
701 |
+
"authors": [
|
702 |
+
{
|
703 |
+
"name": "Sebastian Bergmann",
|
704 |
+
"email": "sebastian@phpunit.de"
|
705 |
+
}
|
706 |
+
],
|
707 |
+
"description": "Wrapper around PHP's tokenizer extension.",
|
708 |
+
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
|
709 |
+
"keywords": [
|
710 |
+
"tokenizer"
|
711 |
+
],
|
712 |
+
"time": "2017-02-27T10:12:30+00:00"
|
713 |
+
},
|
714 |
+
{
|
715 |
+
"name": "phpunit/phpunit",
|
716 |
+
"version": "4.8.35",
|
717 |
+
"source": {
|
718 |
+
"type": "git",
|
719 |
+
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
720 |
+
"reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87"
|
721 |
+
},
|
722 |
+
"dist": {
|
723 |
+
"type": "zip",
|
724 |
+
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/791b1a67c25af50e230f841ee7a9c6eba507dc87",
|
725 |
+
"reference": "791b1a67c25af50e230f841ee7a9c6eba507dc87",
|
726 |
+
"shasum": ""
|
727 |
+
},
|
728 |
+
"require": {
|
729 |
+
"ext-dom": "*",
|
730 |
+
"ext-json": "*",
|
731 |
+
"ext-pcre": "*",
|
732 |
+
"ext-reflection": "*",
|
733 |
+
"ext-spl": "*",
|
734 |
+
"php": ">=5.3.3",
|
735 |
+
"phpspec/prophecy": "^1.3.1",
|
736 |
+
"phpunit/php-code-coverage": "~2.1",
|
737 |
+
"phpunit/php-file-iterator": "~1.4",
|
738 |
+
"phpunit/php-text-template": "~1.2",
|
739 |
+
"phpunit/php-timer": "^1.0.6",
|
740 |
+
"phpunit/phpunit-mock-objects": "~2.3",
|
741 |
+
"sebastian/comparator": "~1.2.2",
|
742 |
+
"sebastian/diff": "~1.2",
|
743 |
+
"sebastian/environment": "~1.3",
|
744 |
+
"sebastian/exporter": "~1.2",
|
745 |
+
"sebastian/global-state": "~1.0",
|
746 |
+
"sebastian/version": "~1.0",
|
747 |
+
"symfony/yaml": "~2.1|~3.0"
|
748 |
+
},
|
749 |
+
"suggest": {
|
750 |
+
"phpunit/php-invoker": "~1.1"
|
751 |
+
},
|
752 |
+
"bin": [
|
753 |
+
"phpunit"
|
754 |
+
],
|
755 |
+
"type": "library",
|
756 |
+
"extra": {
|
757 |
+
"branch-alias": {
|
758 |
+
"dev-master": "4.8.x-dev"
|
759 |
+
}
|
760 |
+
},
|
761 |
+
"autoload": {
|
762 |
+
"classmap": [
|
763 |
+
"src/"
|
764 |
+
]
|
765 |
+
},
|
766 |
+
"notification-url": "https://packagist.org/downloads/",
|
767 |
+
"license": [
|
768 |
+
"BSD-3-Clause"
|
769 |
+
],
|
770 |
+
"authors": [
|
771 |
+
{
|
772 |
+
"name": "Sebastian Bergmann",
|
773 |
+
"email": "sebastian@phpunit.de",
|
774 |
+
"role": "lead"
|
775 |
+
}
|
776 |
+
],
|
777 |
+
"description": "The PHP Unit Testing framework.",
|
778 |
+
"homepage": "https://phpunit.de/",
|
779 |
+
"keywords": [
|
780 |
+
"phpunit",
|
781 |
+
"testing",
|
782 |
+
"xunit"
|
783 |
+
],
|
784 |
+
"time": "2017-02-06T05:18:07+00:00"
|
785 |
+
},
|
786 |
+
{
|
787 |
+
"name": "phpunit/phpunit-mock-objects",
|
788 |
+
"version": "2.3.8",
|
789 |
+
"source": {
|
790 |
+
"type": "git",
|
791 |
+
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
792 |
+
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
|
793 |
+
},
|
794 |
+
"dist": {
|
795 |
+
"type": "zip",
|
796 |
+
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
|
797 |
+
"reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
|
798 |
+
"shasum": ""
|
799 |
+
},
|
800 |
+
"require": {
|
801 |
+
"doctrine/instantiator": "^1.0.2",
|
802 |
+
"php": ">=5.3.3",
|
803 |
+
"phpunit/php-text-template": "~1.2",
|
804 |
+
"sebastian/exporter": "~1.2"
|
805 |
+
},
|
806 |
+
"require-dev": {
|
807 |
+
"phpunit/phpunit": "~4.4"
|
808 |
+
},
|
809 |
+
"suggest": {
|
810 |
+
"ext-soap": "*"
|
811 |
+
},
|
812 |
+
"type": "library",
|
813 |
+
"extra": {
|
814 |
+
"branch-alias": {
|
815 |
+
"dev-master": "2.3.x-dev"
|
816 |
+
}
|
817 |
+
},
|
818 |
+
"autoload": {
|
819 |
+
"classmap": [
|
820 |
+
"src/"
|
821 |
+
]
|
822 |
+
},
|
823 |
+
"notification-url": "https://packagist.org/downloads/",
|
824 |
+
"license": [
|
825 |
+
"BSD-3-Clause"
|
826 |
+
],
|
827 |
+
"authors": [
|
828 |
+
{
|
829 |
+
"name": "Sebastian Bergmann",
|
830 |
+
"email": "sb@sebastian-bergmann.de",
|
831 |
+
"role": "lead"
|
832 |
+
}
|
833 |
+
],
|
834 |
+
"description": "Mock Object library for PHPUnit",
|
835 |
+
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
|
836 |
+
"keywords": [
|
837 |
+
"mock",
|
838 |
+
"xunit"
|
839 |
+
],
|
840 |
+
"time": "2015-10-02T06:51:40+00:00"
|
841 |
+
},
|
842 |
+
{
|
843 |
+
"name": "sebastian/comparator",
|
844 |
+
"version": "1.2.4",
|
845 |
+
"source": {
|
846 |
+
"type": "git",
|
847 |
+
"url": "https://github.com/sebastianbergmann/comparator.git",
|
848 |
+
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
|
849 |
+
},
|
850 |
+
"dist": {
|
851 |
+
"type": "zip",
|
852 |
+
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
|
853 |
+
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
|
854 |
+
"shasum": ""
|
855 |
+
},
|
856 |
+
"require": {
|
857 |
+
"php": ">=5.3.3",
|
858 |
+
"sebastian/diff": "~1.2",
|
859 |
+
"sebastian/exporter": "~1.2 || ~2.0"
|
860 |
+
},
|
861 |
+
"require-dev": {
|
862 |
+
"phpunit/phpunit": "~4.4"
|
863 |
+
},
|
864 |
+
"type": "library",
|
865 |
+
"extra": {
|
866 |
+
"branch-alias": {
|
867 |
+
"dev-master": "1.2.x-dev"
|
868 |
+
}
|
869 |
+
},
|
870 |
+
"autoload": {
|
871 |
+
"classmap": [
|
872 |
+
"src/"
|
873 |
+
]
|
874 |
+
},
|
875 |
+
"notification-url": "https://packagist.org/downloads/",
|
876 |
+
"license": [
|
877 |
+
"BSD-3-Clause"
|
878 |
+
],
|
879 |
+
"authors": [
|
880 |
+
{
|
881 |
+
"name": "Jeff Welch",
|
882 |
+
"email": "whatthejeff@gmail.com"
|
883 |
+
},
|
884 |
+
{
|
885 |
+
"name": "Volker Dusch",
|
886 |
+
"email": "github@wallbash.com"
|
887 |
+
},
|
888 |
+
{
|
889 |
+
"name": "Bernhard Schussek",
|
890 |
+
"email": "bschussek@2bepublished.at"
|
891 |
+
},
|
892 |
+
{
|
893 |
+
"name": "Sebastian Bergmann",
|
894 |
+
"email": "sebastian@phpunit.de"
|
895 |
+
}
|
896 |
+
],
|
897 |
+
"description": "Provides the functionality to compare PHP values for equality",
|
898 |
+
"homepage": "http://www.github.com/sebastianbergmann/comparator",
|
899 |
+
"keywords": [
|
900 |
+
"comparator",
|
901 |
+
"compare",
|
902 |
+
"equality"
|
903 |
+
],
|
904 |
+
"time": "2017-01-29T09:50:25+00:00"
|
905 |
+
},
|
906 |
+
{
|
907 |
+
"name": "sebastian/diff",
|
908 |
+
"version": "1.4.3",
|
909 |
+
"source": {
|
910 |
+
"type": "git",
|
911 |
+
"url": "https://github.com/sebastianbergmann/diff.git",
|
912 |
+
"reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
|
913 |
+
},
|
914 |
+
"dist": {
|
915 |
+
"type": "zip",
|
916 |
+
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
|
917 |
+
"reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
|
918 |
+
"shasum": ""
|
919 |
+
},
|
920 |
+
"require": {
|
921 |
+
"php": "^5.3.3 || ^7.0"
|
922 |
+
},
|
923 |
+
"require-dev": {
|
924 |
+
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
|
925 |
+
},
|
926 |
+
"type": "library",
|
927 |
+
"extra": {
|
928 |
+
"branch-alias": {
|
929 |
+
"dev-master": "1.4-dev"
|
930 |
+
}
|
931 |
+
},
|
932 |
+
"autoload": {
|
933 |
+
"classmap": [
|
934 |
+
"src/"
|
935 |
+
]
|
936 |
+
},
|
937 |
+
"notification-url": "https://packagist.org/downloads/",
|
938 |
+
"license": [
|
939 |
+
"BSD-3-Clause"
|
940 |
+
],
|
941 |
+
"authors": [
|
942 |
+
{
|
943 |
+
"name": "Kore Nordmann",
|
944 |
+
"email": "mail@kore-nordmann.de"
|
945 |
+
},
|
946 |
+
{
|
947 |
+
"name": "Sebastian Bergmann",
|
948 |
+
"email": "sebastian@phpunit.de"
|
949 |
+
}
|
950 |
+
],
|
951 |
+
"description": "Diff implementation",
|
952 |
+
"homepage": "https://github.com/sebastianbergmann/diff",
|
953 |
+
"keywords": [
|
954 |
+
"diff"
|
955 |
+
],
|
956 |
+
"time": "2017-05-22T07:24:03+00:00"
|
957 |
+
},
|
958 |
+
{
|
959 |
+
"name": "sebastian/environment",
|
960 |
+
"version": "1.3.8",
|
961 |
+
"source": {
|
962 |
+
"type": "git",
|
963 |
+
"url": "https://github.com/sebastianbergmann/environment.git",
|
964 |
+
"reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
|
965 |
+
},
|
966 |
+
"dist": {
|
967 |
+
"type": "zip",
|
968 |
+
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
|
969 |
+
"reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
|
970 |
+
"shasum": ""
|
971 |
+
},
|
972 |
+
"require": {
|
973 |
+
"php": "^5.3.3 || ^7.0"
|
974 |
+
},
|
975 |
+
"require-dev": {
|
976 |
+
"phpunit/phpunit": "^4.8 || ^5.0"
|
977 |
+
},
|
978 |
+
"type": "library",
|
979 |
+
"extra": {
|
980 |
+
"branch-alias": {
|
981 |
+
"dev-master": "1.3.x-dev"
|
982 |
+
}
|
983 |
+
},
|
984 |
+
"autoload": {
|
985 |
+
"classmap": [
|
986 |
+
"src/"
|
987 |
+
]
|
988 |
+
},
|
989 |
+
"notification-url": "https://packagist.org/downloads/",
|
990 |
+
"license": [
|
991 |
+
"BSD-3-Clause"
|
992 |
+
],
|
993 |
+
"authors": [
|
994 |
+
{
|
995 |
+
"name": "Sebastian Bergmann",
|
996 |
+
"email": "sebastian@phpunit.de"
|
997 |
+
}
|
998 |
+
],
|
999 |
+
"description": "Provides functionality to handle HHVM/PHP environments",
|
1000 |
+
"homepage": "http://www.github.com/sebastianbergmann/environment",
|
1001 |
+
"keywords": [
|
1002 |
+
"Xdebug",
|
1003 |
+
"environment",
|
1004 |
+
"hhvm"
|
1005 |
+
],
|
1006 |
+
"time": "2016-08-18T05:49:44+00:00"
|
1007 |
+
},
|
1008 |
+
{
|
1009 |
+
"name": "sebastian/exporter",
|
1010 |
+
"version": "1.2.2",
|
1011 |
+
"source": {
|
1012 |
+
"type": "git",
|
1013 |
+
"url": "https://github.com/sebastianbergmann/exporter.git",
|
1014 |
+
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
|
1015 |
+
},
|
1016 |
+
"dist": {
|
1017 |
+
"type": "zip",
|
1018 |
+
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
|
1019 |
+
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
|
1020 |
+
"shasum": ""
|
1021 |
+
},
|
1022 |
+
"require": {
|
1023 |
+
"php": ">=5.3.3",
|
1024 |
+
"sebastian/recursion-context": "~1.0"
|
1025 |
+
},
|
1026 |
+
"require-dev": {
|
1027 |
+
"ext-mbstring": "*",
|
1028 |
+
"phpunit/phpunit": "~4.4"
|
1029 |
+
},
|
1030 |
+
"type": "library",
|
1031 |
+
"extra": {
|
1032 |
+
"branch-alias": {
|
1033 |
+
"dev-master": "1.3.x-dev"
|
1034 |
+
}
|
1035 |
+
},
|
1036 |
+
"autoload": {
|
1037 |
+
"classmap": [
|
1038 |
+
"src/"
|
1039 |
+
]
|
1040 |
+
},
|
1041 |
+
"notification-url": "https://packagist.org/downloads/",
|
1042 |
+
"license": [
|
1043 |
+
"BSD-3-Clause"
|
1044 |
+
],
|
1045 |
+
"authors": [
|
1046 |
+
{
|
1047 |
+
"name": "Jeff Welch",
|
1048 |
+
"email": "whatthejeff@gmail.com"
|
1049 |
+
},
|
1050 |
+
{
|
1051 |
+
"name": "Volker Dusch",
|
1052 |
+
"email": "github@wallbash.com"
|
1053 |
+
},
|
1054 |
+
{
|
1055 |
+
"name": "Bernhard Schussek",
|
1056 |
+
"email": "bschussek@2bepublished.at"
|
1057 |
+
},
|
1058 |
+
{
|
1059 |
+
"name": "Sebastian Bergmann",
|
1060 |
+
"email": "sebastian@phpunit.de"
|
1061 |
+
},
|
1062 |
+
{
|
1063 |
+
"name": "Adam Harvey",
|
1064 |
+
"email": "aharvey@php.net"
|
1065 |
+
}
|
1066 |
+
],
|
1067 |
+
"description": "Provides the functionality to export PHP variables for visualization",
|
1068 |
+
"homepage": "http://www.github.com/sebastianbergmann/exporter",
|
1069 |
+
"keywords": [
|
1070 |
+
"export",
|
1071 |
+
"exporter"
|
1072 |
+
],
|
1073 |
+
"time": "2016-06-17T09:04:28+00:00"
|
1074 |
+
},
|
1075 |
+
{
|
1076 |
+
"name": "sebastian/global-state",
|
1077 |
+
"version": "1.1.1",
|
1078 |
+
"source": {
|
1079 |
+
"type": "git",
|
1080 |
+
"url": "https://github.com/sebastianbergmann/global-state.git",
|
1081 |
+
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
|
1082 |
+
},
|
1083 |
+
"dist": {
|
1084 |
+
"type": "zip",
|
1085 |
+
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
|
1086 |
+
"reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
|
1087 |
+
"shasum": ""
|
1088 |
+
},
|
1089 |
+
"require": {
|
1090 |
+
"php": ">=5.3.3"
|
1091 |
+
},
|
1092 |
+
"require-dev": {
|
1093 |
+
"phpunit/phpunit": "~4.2"
|
1094 |
+
},
|
1095 |
+
"suggest": {
|
1096 |
+
"ext-uopz": "*"
|
1097 |
+
},
|
1098 |
+
"type": "library",
|
1099 |
+
"extra": {
|
1100 |
+
"branch-alias": {
|
1101 |
+
"dev-master": "1.0-dev"
|
1102 |
+
}
|
1103 |
+
},
|
1104 |
+
"autoload": {
|
1105 |
+
"classmap": [
|
1106 |
+
"src/"
|
1107 |
+
]
|
1108 |
+
},
|
1109 |
+
"notification-url": "https://packagist.org/downloads/",
|
1110 |
+
"license": [
|
1111 |
+
"BSD-3-Clause"
|
1112 |
+
],
|
1113 |
+
"authors": [
|
1114 |
+
{
|
1115 |
+
"name": "Sebastian Bergmann",
|
1116 |
+
"email": "sebastian@phpunit.de"
|
1117 |
+
}
|
1118 |
+
],
|
1119 |
+
"description": "Snapshotting of global state",
|
1120 |
+
"homepage": "http://www.github.com/sebastianbergmann/global-state",
|
1121 |
+
"keywords": [
|
1122 |
+
"global state"
|
1123 |
+
],
|
1124 |
+
"time": "2015-10-12T03:26:01+00:00"
|
1125 |
+
},
|
1126 |
+
{
|
1127 |
+
"name": "sebastian/recursion-context",
|
1128 |
+
"version": "1.0.5",
|
1129 |
+
"source": {
|
1130 |
+
"type": "git",
|
1131 |
+
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
1132 |
+
"reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
|
1133 |
+
},
|
1134 |
+
"dist": {
|
1135 |
+
"type": "zip",
|
1136 |
+
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
|
1137 |
+
"reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
|
1138 |
+
"shasum": ""
|
1139 |
+
},
|
1140 |
+
"require": {
|
1141 |
+
"php": ">=5.3.3"
|
1142 |
+
},
|
1143 |
+
"require-dev": {
|
1144 |
+
"phpunit/phpunit": "~4.4"
|
1145 |
+
},
|
1146 |
+
"type": "library",
|
1147 |
+
"extra": {
|
1148 |
+
"branch-alias": {
|
1149 |
+
"dev-master": "1.0.x-dev"
|
1150 |
+
}
|
1151 |
+
},
|
1152 |
+
"autoload": {
|
1153 |
+
"classmap": [
|
1154 |
+
"src/"
|
1155 |
+
]
|
1156 |
+
},
|
1157 |
+
"notification-url": "https://packagist.org/downloads/",
|
1158 |
+
"license": [
|
1159 |
+
"BSD-3-Clause"
|
1160 |
+
],
|
1161 |
+
"authors": [
|
1162 |
+
{
|
1163 |
+
"name": "Jeff Welch",
|
1164 |
+
"email": "whatthejeff@gmail.com"
|
1165 |
+
},
|
1166 |
+
{
|
1167 |
+
"name": "Sebastian Bergmann",
|
1168 |
+
"email": "sebastian@phpunit.de"
|
1169 |
+
},
|
1170 |
+
{
|
1171 |
+
"name": "Adam Harvey",
|
1172 |
+
"email": "aharvey@php.net"
|
1173 |
+
}
|
1174 |
+
],
|
1175 |
+
"description": "Provides functionality to recursively process PHP variables",
|
1176 |
+
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
1177 |
+
"time": "2016-10-03T07:41:43+00:00"
|
1178 |
+
},
|
1179 |
+
{
|
1180 |
+
"name": "sebastian/version",
|
1181 |
+
"version": "1.0.6",
|
1182 |
+
"source": {
|
1183 |
+
"type": "git",
|
1184 |
+
"url": "https://github.com/sebastianbergmann/version.git",
|
1185 |
+
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
|
1186 |
+
},
|
1187 |
+
"dist": {
|
1188 |
+
"type": "zip",
|
1189 |
+
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
|
1190 |
+
"reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
|
1191 |
+
"shasum": ""
|
1192 |
+
},
|
1193 |
+
"type": "library",
|
1194 |
+
"autoload": {
|
1195 |
+
"classmap": [
|
1196 |
+
"src/"
|
1197 |
+
]
|
1198 |
+
},
|
1199 |
+
"notification-url": "https://packagist.org/downloads/",
|
1200 |
+
"license": [
|
1201 |
+
"BSD-3-Clause"
|
1202 |
+
],
|
1203 |
+
"authors": [
|
1204 |
+
{
|
1205 |
+
"name": "Sebastian Bergmann",
|
1206 |
+
"email": "sebastian@phpunit.de",
|
1207 |
+
"role": "lead"
|
1208 |
+
}
|
1209 |
+
],
|
1210 |
+
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
1211 |
+
"homepage": "https://github.com/sebastianbergmann/version",
|
1212 |
+
"time": "2015-06-21T13:59:46+00:00"
|
1213 |
+
},
|
1214 |
+
{
|
1215 |
+
"name": "symfony/yaml",
|
1216 |
+
"version": "v3.2.8",
|
1217 |
+
"source": {
|
1218 |
+
"type": "git",
|
1219 |
+
"url": "https://github.com/symfony/yaml.git",
|
1220 |
+
"reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6"
|
1221 |
+
},
|
1222 |
+
"dist": {
|
1223 |
+
"type": "zip",
|
1224 |
+
"url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6",
|
1225 |
+
"reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6",
|
1226 |
+
"shasum": ""
|
1227 |
+
},
|
1228 |
+
"require": {
|
1229 |
+
"php": ">=5.5.9"
|
1230 |
+
},
|
1231 |
+
"require-dev": {
|
1232 |
+
"symfony/console": "~2.8|~3.0"
|
1233 |
+
},
|
1234 |
+
"suggest": {
|
1235 |
+
"symfony/console": "For validating YAML files using the lint command"
|
1236 |
+
},
|
1237 |
+
"type": "library",
|
1238 |
+
"extra": {
|
1239 |
+
"branch-alias": {
|
1240 |
+
"dev-master": "3.2-dev"
|
1241 |
+
}
|
1242 |
+
},
|
1243 |
+
"autoload": {
|
1244 |
+
"psr-4": {
|
1245 |
+
"Symfony\\Component\\Yaml\\": ""
|
1246 |
+
},
|
1247 |
+
"exclude-from-classmap": [
|
1248 |
+
"/Tests/"
|
1249 |
+
]
|
1250 |
+
},
|
1251 |
+
"notification-url": "https://packagist.org/downloads/",
|
1252 |
+
"license": [
|
1253 |
+
"MIT"
|
1254 |
+
],
|
1255 |
+
"authors": [
|
1256 |
+
{
|
1257 |
+
"name": "Fabien Potencier",
|
1258 |
+
"email": "fabien@symfony.com"
|
1259 |
+
},
|
1260 |
+
{
|
1261 |
+
"name": "Symfony Community",
|
1262 |
+
"homepage": "https://symfony.com/contributors"
|
1263 |
+
}
|
1264 |
+
],
|
1265 |
+
"description": "Symfony Yaml Component",
|
1266 |
+
"homepage": "https://symfony.com",
|
1267 |
+
"time": "2017-05-01T14:55:58+00:00"
|
1268 |
+
},
|
1269 |
+
{
|
1270 |
+
"name": "webmozart/assert",
|
1271 |
+
"version": "1.2.0",
|
1272 |
+
"source": {
|
1273 |
+
"type": "git",
|
1274 |
+
"url": "https://github.com/webmozart/assert.git",
|
1275 |
+
"reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f"
|
1276 |
+
},
|
1277 |
+
"dist": {
|
1278 |
+
"type": "zip",
|
1279 |
+
"url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f",
|
1280 |
+
"reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f",
|
1281 |
+
"shasum": ""
|
1282 |
+
},
|
1283 |
+
"require": {
|
1284 |
+
"php": "^5.3.3 || ^7.0"
|
1285 |
+
},
|
1286 |
+
"require-dev": {
|
1287 |
+
"phpunit/phpunit": "^4.6",
|
1288 |
+
"sebastian/version": "^1.0.1"
|
1289 |
+
},
|
1290 |
+
"type": "library",
|
1291 |
+
"extra": {
|
1292 |
+
"branch-alias": {
|
1293 |
+
"dev-master": "1.3-dev"
|
1294 |
+
}
|
1295 |
+
},
|
1296 |
+
"autoload": {
|
1297 |
+
"psr-4": {
|
1298 |
+
"Webmozart\\Assert\\": "src/"
|
1299 |
+
}
|
1300 |
+
},
|
1301 |
+
"notification-url": "https://packagist.org/downloads/",
|
1302 |
+
"license": [
|
1303 |
+
"MIT"
|
1304 |
+
],
|
1305 |
+
"authors": [
|
1306 |
+
{
|
1307 |
+
"name": "Bernhard Schussek",
|
1308 |
+
"email": "bschussek@gmail.com"
|
1309 |
+
}
|
1310 |
+
],
|
1311 |
+
"description": "Assertions to validate method input/output with nice error messages.",
|
1312 |
+
"keywords": [
|
1313 |
+
"assert",
|
1314 |
+
"check",
|
1315 |
+
"validate"
|
1316 |
+
],
|
1317 |
+
"time": "2016-11-23T20:04:58+00:00"
|
1318 |
+
}
|
1319 |
+
],
|
1320 |
+
"aliases": [],
|
1321 |
+
"minimum-stability": "stable",
|
1322 |
+
"stability-flags": [],
|
1323 |
+
"prefer-stable": false,
|
1324 |
+
"prefer-lowest": false,
|
1325 |
+
"platform": {
|
1326 |
+
"php": "^5.4 || ^7.0"
|
1327 |
+
},
|
1328 |
+
"platform-dev": []
|
1329 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/example-override-styling.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
|
10 |
+
require_once __DIR__ . '/../vendor/autoload.php';
|
11 |
+
|
12 |
+
use Facebook\InstantArticles\AMP\AMPArticle;
|
13 |
+
|
14 |
+
// Prevents the logger from dumping too much info, check the file for details
|
15 |
+
include __DIR__ . '/quiet_logger.php';
|
16 |
+
|
17 |
+
// Load instant article file into string
|
18 |
+
$instant_article_string = file_get_contents(__DIR__.'/instant-article-example.html');
|
19 |
+
|
20 |
+
// Loads from a file or even you could load from the graph API style Editor.
|
21 |
+
$styleGotFromSomewhereElse = file_get_contents(__DIR__.'/styles/style-got-from-somewhereelse.json');
|
22 |
+
|
23 |
+
$properties = array(
|
24 |
+
// Overrides any style linked from the Instant Article, this might be useful if you want to apply a different style than the one in specified Instant Articles.
|
25 |
+
'override-styles' => json_decode($styleGotFromSomewhereElse, true)
|
26 |
+
);
|
27 |
+
|
28 |
+
// Converts it into AMP
|
29 |
+
$amp_string = AMPArticle::create($instant_article_string, $properties)->render();
|
30 |
+
|
31 |
+
print($amp_string);
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/example-quick-start.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
|
10 |
+
require_once __DIR__ . '/../vendor/autoload.php';
|
11 |
+
|
12 |
+
// Prevents the logger from dumping too much info, check the file for details
|
13 |
+
include __DIR__ . '/quiet_logger.php';
|
14 |
+
|
15 |
+
use Facebook\InstantArticles\AMP\AMPArticle;
|
16 |
+
|
17 |
+
// Load instant article file into string
|
18 |
+
$instant_article_string = file_get_contents(__DIR__.'/instant-article-example.html');
|
19 |
+
|
20 |
+
// Instant articles have no width and height information for images and video on
|
21 |
+
// it's markup but the AMP spec requires everything to have explicit sizing.
|
22 |
+
|
23 |
+
// This will hold our custom properties
|
24 |
+
$properties = array();
|
25 |
+
|
26 |
+
// Videos require explicit sizing, if you fail to provide it, the default values
|
27 |
+
// may distort your Videos
|
28 |
+
$properties[AMPArticle::MEDIA_SIZES_KEY]
|
29 |
+
['http://mydomain.com/path/to/video.mp4'] = array(320, 240);
|
30 |
+
|
31 |
+
// Images can also be passed
|
32 |
+
// IMPORTANT: The image will not have fixed-width, but it will respect the
|
33 |
+
// aspect ration provided here. They are using the responsive layout
|
34 |
+
$properties[AMPArticle::MEDIA_SIZES_KEY]
|
35 |
+
['http://mydomain.com/path/to/crazy.jpg'] = array(640, 480);
|
36 |
+
|
37 |
+
// The SDK can automatically download the images and get their sizes if they are not
|
38 |
+
// in the array above, if you enable the following option.
|
39 |
+
//
|
40 |
+
// WARNING: THIS MAY LEAD TO EXCESSIVE DOWNLOADING - USE WITH CAUTION
|
41 |
+
// WE STRONGLY RECOMMEND YOU TO PASS THE IMAGE SIZING VIA THE
|
42 |
+
// $properties[AMPArticle::MEDIA_SIZES_KEY] ARRAY
|
43 |
+
//
|
44 |
+
// You can check in the markup that the image fb_icon_325x325.png
|
45 |
+
// has the correct 325x325 size after enabling this option.
|
46 |
+
$properties[AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY] = true;
|
47 |
+
|
48 |
+
// AMP has its own format for setting tracking pixels and/or analytics calls.
|
49 |
+
// You can provide a list of one or more strings containing the markup for
|
50 |
+
// the <amp-analytics> or <amp pixel> tags to the following option.
|
51 |
+
//
|
52 |
+
// See also the AMP specs for these tags:
|
53 |
+
// - https://www.ampproject.org/docs/reference/components/amp-analytics
|
54 |
+
// - https://www.ampproject.org/docs/reference/components/amp-pixel
|
55 |
+
$properties[AMPArticle::ANALYTICS_KEY] = array(
|
56 |
+
'<amp-pixel src="http://mydomain.com/my_tracking_pixel.gif">',
|
57 |
+
'<amp-analytics config="https://mydomain.com/analytics.config.json"></amp-analytics>'
|
58 |
+
);
|
59 |
+
|
60 |
+
// Converts it into AMP
|
61 |
+
$amp_string =
|
62 |
+
AMPArticle::create($instant_article_string, $properties)->render();
|
63 |
+
|
64 |
+
print($amp_string);
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/example-simple-styling.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
|
10 |
+
require_once __DIR__ . '/../vendor/autoload.php';
|
11 |
+
|
12 |
+
use Facebook\InstantArticles\AMP\AMPArticle;
|
13 |
+
|
14 |
+
// Prevents the logger from dumping too much info, check the file for details
|
15 |
+
include __DIR__ . '/quiet_logger.php';
|
16 |
+
|
17 |
+
// Load instant article file into string
|
18 |
+
$instant_article_string = file_get_contents(__DIR__.'/instant-article-example.html');
|
19 |
+
$properties = array(
|
20 |
+
'lang' => 'en-US', // You can set the language your article have
|
21 |
+
'styles-folder' => __DIR__.'/styles' // Where the styles are stored
|
22 |
+
);
|
23 |
+
|
24 |
+
/*
|
25 |
+
As the name of the style used within the Instant article refers to <code>"gray"</code>, the
|
26 |
+
file within directory <code>/styles</code> will be the <code>/styles/gray.style.json.</code>
|
27 |
+
*/
|
28 |
+
|
29 |
+
// Converts it into AMP
|
30 |
+
$amp_string = AMPArticle::create($instant_article_string, $properties)->render();
|
31 |
+
|
32 |
+
print($amp_string);
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/instant-article-example.html
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html>
|
2 |
+
<html lang="en" prefix="op: http://media.facebook.com/op#">
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8">
|
5 |
+
<!-- URL of the web version of this article -->
|
6 |
+
<link rel="canonical" href="http://example.com/article.html">
|
7 |
+
<meta property="op:markup_version" content="v1.0">
|
8 |
+
<meta property="fb:article_style" content="gray">
|
9 |
+
</head>
|
10 |
+
<body>
|
11 |
+
<article>
|
12 |
+
<header>
|
13 |
+
<!-- The title and subtitle shown in your Instant Article -->
|
14 |
+
<h1>Article Title</h1>
|
15 |
+
<h2>Article Subtitle</h2>
|
16 |
+
|
17 |
+
<!-- The date and time when your article was originally published -->
|
18 |
+
<time class="op-published" datetime="2014-11-11T04:44:16Z">November 11th, 4:44 PM</time>
|
19 |
+
|
20 |
+
<!-- The date and time when your article was last updated -->
|
21 |
+
<time class="op-modified" dateTime="2014-12-11T04:44:16Z">December 11th, 4:44 PM</time>
|
22 |
+
|
23 |
+
<!-- The authors of your article -->
|
24 |
+
<address>
|
25 |
+
<a rel="facebook" href="http://facebook.com/brandon.diamond">Brandon Diamond</a>
|
26 |
+
Brandon is an avid zombie hunter.
|
27 |
+
</address>
|
28 |
+
<address>
|
29 |
+
<a>TR Vishwanath</a>
|
30 |
+
Vish is a scholar and a gentleman.
|
31 |
+
</address>
|
32 |
+
|
33 |
+
<!-- The cover image shown inside your article -->
|
34 |
+
<figure>
|
35 |
+
<img src="http://mydomain.com/path/to/cover_img.jpg" />
|
36 |
+
<figcaption>This image is amazing</figcaption>
|
37 |
+
</figure>
|
38 |
+
|
39 |
+
<!-- A kicker for your article -->
|
40 |
+
<h3 class="op-kicker">
|
41 |
+
This is a kicker
|
42 |
+
</h3>
|
43 |
+
|
44 |
+
</header>
|
45 |
+
|
46 |
+
<!-- Article body goes here -->
|
47 |
+
|
48 |
+
<!-- Body text for your article -->
|
49 |
+
<p> Article content </p>
|
50 |
+
|
51 |
+
<!-- A video within your article -->
|
52 |
+
<figure>
|
53 |
+
<video>
|
54 |
+
<source src="http://mydomain.com/path/to/video.mp4" type="video/mp4" />
|
55 |
+
</video>
|
56 |
+
</figure>
|
57 |
+
|
58 |
+
<!-- An ad within your article -->
|
59 |
+
<figure class="op-ad">
|
60 |
+
<iframe src="https://www.adserver.com/ss;adtype=banner320x50" height="60" width="320"></iframe>
|
61 |
+
</figure>
|
62 |
+
|
63 |
+
<!-- Image hotlinked from some other domain -->
|
64 |
+
<figure>
|
65 |
+
<img src="https://www.facebook.com/images/fb_icon_325x325.png" />
|
66 |
+
<figcaption>Like it!</figcaption>
|
67 |
+
</figure>
|
68 |
+
|
69 |
+
<!-- Image -->
|
70 |
+
<figure>
|
71 |
+
<img src="http://mydomain.com/path/to/crazy.jpg" />
|
72 |
+
<figcaption>This is crazy</figcaption>
|
73 |
+
</figure>
|
74 |
+
|
75 |
+
<!-- Analytics code for your article -->
|
76 |
+
<figure class="op-tracker">
|
77 |
+
<iframe src="" hidden></iframe>
|
78 |
+
</figure>
|
79 |
+
|
80 |
+
<footer>
|
81 |
+
<!-- Credits for your article -->
|
82 |
+
<aside>Acknowledgements</aside>
|
83 |
+
|
84 |
+
<!-- Copyright details for your article -->
|
85 |
+
<small>Legal notes</small>
|
86 |
+
</footer>
|
87 |
+
</article>
|
88 |
+
</body>
|
89 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/quiet_logger.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
\Logger::configure(
|
4 |
+
[
|
5 |
+
'rootLogger' => [
|
6 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
7 |
+
],
|
8 |
+
'appenders' => [
|
9 |
+
'facebook-instantarticles-traverser' => [
|
10 |
+
'class' => 'LoggerAppenderConsole',
|
11 |
+
'threshold' => 'INFO',
|
12 |
+
'layout' => [
|
13 |
+
'class' => 'LoggerLayoutSimple'
|
14 |
+
]
|
15 |
+
]
|
16 |
+
]
|
17 |
+
]
|
18 |
+
);
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/styles/gray.style.json
ADDED
@@ -0,0 +1,993 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"background_color": "#EEEEEE",
|
3 |
+
"header": {
|
4 |
+
"logo": {
|
5 |
+
"dataURL": null,
|
6 |
+
"id": "1229084557204785",
|
7 |
+
"full_resolution_url": "https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8",
|
8 |
+
"full_resolution_width": 2600,
|
9 |
+
"full_resolution_height": 512,
|
10 |
+
"thumbnail_url": "https://fb-s-d-a.akamaihd.net/h-ak-xpf1/v/t39.5687-6/17634152_1374280939304404_1278222734471462912_n.png?_nc_log=1&oh=d3e95b10e960a9527ad643c47d821160&oe=598664D5&__gda__=1498346669_5ee6f5a2bd8d17474bfb46398d9b888a",
|
11 |
+
"article_scaling_factor": 1
|
12 |
+
},
|
13 |
+
"logo_scale": 1,
|
14 |
+
"accent_color": "#000000",
|
15 |
+
"background_color": "#666666",
|
16 |
+
"bar_color": null
|
17 |
+
},
|
18 |
+
"kicker": {
|
19 |
+
"font": "Helvetica Neue",
|
20 |
+
"color": "#000000",
|
21 |
+
"background_color": "#00FFFFFF",
|
22 |
+
"capitalization": "ALL_CAPS",
|
23 |
+
"text_alignment": "LEFT",
|
24 |
+
"display": "INLINE",
|
25 |
+
"line_height_scale": 1,
|
26 |
+
"text_size_scale": 1,
|
27 |
+
"margin": {
|
28 |
+
"right": {
|
29 |
+
"scaling_factor": 1,
|
30 |
+
"size": "DOCUMENT_MARGIN"
|
31 |
+
},
|
32 |
+
"left": {
|
33 |
+
"scaling_factor": 1,
|
34 |
+
"size": "DOCUMENT_MARGIN"
|
35 |
+
}
|
36 |
+
},
|
37 |
+
"border": {
|
38 |
+
"top": {
|
39 |
+
"width": 0
|
40 |
+
},
|
41 |
+
"right": {
|
42 |
+
"width": 0
|
43 |
+
},
|
44 |
+
"bottom": {
|
45 |
+
"width": 0
|
46 |
+
},
|
47 |
+
"left": {
|
48 |
+
"width": 0
|
49 |
+
}
|
50 |
+
},
|
51 |
+
"padding": {
|
52 |
+
"top": {
|
53 |
+
"scaling_factor": 1,
|
54 |
+
"size": "NONE"
|
55 |
+
},
|
56 |
+
"right": {
|
57 |
+
"scaling_factor": 1,
|
58 |
+
"size": "NONE"
|
59 |
+
},
|
60 |
+
"bottom": {
|
61 |
+
"scaling_factor": 1,
|
62 |
+
"size": "NONE"
|
63 |
+
},
|
64 |
+
"left": {
|
65 |
+
"scaling_factor": 1,
|
66 |
+
"size": "NONE"
|
67 |
+
}
|
68 |
+
}
|
69 |
+
},
|
70 |
+
"title": {
|
71 |
+
"font": "Georgia",
|
72 |
+
"color": "#000000",
|
73 |
+
"background_color": "#00FFFFFF",
|
74 |
+
"capitalization": "NONE",
|
75 |
+
"text_alignment": "LEFT",
|
76 |
+
"display": "INLINE",
|
77 |
+
"line_height_scale": 1,
|
78 |
+
"text_size_scale": 1,
|
79 |
+
"margin": {
|
80 |
+
"right": {
|
81 |
+
"scaling_factor": 1,
|
82 |
+
"size": "DOCUMENT_MARGIN"
|
83 |
+
},
|
84 |
+
"left": {
|
85 |
+
"scaling_factor": 1,
|
86 |
+
"size": "DOCUMENT_MARGIN"
|
87 |
+
}
|
88 |
+
},
|
89 |
+
"border": {
|
90 |
+
"top": {
|
91 |
+
"width": 0
|
92 |
+
},
|
93 |
+
"right": {
|
94 |
+
"width": 0
|
95 |
+
},
|
96 |
+
"bottom": {
|
97 |
+
"width": 0
|
98 |
+
},
|
99 |
+
"left": {
|
100 |
+
"width": 0
|
101 |
+
}
|
102 |
+
},
|
103 |
+
"padding": {
|
104 |
+
"top": {
|
105 |
+
"scaling_factor": 1,
|
106 |
+
"size": "NONE"
|
107 |
+
},
|
108 |
+
"right": {
|
109 |
+
"scaling_factor": 1,
|
110 |
+
"size": "NONE"
|
111 |
+
},
|
112 |
+
"bottom": {
|
113 |
+
"scaling_factor": 1,
|
114 |
+
"size": "NONE"
|
115 |
+
},
|
116 |
+
"left": {
|
117 |
+
"scaling_factor": 1,
|
118 |
+
"size": "NONE"
|
119 |
+
}
|
120 |
+
}
|
121 |
+
},
|
122 |
+
"subtitle": {
|
123 |
+
"font": "Georgia",
|
124 |
+
"color": "#000000",
|
125 |
+
"background_color": "#00FFFFFF",
|
126 |
+
"capitalization": "NONE",
|
127 |
+
"text_alignment": "LEFT",
|
128 |
+
"display": "INLINE",
|
129 |
+
"line_height_scale": 1,
|
130 |
+
"text_size_scale": 1,
|
131 |
+
"margin": {
|
132 |
+
"right": {
|
133 |
+
"scaling_factor": 1,
|
134 |
+
"size": "DOCUMENT_MARGIN"
|
135 |
+
},
|
136 |
+
"left": {
|
137 |
+
"scaling_factor": 1,
|
138 |
+
"size": "DOCUMENT_MARGIN"
|
139 |
+
}
|
140 |
+
},
|
141 |
+
"border": {
|
142 |
+
"top": {
|
143 |
+
"width": 0
|
144 |
+
},
|
145 |
+
"right": {
|
146 |
+
"width": 0
|
147 |
+
},
|
148 |
+
"bottom": {
|
149 |
+
"width": 0
|
150 |
+
},
|
151 |
+
"left": {
|
152 |
+
"width": 0
|
153 |
+
}
|
154 |
+
},
|
155 |
+
"padding": {
|
156 |
+
"top": {
|
157 |
+
"scaling_factor": 1,
|
158 |
+
"size": "NONE"
|
159 |
+
},
|
160 |
+
"right": {
|
161 |
+
"scaling_factor": 1,
|
162 |
+
"size": "NONE"
|
163 |
+
},
|
164 |
+
"bottom": {
|
165 |
+
"scaling_factor": 1,
|
166 |
+
"size": "NONE"
|
167 |
+
},
|
168 |
+
"left": {
|
169 |
+
"scaling_factor": 1,
|
170 |
+
"size": "NONE"
|
171 |
+
}
|
172 |
+
}
|
173 |
+
},
|
174 |
+
"byline": {
|
175 |
+
"font": "Helvetica Neue",
|
176 |
+
"color": "#000000",
|
177 |
+
"capitalization": "ALL_CAPS",
|
178 |
+
"text_alignment": "LEFT",
|
179 |
+
"line_height_scale": 1,
|
180 |
+
"text_size_scale": 1,
|
181 |
+
"margin": {
|
182 |
+
"right": {
|
183 |
+
"scaling_factor": 1,
|
184 |
+
"size": "DOCUMENT_MARGIN"
|
185 |
+
},
|
186 |
+
"left": {
|
187 |
+
"scaling_factor": 1,
|
188 |
+
"size": "DOCUMENT_MARGIN"
|
189 |
+
}
|
190 |
+
}
|
191 |
+
},
|
192 |
+
"date_style": "MONTH_DAY_YEAR",
|
193 |
+
"primary_heading": {
|
194 |
+
"font": "Georgia",
|
195 |
+
"color": "#000000",
|
196 |
+
"background_color": "#00FFFFFF",
|
197 |
+
"capitalization": "NONE",
|
198 |
+
"text_alignment": "LEFT",
|
199 |
+
"display": "INLINE",
|
200 |
+
"line_height_scale": 1,
|
201 |
+
"text_size_scale": 1,
|
202 |
+
"margin": {
|
203 |
+
"right": {
|
204 |
+
"scaling_factor": 1,
|
205 |
+
"size": "DOCUMENT_MARGIN"
|
206 |
+
},
|
207 |
+
"left": {
|
208 |
+
"scaling_factor": 1,
|
209 |
+
"size": "DOCUMENT_MARGIN"
|
210 |
+
}
|
211 |
+
},
|
212 |
+
"border": {
|
213 |
+
"top": {
|
214 |
+
"width": 0
|
215 |
+
},
|
216 |
+
"right": {
|
217 |
+
"width": 0
|
218 |
+
},
|
219 |
+
"bottom": {
|
220 |
+
"width": 0
|
221 |
+
},
|
222 |
+
"left": {
|
223 |
+
"width": 0
|
224 |
+
}
|
225 |
+
},
|
226 |
+
"padding": {
|
227 |
+
"top": {
|
228 |
+
"scaling_factor": 1,
|
229 |
+
"size": "NONE"
|
230 |
+
},
|
231 |
+
"right": {
|
232 |
+
"scaling_factor": 1,
|
233 |
+
"size": "NONE"
|
234 |
+
},
|
235 |
+
"bottom": {
|
236 |
+
"scaling_factor": 1,
|
237 |
+
"size": "NONE"
|
238 |
+
},
|
239 |
+
"left": {
|
240 |
+
"scaling_factor": 1,
|
241 |
+
"size": "NONE"
|
242 |
+
}
|
243 |
+
}
|
244 |
+
},
|
245 |
+
"secondary_heading": {
|
246 |
+
"font": "Georgia",
|
247 |
+
"color": "#000000",
|
248 |
+
"background_color": "#00FFFFFF",
|
249 |
+
"capitalization": "NONE",
|
250 |
+
"text_alignment": "LEFT",
|
251 |
+
"display": "INLINE",
|
252 |
+
"line_height_scale": 1,
|
253 |
+
"text_size_scale": 1,
|
254 |
+
"margin": {
|
255 |
+
"right": {
|
256 |
+
"scaling_factor": 1,
|
257 |
+
"size": "DOCUMENT_MARGIN"
|
258 |
+
},
|
259 |
+
"left": {
|
260 |
+
"scaling_factor": 1,
|
261 |
+
"size": "DOCUMENT_MARGIN"
|
262 |
+
}
|
263 |
+
},
|
264 |
+
"border": {
|
265 |
+
"top": {
|
266 |
+
"width": 0
|
267 |
+
},
|
268 |
+
"right": {
|
269 |
+
"width": 0
|
270 |
+
},
|
271 |
+
"bottom": {
|
272 |
+
"width": 0
|
273 |
+
},
|
274 |
+
"left": {
|
275 |
+
"width": 0
|
276 |
+
}
|
277 |
+
},
|
278 |
+
"padding": {
|
279 |
+
"top": {
|
280 |
+
"scaling_factor": 1,
|
281 |
+
"size": "NONE"
|
282 |
+
},
|
283 |
+
"right": {
|
284 |
+
"scaling_factor": 1,
|
285 |
+
"size": "NONE"
|
286 |
+
},
|
287 |
+
"bottom": {
|
288 |
+
"scaling_factor": 1,
|
289 |
+
"size": "NONE"
|
290 |
+
},
|
291 |
+
"left": {
|
292 |
+
"scaling_factor": 1,
|
293 |
+
"size": "NONE"
|
294 |
+
}
|
295 |
+
}
|
296 |
+
},
|
297 |
+
"body_text": {
|
298 |
+
"font": "Georgia",
|
299 |
+
"color": "#000000",
|
300 |
+
"capitalization": "NONE",
|
301 |
+
"text_alignment": "LEFT",
|
302 |
+
"line_height_scale": 1,
|
303 |
+
"text_size_scale": 1,
|
304 |
+
"margin": {
|
305 |
+
"right": {
|
306 |
+
"scaling_factor": 1,
|
307 |
+
"size": "DOCUMENT_MARGIN"
|
308 |
+
},
|
309 |
+
"left": {
|
310 |
+
"scaling_factor": 1,
|
311 |
+
"size": "DOCUMENT_MARGIN"
|
312 |
+
}
|
313 |
+
}
|
314 |
+
},
|
315 |
+
"inline_link": {
|
316 |
+
"color": "#000000",
|
317 |
+
"underline": "SIMPLE_UNDERLINE",
|
318 |
+
"font": "Georgia"
|
319 |
+
},
|
320 |
+
"block_quote": {
|
321 |
+
"font": "Georgia",
|
322 |
+
"color": "#000000",
|
323 |
+
"background_color": "#00FFFFFF",
|
324 |
+
"capitalization": "NONE",
|
325 |
+
"text_alignment": "LEFT",
|
326 |
+
"display": "BLOCK",
|
327 |
+
"line_height_scale": 1,
|
328 |
+
"text_size_scale": 1,
|
329 |
+
"margin": {
|
330 |
+
"right": {
|
331 |
+
"scaling_factor": 1,
|
332 |
+
"size": "DOCUMENT_MARGIN"
|
333 |
+
},
|
334 |
+
"left": {
|
335 |
+
"scaling_factor": 1,
|
336 |
+
"size": "DOCUMENT_MARGIN"
|
337 |
+
}
|
338 |
+
},
|
339 |
+
"border": {
|
340 |
+
"top": {
|
341 |
+
"color": "#000000",
|
342 |
+
"width": 0
|
343 |
+
},
|
344 |
+
"right": {
|
345 |
+
"color": "#000000",
|
346 |
+
"width": 0
|
347 |
+
},
|
348 |
+
"bottom": {
|
349 |
+
"color": "#000000",
|
350 |
+
"width": 0
|
351 |
+
},
|
352 |
+
"left": {
|
353 |
+
"color": "#000000",
|
354 |
+
"width": 2
|
355 |
+
}
|
356 |
+
},
|
357 |
+
"padding": {
|
358 |
+
"top": {
|
359 |
+
"scaling_factor": 1,
|
360 |
+
"size": "NONE"
|
361 |
+
},
|
362 |
+
"right": {
|
363 |
+
"scaling_factor": 1,
|
364 |
+
"size": "SMALL"
|
365 |
+
},
|
366 |
+
"bottom": {
|
367 |
+
"scaling_factor": 1,
|
368 |
+
"size": "NONE"
|
369 |
+
},
|
370 |
+
"left": {
|
371 |
+
"scaling_factor": 1,
|
372 |
+
"size": "MEDIUM"
|
373 |
+
}
|
374 |
+
}
|
375 |
+
},
|
376 |
+
"pull_quote": {
|
377 |
+
"font": "Georgia",
|
378 |
+
"color": "#000000",
|
379 |
+
"background_color": "#00FFFFFF",
|
380 |
+
"capitalization": "NONE",
|
381 |
+
"text_alignment": "LEFT",
|
382 |
+
"display": "INLINE",
|
383 |
+
"line_height_scale": 1,
|
384 |
+
"text_size_scale": 1,
|
385 |
+
"margin": {
|
386 |
+
"right": {
|
387 |
+
"scaling_factor": 1,
|
388 |
+
"size": "DOCUMENT_MARGIN"
|
389 |
+
},
|
390 |
+
"left": {
|
391 |
+
"scaling_factor": 1,
|
392 |
+
"size": "DOCUMENT_MARGIN"
|
393 |
+
}
|
394 |
+
},
|
395 |
+
"border": {
|
396 |
+
"top": {
|
397 |
+
"width": 0
|
398 |
+
},
|
399 |
+
"right": {
|
400 |
+
"width": 0
|
401 |
+
},
|
402 |
+
"bottom": {
|
403 |
+
"width": 0
|
404 |
+
},
|
405 |
+
"left": {
|
406 |
+
"width": 0
|
407 |
+
}
|
408 |
+
},
|
409 |
+
"padding": {
|
410 |
+
"top": {
|
411 |
+
"scaling_factor": 1,
|
412 |
+
"size": "NONE"
|
413 |
+
},
|
414 |
+
"right": {
|
415 |
+
"scaling_factor": 1,
|
416 |
+
"size": "NONE"
|
417 |
+
},
|
418 |
+
"bottom": {
|
419 |
+
"scaling_factor": 1,
|
420 |
+
"size": "NONE"
|
421 |
+
},
|
422 |
+
"left": {
|
423 |
+
"scaling_factor": 1,
|
424 |
+
"size": "NONE"
|
425 |
+
}
|
426 |
+
}
|
427 |
+
},
|
428 |
+
"pull_quote_attribution": {
|
429 |
+
"font": "Helvetica Neue",
|
430 |
+
"color": "#000000",
|
431 |
+
"background_color": "#00FFFFFF",
|
432 |
+
"capitalization": "ALL_CAPS",
|
433 |
+
"text_alignment": "LEFT",
|
434 |
+
"display": "INLINE",
|
435 |
+
"line_height_scale": 1,
|
436 |
+
"text_size_scale": 1,
|
437 |
+
"margin": {
|
438 |
+
"right": {
|
439 |
+
"scaling_factor": 1,
|
440 |
+
"size": "DOCUMENT_MARGIN"
|
441 |
+
},
|
442 |
+
"left": {
|
443 |
+
"scaling_factor": 1,
|
444 |
+
"size": "DOCUMENT_MARGIN"
|
445 |
+
}
|
446 |
+
},
|
447 |
+
"border": {
|
448 |
+
"top": {
|
449 |
+
"width": 0
|
450 |
+
},
|
451 |
+
"right": {
|
452 |
+
"width": 0
|
453 |
+
},
|
454 |
+
"bottom": {
|
455 |
+
"width": 0
|
456 |
+
},
|
457 |
+
"left": {
|
458 |
+
"width": 0
|
459 |
+
}
|
460 |
+
},
|
461 |
+
"padding": {
|
462 |
+
"top": {
|
463 |
+
"scaling_factor": 1,
|
464 |
+
"size": "NONE"
|
465 |
+
},
|
466 |
+
"right": {
|
467 |
+
"scaling_factor": 1,
|
468 |
+
"size": "NONE"
|
469 |
+
},
|
470 |
+
"bottom": {
|
471 |
+
"scaling_factor": 1,
|
472 |
+
"size": "NONE"
|
473 |
+
},
|
474 |
+
"left": {
|
475 |
+
"scaling_factor": 1,
|
476 |
+
"size": "NONE"
|
477 |
+
}
|
478 |
+
}
|
479 |
+
},
|
480 |
+
"caption_title_small": {
|
481 |
+
"font": "Helvetica Neue Bold",
|
482 |
+
"color": "#808080",
|
483 |
+
"background_color": "#00FFFF",
|
484 |
+
"capitalization": "NONE",
|
485 |
+
"display": "INLINE",
|
486 |
+
"line_height_scale": 1,
|
487 |
+
"text_size_scale": 1,
|
488 |
+
"margin": {
|
489 |
+
"right": {
|
490 |
+
"scaling_factor": 1,
|
491 |
+
"size": "DOCUMENT_MARGIN"
|
492 |
+
},
|
493 |
+
"left": {
|
494 |
+
"scaling_factor": 1,
|
495 |
+
"size": "DOCUMENT_MARGIN"
|
496 |
+
}
|
497 |
+
},
|
498 |
+
"border": {
|
499 |
+
"top": {
|
500 |
+
"width": 0
|
501 |
+
},
|
502 |
+
"right": {
|
503 |
+
"width": 0
|
504 |
+
},
|
505 |
+
"bottom": {
|
506 |
+
"width": 0
|
507 |
+
},
|
508 |
+
"left": {
|
509 |
+
"width": 0
|
510 |
+
}
|
511 |
+
},
|
512 |
+
"padding": {
|
513 |
+
"top": {
|
514 |
+
"scaling_factor": 1,
|
515 |
+
"size": "NONE"
|
516 |
+
},
|
517 |
+
"right": {
|
518 |
+
"scaling_factor": 1,
|
519 |
+
"size": "NONE"
|
520 |
+
},
|
521 |
+
"bottom": {
|
522 |
+
"scaling_factor": 1,
|
523 |
+
"size": "NONE"
|
524 |
+
},
|
525 |
+
"left": {
|
526 |
+
"scaling_factor": 1,
|
527 |
+
"size": "NONE"
|
528 |
+
}
|
529 |
+
}
|
530 |
+
},
|
531 |
+
"caption_description_small": {
|
532 |
+
"font": "Helvetica Neue",
|
533 |
+
"color": "#808080",
|
534 |
+
"background_color": "#00FFFFFF",
|
535 |
+
"capitalization": "NONE",
|
536 |
+
"display": "INLINE",
|
537 |
+
"line_height_scale": 1,
|
538 |
+
"text_size_scale": 1,
|
539 |
+
"margin": {
|
540 |
+
"right": {
|
541 |
+
"scaling_factor": 1,
|
542 |
+
"size": "DOCUMENT_MARGIN"
|
543 |
+
},
|
544 |
+
"left": {
|
545 |
+
"scaling_factor": 1,
|
546 |
+
"size": "DOCUMENT_MARGIN"
|
547 |
+
}
|
548 |
+
},
|
549 |
+
"border": {
|
550 |
+
"top": {
|
551 |
+
"width": 0
|
552 |
+
},
|
553 |
+
"right": {
|
554 |
+
"width": 0
|
555 |
+
},
|
556 |
+
"bottom": {
|
557 |
+
"width": 0
|
558 |
+
},
|
559 |
+
"left": {
|
560 |
+
"width": 0
|
561 |
+
}
|
562 |
+
},
|
563 |
+
"padding": {
|
564 |
+
"top": {
|
565 |
+
"scaling_factor": 1,
|
566 |
+
"size": "NONE"
|
567 |
+
},
|
568 |
+
"right": {
|
569 |
+
"scaling_factor": 1,
|
570 |
+
"size": "NONE"
|
571 |
+
},
|
572 |
+
"bottom": {
|
573 |
+
"scaling_factor": 1,
|
574 |
+
"size": "NONE"
|
575 |
+
},
|
576 |
+
"left": {
|
577 |
+
"scaling_factor": 1,
|
578 |
+
"size": "NONE"
|
579 |
+
}
|
580 |
+
}
|
581 |
+
},
|
582 |
+
"caption_credit": {
|
583 |
+
"font": "Helvetica Neue",
|
584 |
+
"color": "#BFBFBF",
|
585 |
+
"background_color": "#00FFFFFF",
|
586 |
+
"capitalization": "ALL_CAPS",
|
587 |
+
"display": "INLINE",
|
588 |
+
"line_height_scale": 1,
|
589 |
+
"text_size_scale": 1,
|
590 |
+
"margin": {
|
591 |
+
"right": {
|
592 |
+
"scaling_factor": 1,
|
593 |
+
"size": "DOCUMENT_MARGIN"
|
594 |
+
},
|
595 |
+
"left": {
|
596 |
+
"scaling_factor": 1,
|
597 |
+
"size": "DOCUMENT_MARGIN"
|
598 |
+
}
|
599 |
+
},
|
600 |
+
"border": {
|
601 |
+
"top": {
|
602 |
+
"width": 0
|
603 |
+
},
|
604 |
+
"right": {
|
605 |
+
"width": 0
|
606 |
+
},
|
607 |
+
"bottom": {
|
608 |
+
"width": 0
|
609 |
+
},
|
610 |
+
"left": {
|
611 |
+
"width": 0
|
612 |
+
}
|
613 |
+
},
|
614 |
+
"padding": {
|
615 |
+
"top": {
|
616 |
+
"scaling_factor": 1,
|
617 |
+
"size": "NONE"
|
618 |
+
},
|
619 |
+
"right": {
|
620 |
+
"scaling_factor": 1,
|
621 |
+
"size": "NONE"
|
622 |
+
},
|
623 |
+
"bottom": {
|
624 |
+
"scaling_factor": 1,
|
625 |
+
"size": "NONE"
|
626 |
+
},
|
627 |
+
"left": {
|
628 |
+
"scaling_factor": 1,
|
629 |
+
"size": "NONE"
|
630 |
+
}
|
631 |
+
}
|
632 |
+
},
|
633 |
+
"caption_title": {
|
634 |
+
"font": "Georgia",
|
635 |
+
"color": "#808080",
|
636 |
+
"background_color": "#00FFFFFF",
|
637 |
+
"capitalization": "NONE",
|
638 |
+
"display": "INLINE",
|
639 |
+
"line_height_scale": 1,
|
640 |
+
"text_size_scale": 1,
|
641 |
+
"margin": {
|
642 |
+
"right": {
|
643 |
+
"scaling_factor": 1,
|
644 |
+
"size": "DOCUMENT_MARGIN"
|
645 |
+
},
|
646 |
+
"left": {
|
647 |
+
"scaling_factor": 1,
|
648 |
+
"size": "DOCUMENT_MARGIN"
|
649 |
+
}
|
650 |
+
},
|
651 |
+
"border": {
|
652 |
+
"top": {
|
653 |
+
"width": 0
|
654 |
+
},
|
655 |
+
"right": {
|
656 |
+
"width": 0
|
657 |
+
},
|
658 |
+
"bottom": {
|
659 |
+
"width": 0
|
660 |
+
},
|
661 |
+
"left": {
|
662 |
+
"width": 0
|
663 |
+
}
|
664 |
+
},
|
665 |
+
"padding": {
|
666 |
+
"top": {
|
667 |
+
"scaling_factor": 1,
|
668 |
+
"size": "NONE"
|
669 |
+
},
|
670 |
+
"right": {
|
671 |
+
"scaling_factor": 1,
|
672 |
+
"size": "NONE"
|
673 |
+
},
|
674 |
+
"bottom": {
|
675 |
+
"scaling_factor": 1,
|
676 |
+
"size": "NONE"
|
677 |
+
},
|
678 |
+
"left": {
|
679 |
+
"scaling_factor": 1,
|
680 |
+
"size": "NONE"
|
681 |
+
}
|
682 |
+
}
|
683 |
+
},
|
684 |
+
"caption_description": {
|
685 |
+
"font": "Georgia",
|
686 |
+
"color": "#808080",
|
687 |
+
"background_color": "#00FFFFFF",
|
688 |
+
"capitalization": "NONE",
|
689 |
+
"display": "INLINE",
|
690 |
+
"line_height_scale": 1,
|
691 |
+
"text_size_scale": 1,
|
692 |
+
"margin": {
|
693 |
+
"right": {
|
694 |
+
"scaling_factor": 1,
|
695 |
+
"size": "DOCUMENT_MARGIN"
|
696 |
+
},
|
697 |
+
"left": {
|
698 |
+
"scaling_factor": 1,
|
699 |
+
"size": "DOCUMENT_MARGIN"
|
700 |
+
}
|
701 |
+
},
|
702 |
+
"border": {
|
703 |
+
"top": {
|
704 |
+
"width": 0
|
705 |
+
},
|
706 |
+
"right": {
|
707 |
+
"width": 0
|
708 |
+
},
|
709 |
+
"bottom": {
|
710 |
+
"width": 0
|
711 |
+
},
|
712 |
+
"left": {
|
713 |
+
"width": 0
|
714 |
+
}
|
715 |
+
},
|
716 |
+
"padding": {
|
717 |
+
"top": {
|
718 |
+
"scaling_factor": 1,
|
719 |
+
"size": "NONE"
|
720 |
+
},
|
721 |
+
"right": {
|
722 |
+
"scaling_factor": 1,
|
723 |
+
"size": "NONE"
|
724 |
+
},
|
725 |
+
"bottom": {
|
726 |
+
"scaling_factor": 1,
|
727 |
+
"size": "NONE"
|
728 |
+
},
|
729 |
+
"left": {
|
730 |
+
"scaling_factor": 1,
|
731 |
+
"size": "NONE"
|
732 |
+
}
|
733 |
+
}
|
734 |
+
},
|
735 |
+
"caption_title_large": {
|
736 |
+
"font": "Georgia",
|
737 |
+
"color": "#808080",
|
738 |
+
"background_color": "#00FFFFFF",
|
739 |
+
"capitalization": "NONE",
|
740 |
+
"display": "INLINE",
|
741 |
+
"line_height_scale": 1,
|
742 |
+
"text_size_scale": 1,
|
743 |
+
"margin": {
|
744 |
+
"right": {
|
745 |
+
"scaling_factor": 1,
|
746 |
+
"size": "DOCUMENT_MARGIN"
|
747 |
+
},
|
748 |
+
"left": {
|
749 |
+
"scaling_factor": 1,
|
750 |
+
"size": "DOCUMENT_MARGIN"
|
751 |
+
}
|
752 |
+
},
|
753 |
+
"border": {
|
754 |
+
"top": {
|
755 |
+
"width": 0
|
756 |
+
},
|
757 |
+
"right": {
|
758 |
+
"width": 0
|
759 |
+
},
|
760 |
+
"bottom": {
|
761 |
+
"width": 0
|
762 |
+
},
|
763 |
+
"left": {
|
764 |
+
"width": 0
|
765 |
+
}
|
766 |
+
},
|
767 |
+
"padding": {
|
768 |
+
"top": {
|
769 |
+
"scaling_factor": 1,
|
770 |
+
"size": "NONE"
|
771 |
+
},
|
772 |
+
"right": {
|
773 |
+
"scaling_factor": 1,
|
774 |
+
"size": "NONE"
|
775 |
+
},
|
776 |
+
"bottom": {
|
777 |
+
"scaling_factor": 1,
|
778 |
+
"size": "NONE"
|
779 |
+
},
|
780 |
+
"left": {
|
781 |
+
"scaling_factor": 1,
|
782 |
+
"size": "NONE"
|
783 |
+
}
|
784 |
+
}
|
785 |
+
},
|
786 |
+
"caption_description_large": {
|
787 |
+
"font": "Georgia",
|
788 |
+
"color": "#808080",
|
789 |
+
"background_color": "#00FFFFFF",
|
790 |
+
"capitalization": "NONE",
|
791 |
+
"display": "INLINE",
|
792 |
+
"line_height_scale": 1,
|
793 |
+
"text_size_scale": 1,
|
794 |
+
"margin": {
|
795 |
+
"right": {
|
796 |
+
"scaling_factor": 1,
|
797 |
+
"size": "DOCUMENT_MARGIN"
|
798 |
+
},
|
799 |
+
"left": {
|
800 |
+
"scaling_factor": 1,
|
801 |
+
"size": "DOCUMENT_MARGIN"
|
802 |
+
}
|
803 |
+
},
|
804 |
+
"border": {
|
805 |
+
"top": {
|
806 |
+
"width": 0
|
807 |
+
},
|
808 |
+
"right": {
|
809 |
+
"width": 0
|
810 |
+
},
|
811 |
+
"bottom": {
|
812 |
+
"width": 0
|
813 |
+
},
|
814 |
+
"left": {
|
815 |
+
"width": 0
|
816 |
+
}
|
817 |
+
},
|
818 |
+
"padding": {
|
819 |
+
"top": {
|
820 |
+
"scaling_factor": 1,
|
821 |
+
"size": "NONE"
|
822 |
+
},
|
823 |
+
"right": {
|
824 |
+
"scaling_factor": 1,
|
825 |
+
"size": "NONE"
|
826 |
+
},
|
827 |
+
"bottom": {
|
828 |
+
"scaling_factor": 1,
|
829 |
+
"size": "NONE"
|
830 |
+
},
|
831 |
+
"left": {
|
832 |
+
"scaling_factor": 1,
|
833 |
+
"size": "NONE"
|
834 |
+
}
|
835 |
+
}
|
836 |
+
},
|
837 |
+
"caption_title_extra_large": {
|
838 |
+
"font": "Georgia",
|
839 |
+
"color": "#808080",
|
840 |
+
"background_color": "#00FFFFFF",
|
841 |
+
"capitalization": "NONE",
|
842 |
+
"display": "INLINE",
|
843 |
+
"line_height_scale": 1,
|
844 |
+
"text_size_scale": 1,
|
845 |
+
"margin": {
|
846 |
+
"right": {
|
847 |
+
"scaling_factor": 1,
|
848 |
+
"size": "DOCUMENT_MARGIN"
|
849 |
+
},
|
850 |
+
"left": {
|
851 |
+
"scaling_factor": 1,
|
852 |
+
"size": "DOCUMENT_MARGIN"
|
853 |
+
}
|
854 |
+
},
|
855 |
+
"border": {
|
856 |
+
"top": {
|
857 |
+
"width": 0
|
858 |
+
},
|
859 |
+
"right": {
|
860 |
+
"width": 0
|
861 |
+
},
|
862 |
+
"bottom": {
|
863 |
+
"width": 0
|
864 |
+
},
|
865 |
+
"left": {
|
866 |
+
"width": 0
|
867 |
+
}
|
868 |
+
},
|
869 |
+
"padding": {
|
870 |
+
"top": {
|
871 |
+
"scaling_factor": 1,
|
872 |
+
"size": "NONE"
|
873 |
+
},
|
874 |
+
"right": {
|
875 |
+
"scaling_factor": 1,
|
876 |
+
"size": "NONE"
|
877 |
+
},
|
878 |
+
"bottom": {
|
879 |
+
"scaling_factor": 1,
|
880 |
+
"size": "NONE"
|
881 |
+
},
|
882 |
+
"left": {
|
883 |
+
"scaling_factor": 1,
|
884 |
+
"size": "NONE"
|
885 |
+
}
|
886 |
+
}
|
887 |
+
},
|
888 |
+
"caption_description_extra_large": {
|
889 |
+
"font": "Georgia",
|
890 |
+
"color": "#808080",
|
891 |
+
"background_color": "#00FFFFFF",
|
892 |
+
"capitalization": "NONE",
|
893 |
+
"display": "INLINE",
|
894 |
+
"line_height_scale": 1,
|
895 |
+
"text_size_scale": 1,
|
896 |
+
"margin": {
|
897 |
+
"right": {
|
898 |
+
"scaling_factor": 1,
|
899 |
+
"size": "DOCUMENT_MARGIN"
|
900 |
+
},
|
901 |
+
"left": {
|
902 |
+
"scaling_factor": 1,
|
903 |
+
"size": "DOCUMENT_MARGIN"
|
904 |
+
}
|
905 |
+
},
|
906 |
+
"border": {
|
907 |
+
"top": {
|
908 |
+
"width": 0
|
909 |
+
},
|
910 |
+
"right": {
|
911 |
+
"width": 0
|
912 |
+
},
|
913 |
+
"bottom": {
|
914 |
+
"width": 0
|
915 |
+
},
|
916 |
+
"left": {
|
917 |
+
"width": 0
|
918 |
+
}
|
919 |
+
},
|
920 |
+
"padding": {
|
921 |
+
"top": {
|
922 |
+
"scaling_factor": 1,
|
923 |
+
"size": "NONE"
|
924 |
+
},
|
925 |
+
"right": {
|
926 |
+
"scaling_factor": 1,
|
927 |
+
"size": "NONE"
|
928 |
+
},
|
929 |
+
"bottom": {
|
930 |
+
"scaling_factor": 1,
|
931 |
+
"size": "NONE"
|
932 |
+
},
|
933 |
+
"left": {
|
934 |
+
"scaling_factor": 1,
|
935 |
+
"size": "NONE"
|
936 |
+
}
|
937 |
+
}
|
938 |
+
},
|
939 |
+
"footer": {
|
940 |
+
"font": "Helvetica Neue",
|
941 |
+
"color": "#000000",
|
942 |
+
"background_color": "#00FFFFFF",
|
943 |
+
"capitalization": "NONE",
|
944 |
+
"text_alignment": "LEFT",
|
945 |
+
"display": "INLINE",
|
946 |
+
"line_height_scale": 1,
|
947 |
+
"text_size_scale": 1,
|
948 |
+
"margin": {
|
949 |
+
"right": {
|
950 |
+
"scaling_factor": 1,
|
951 |
+
"size": "DOCUMENT_MARGIN"
|
952 |
+
},
|
953 |
+
"left": {
|
954 |
+
"scaling_factor": 1,
|
955 |
+
"size": "DOCUMENT_MARGIN"
|
956 |
+
}
|
957 |
+
},
|
958 |
+
"border": {
|
959 |
+
"top": {
|
960 |
+
"width": 0
|
961 |
+
},
|
962 |
+
"right": {
|
963 |
+
"width": 0
|
964 |
+
},
|
965 |
+
"bottom": {
|
966 |
+
"width": 0
|
967 |
+
},
|
968 |
+
"left": {
|
969 |
+
"width": 0
|
970 |
+
}
|
971 |
+
},
|
972 |
+
"padding": {
|
973 |
+
"top": {
|
974 |
+
"scaling_factor": 1,
|
975 |
+
"size": "NONE"
|
976 |
+
},
|
977 |
+
"right": {
|
978 |
+
"scaling_factor": 1,
|
979 |
+
"size": "NONE"
|
980 |
+
},
|
981 |
+
"bottom": {
|
982 |
+
"scaling_factor": 1,
|
983 |
+
"size": "NONE"
|
984 |
+
},
|
985 |
+
"left": {
|
986 |
+
"scaling_factor": 1,
|
987 |
+
"size": "NONE"
|
988 |
+
}
|
989 |
+
}
|
990 |
+
},
|
991 |
+
"id": "1755859684428101",
|
992 |
+
"name": "wod-gray"
|
993 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/examples/styles/style-got-from-somewhereelse.json
ADDED
@@ -0,0 +1,993 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"background_color": "#EEEEEE",
|
3 |
+
"header": {
|
4 |
+
"logo": {
|
5 |
+
"dataURL": null,
|
6 |
+
"id": "1229084557204785",
|
7 |
+
"full_resolution_url": "https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8",
|
8 |
+
"full_resolution_width": 2600,
|
9 |
+
"full_resolution_height": 512,
|
10 |
+
"thumbnail_url": "https://fb-s-d-a.akamaihd.net/h-ak-xpf1/v/t39.5687-6/17634152_1374280939304404_1278222734471462912_n.png?_nc_log=1&oh=d3e95b10e960a9527ad643c47d821160&oe=598664D5&__gda__=1498346669_5ee6f5a2bd8d17474bfb46398d9b888a",
|
11 |
+
"article_scaling_factor": 1
|
12 |
+
},
|
13 |
+
"logo_scale": 1,
|
14 |
+
"accent_color": "#000000",
|
15 |
+
"background_color": "#000066",
|
16 |
+
"bar_color": null
|
17 |
+
},
|
18 |
+
"kicker": {
|
19 |
+
"font": "Helvetica Neue",
|
20 |
+
"color": "#000000",
|
21 |
+
"background_color": "#00FFFFFF",
|
22 |
+
"capitalization": "ALL_CAPS",
|
23 |
+
"text_alignment": "LEFT",
|
24 |
+
"display": "INLINE",
|
25 |
+
"line_height_scale": 1,
|
26 |
+
"text_size_scale": 1,
|
27 |
+
"margin": {
|
28 |
+
"right": {
|
29 |
+
"scaling_factor": 1,
|
30 |
+
"size": "DOCUMENT_MARGIN"
|
31 |
+
},
|
32 |
+
"left": {
|
33 |
+
"scaling_factor": 1,
|
34 |
+
"size": "DOCUMENT_MARGIN"
|
35 |
+
}
|
36 |
+
},
|
37 |
+
"border": {
|
38 |
+
"top": {
|
39 |
+
"width": 0
|
40 |
+
},
|
41 |
+
"right": {
|
42 |
+
"width": 0
|
43 |
+
},
|
44 |
+
"bottom": {
|
45 |
+
"width": 0
|
46 |
+
},
|
47 |
+
"left": {
|
48 |
+
"width": 0
|
49 |
+
}
|
50 |
+
},
|
51 |
+
"padding": {
|
52 |
+
"top": {
|
53 |
+
"scaling_factor": 1,
|
54 |
+
"size": "NONE"
|
55 |
+
},
|
56 |
+
"right": {
|
57 |
+
"scaling_factor": 1,
|
58 |
+
"size": "NONE"
|
59 |
+
},
|
60 |
+
"bottom": {
|
61 |
+
"scaling_factor": 1,
|
62 |
+
"size": "NONE"
|
63 |
+
},
|
64 |
+
"left": {
|
65 |
+
"scaling_factor": 1,
|
66 |
+
"size": "NONE"
|
67 |
+
}
|
68 |
+
}
|
69 |
+
},
|
70 |
+
"title": {
|
71 |
+
"font": "Georgia",
|
72 |
+
"color": "#000000",
|
73 |
+
"background_color": "#00FFFFFF",
|
74 |
+
"capitalization": "NONE",
|
75 |
+
"text_alignment": "LEFT",
|
76 |
+
"display": "INLINE",
|
77 |
+
"line_height_scale": 1,
|
78 |
+
"text_size_scale": 1,
|
79 |
+
"margin": {
|
80 |
+
"right": {
|
81 |
+
"scaling_factor": 1,
|
82 |
+
"size": "DOCUMENT_MARGIN"
|
83 |
+
},
|
84 |
+
"left": {
|
85 |
+
"scaling_factor": 1,
|
86 |
+
"size": "DOCUMENT_MARGIN"
|
87 |
+
}
|
88 |
+
},
|
89 |
+
"border": {
|
90 |
+
"top": {
|
91 |
+
"width": 0
|
92 |
+
},
|
93 |
+
"right": {
|
94 |
+
"width": 0
|
95 |
+
},
|
96 |
+
"bottom": {
|
97 |
+
"width": 0
|
98 |
+
},
|
99 |
+
"left": {
|
100 |
+
"width": 0
|
101 |
+
}
|
102 |
+
},
|
103 |
+
"padding": {
|
104 |
+
"top": {
|
105 |
+
"scaling_factor": 1,
|
106 |
+
"size": "NONE"
|
107 |
+
},
|
108 |
+
"right": {
|
109 |
+
"scaling_factor": 1,
|
110 |
+
"size": "NONE"
|
111 |
+
},
|
112 |
+
"bottom": {
|
113 |
+
"scaling_factor": 1,
|
114 |
+
"size": "NONE"
|
115 |
+
},
|
116 |
+
"left": {
|
117 |
+
"scaling_factor": 1,
|
118 |
+
"size": "NONE"
|
119 |
+
}
|
120 |
+
}
|
121 |
+
},
|
122 |
+
"subtitle": {
|
123 |
+
"font": "Georgia",
|
124 |
+
"color": "#000000",
|
125 |
+
"background_color": "#00FFFFFF",
|
126 |
+
"capitalization": "NONE",
|
127 |
+
"text_alignment": "LEFT",
|
128 |
+
"display": "INLINE",
|
129 |
+
"line_height_scale": 1,
|
130 |
+
"text_size_scale": 1,
|
131 |
+
"margin": {
|
132 |
+
"right": {
|
133 |
+
"scaling_factor": 1,
|
134 |
+
"size": "DOCUMENT_MARGIN"
|
135 |
+
},
|
136 |
+
"left": {
|
137 |
+
"scaling_factor": 1,
|
138 |
+
"size": "DOCUMENT_MARGIN"
|
139 |
+
}
|
140 |
+
},
|
141 |
+
"border": {
|
142 |
+
"top": {
|
143 |
+
"width": 0
|
144 |
+
},
|
145 |
+
"right": {
|
146 |
+
"width": 0
|
147 |
+
},
|
148 |
+
"bottom": {
|
149 |
+
"width": 0
|
150 |
+
},
|
151 |
+
"left": {
|
152 |
+
"width": 0
|
153 |
+
}
|
154 |
+
},
|
155 |
+
"padding": {
|
156 |
+
"top": {
|
157 |
+
"scaling_factor": 1,
|
158 |
+
"size": "NONE"
|
159 |
+
},
|
160 |
+
"right": {
|
161 |
+
"scaling_factor": 1,
|
162 |
+
"size": "NONE"
|
163 |
+
},
|
164 |
+
"bottom": {
|
165 |
+
"scaling_factor": 1,
|
166 |
+
"size": "NONE"
|
167 |
+
},
|
168 |
+
"left": {
|
169 |
+
"scaling_factor": 1,
|
170 |
+
"size": "NONE"
|
171 |
+
}
|
172 |
+
}
|
173 |
+
},
|
174 |
+
"byline": {
|
175 |
+
"font": "Helvetica Neue",
|
176 |
+
"color": "#000000",
|
177 |
+
"capitalization": "ALL_CAPS",
|
178 |
+
"text_alignment": "LEFT",
|
179 |
+
"line_height_scale": 1,
|
180 |
+
"text_size_scale": 1,
|
181 |
+
"margin": {
|
182 |
+
"right": {
|
183 |
+
"scaling_factor": 1,
|
184 |
+
"size": "DOCUMENT_MARGIN"
|
185 |
+
},
|
186 |
+
"left": {
|
187 |
+
"scaling_factor": 1,
|
188 |
+
"size": "DOCUMENT_MARGIN"
|
189 |
+
}
|
190 |
+
}
|
191 |
+
},
|
192 |
+
"date_style": "MONTH_DAY_YEAR",
|
193 |
+
"primary_heading": {
|
194 |
+
"font": "Georgia",
|
195 |
+
"color": "#000000",
|
196 |
+
"background_color": "#00FFFFFF",
|
197 |
+
"capitalization": "NONE",
|
198 |
+
"text_alignment": "LEFT",
|
199 |
+
"display": "INLINE",
|
200 |
+
"line_height_scale": 1,
|
201 |
+
"text_size_scale": 1,
|
202 |
+
"margin": {
|
203 |
+
"right": {
|
204 |
+
"scaling_factor": 1,
|
205 |
+
"size": "DOCUMENT_MARGIN"
|
206 |
+
},
|
207 |
+
"left": {
|
208 |
+
"scaling_factor": 1,
|
209 |
+
"size": "DOCUMENT_MARGIN"
|
210 |
+
}
|
211 |
+
},
|
212 |
+
"border": {
|
213 |
+
"top": {
|
214 |
+
"width": 0
|
215 |
+
},
|
216 |
+
"right": {
|
217 |
+
"width": 0
|
218 |
+
},
|
219 |
+
"bottom": {
|
220 |
+
"width": 0
|
221 |
+
},
|
222 |
+
"left": {
|
223 |
+
"width": 0
|
224 |
+
}
|
225 |
+
},
|
226 |
+
"padding": {
|
227 |
+
"top": {
|
228 |
+
"scaling_factor": 1,
|
229 |
+
"size": "NONE"
|
230 |
+
},
|
231 |
+
"right": {
|
232 |
+
"scaling_factor": 1,
|
233 |
+
"size": "NONE"
|
234 |
+
},
|
235 |
+
"bottom": {
|
236 |
+
"scaling_factor": 1,
|
237 |
+
"size": "NONE"
|
238 |
+
},
|
239 |
+
"left": {
|
240 |
+
"scaling_factor": 1,
|
241 |
+
"size": "NONE"
|
242 |
+
}
|
243 |
+
}
|
244 |
+
},
|
245 |
+
"secondary_heading": {
|
246 |
+
"font": "Georgia",
|
247 |
+
"color": "#000000",
|
248 |
+
"background_color": "#00FFFFFF",
|
249 |
+
"capitalization": "NONE",
|
250 |
+
"text_alignment": "LEFT",
|
251 |
+
"display": "INLINE",
|
252 |
+
"line_height_scale": 1,
|
253 |
+
"text_size_scale": 1,
|
254 |
+
"margin": {
|
255 |
+
"right": {
|
256 |
+
"scaling_factor": 1,
|
257 |
+
"size": "DOCUMENT_MARGIN"
|
258 |
+
},
|
259 |
+
"left": {
|
260 |
+
"scaling_factor": 1,
|
261 |
+
"size": "DOCUMENT_MARGIN"
|
262 |
+
}
|
263 |
+
},
|
264 |
+
"border": {
|
265 |
+
"top": {
|
266 |
+
"width": 0
|
267 |
+
},
|
268 |
+
"right": {
|
269 |
+
"width": 0
|
270 |
+
},
|
271 |
+
"bottom": {
|
272 |
+
"width": 0
|
273 |
+
},
|
274 |
+
"left": {
|
275 |
+
"width": 0
|
276 |
+
}
|
277 |
+
},
|
278 |
+
"padding": {
|
279 |
+
"top": {
|
280 |
+
"scaling_factor": 1,
|
281 |
+
"size": "NONE"
|
282 |
+
},
|
283 |
+
"right": {
|
284 |
+
"scaling_factor": 1,
|
285 |
+
"size": "NONE"
|
286 |
+
},
|
287 |
+
"bottom": {
|
288 |
+
"scaling_factor": 1,
|
289 |
+
"size": "NONE"
|
290 |
+
},
|
291 |
+
"left": {
|
292 |
+
"scaling_factor": 1,
|
293 |
+
"size": "NONE"
|
294 |
+
}
|
295 |
+
}
|
296 |
+
},
|
297 |
+
"body_text": {
|
298 |
+
"font": "Georgia",
|
299 |
+
"color": "#000000",
|
300 |
+
"capitalization": "NONE",
|
301 |
+
"text_alignment": "LEFT",
|
302 |
+
"line_height_scale": 1,
|
303 |
+
"text_size_scale": 1,
|
304 |
+
"margin": {
|
305 |
+
"right": {
|
306 |
+
"scaling_factor": 1,
|
307 |
+
"size": "DOCUMENT_MARGIN"
|
308 |
+
},
|
309 |
+
"left": {
|
310 |
+
"scaling_factor": 1,
|
311 |
+
"size": "DOCUMENT_MARGIN"
|
312 |
+
}
|
313 |
+
}
|
314 |
+
},
|
315 |
+
"inline_link": {
|
316 |
+
"color": "#000000",
|
317 |
+
"underline": "SIMPLE_UNDERLINE",
|
318 |
+
"font": "Georgia"
|
319 |
+
},
|
320 |
+
"block_quote": {
|
321 |
+
"font": "Georgia",
|
322 |
+
"color": "#000000",
|
323 |
+
"background_color": "#00FFFFFF",
|
324 |
+
"capitalization": "NONE",
|
325 |
+
"text_alignment": "LEFT",
|
326 |
+
"display": "BLOCK",
|
327 |
+
"line_height_scale": 1,
|
328 |
+
"text_size_scale": 1,
|
329 |
+
"margin": {
|
330 |
+
"right": {
|
331 |
+
"scaling_factor": 1,
|
332 |
+
"size": "DOCUMENT_MARGIN"
|
333 |
+
},
|
334 |
+
"left": {
|
335 |
+
"scaling_factor": 1,
|
336 |
+
"size": "DOCUMENT_MARGIN"
|
337 |
+
}
|
338 |
+
},
|
339 |
+
"border": {
|
340 |
+
"top": {
|
341 |
+
"color": "#000000",
|
342 |
+
"width": 0
|
343 |
+
},
|
344 |
+
"right": {
|
345 |
+
"color": "#000000",
|
346 |
+
"width": 0
|
347 |
+
},
|
348 |
+
"bottom": {
|
349 |
+
"color": "#000000",
|
350 |
+
"width": 0
|
351 |
+
},
|
352 |
+
"left": {
|
353 |
+
"color": "#000000",
|
354 |
+
"width": 2
|
355 |
+
}
|
356 |
+
},
|
357 |
+
"padding": {
|
358 |
+
"top": {
|
359 |
+
"scaling_factor": 1,
|
360 |
+
"size": "NONE"
|
361 |
+
},
|
362 |
+
"right": {
|
363 |
+
"scaling_factor": 1,
|
364 |
+
"size": "SMALL"
|
365 |
+
},
|
366 |
+
"bottom": {
|
367 |
+
"scaling_factor": 1,
|
368 |
+
"size": "NONE"
|
369 |
+
},
|
370 |
+
"left": {
|
371 |
+
"scaling_factor": 1,
|
372 |
+
"size": "MEDIUM"
|
373 |
+
}
|
374 |
+
}
|
375 |
+
},
|
376 |
+
"pull_quote": {
|
377 |
+
"font": "Georgia",
|
378 |
+
"color": "#000000",
|
379 |
+
"background_color": "#00FFFFFF",
|
380 |
+
"capitalization": "NONE",
|
381 |
+
"text_alignment": "LEFT",
|
382 |
+
"display": "INLINE",
|
383 |
+
"line_height_scale": 1,
|
384 |
+
"text_size_scale": 1,
|
385 |
+
"margin": {
|
386 |
+
"right": {
|
387 |
+
"scaling_factor": 1,
|
388 |
+
"size": "DOCUMENT_MARGIN"
|
389 |
+
},
|
390 |
+
"left": {
|
391 |
+
"scaling_factor": 1,
|
392 |
+
"size": "DOCUMENT_MARGIN"
|
393 |
+
}
|
394 |
+
},
|
395 |
+
"border": {
|
396 |
+
"top": {
|
397 |
+
"width": 0
|
398 |
+
},
|
399 |
+
"right": {
|
400 |
+
"width": 0
|
401 |
+
},
|
402 |
+
"bottom": {
|
403 |
+
"width": 0
|
404 |
+
},
|
405 |
+
"left": {
|
406 |
+
"width": 0
|
407 |
+
}
|
408 |
+
},
|
409 |
+
"padding": {
|
410 |
+
"top": {
|
411 |
+
"scaling_factor": 1,
|
412 |
+
"size": "NONE"
|
413 |
+
},
|
414 |
+
"right": {
|
415 |
+
"scaling_factor": 1,
|
416 |
+
"size": "NONE"
|
417 |
+
},
|
418 |
+
"bottom": {
|
419 |
+
"scaling_factor": 1,
|
420 |
+
"size": "NONE"
|
421 |
+
},
|
422 |
+
"left": {
|
423 |
+
"scaling_factor": 1,
|
424 |
+
"size": "NONE"
|
425 |
+
}
|
426 |
+
}
|
427 |
+
},
|
428 |
+
"pull_quote_attribution": {
|
429 |
+
"font": "Helvetica Neue",
|
430 |
+
"color": "#000000",
|
431 |
+
"background_color": "#00FFFFFF",
|
432 |
+
"capitalization": "ALL_CAPS",
|
433 |
+
"text_alignment": "LEFT",
|
434 |
+
"display": "INLINE",
|
435 |
+
"line_height_scale": 1,
|
436 |
+
"text_size_scale": 1,
|
437 |
+
"margin": {
|
438 |
+
"right": {
|
439 |
+
"scaling_factor": 1,
|
440 |
+
"size": "DOCUMENT_MARGIN"
|
441 |
+
},
|
442 |
+
"left": {
|
443 |
+
"scaling_factor": 1,
|
444 |
+
"size": "DOCUMENT_MARGIN"
|
445 |
+
}
|
446 |
+
},
|
447 |
+
"border": {
|
448 |
+
"top": {
|
449 |
+
"width": 0
|
450 |
+
},
|
451 |
+
"right": {
|
452 |
+
"width": 0
|
453 |
+
},
|
454 |
+
"bottom": {
|
455 |
+
"width": 0
|
456 |
+
},
|
457 |
+
"left": {
|
458 |
+
"width": 0
|
459 |
+
}
|
460 |
+
},
|
461 |
+
"padding": {
|
462 |
+
"top": {
|
463 |
+
"scaling_factor": 1,
|
464 |
+
"size": "NONE"
|
465 |
+
},
|
466 |
+
"right": {
|
467 |
+
"scaling_factor": 1,
|
468 |
+
"size": "NONE"
|
469 |
+
},
|
470 |
+
"bottom": {
|
471 |
+
"scaling_factor": 1,
|
472 |
+
"size": "NONE"
|
473 |
+
},
|
474 |
+
"left": {
|
475 |
+
"scaling_factor": 1,
|
476 |
+
"size": "NONE"
|
477 |
+
}
|
478 |
+
}
|
479 |
+
},
|
480 |
+
"caption_title_small": {
|
481 |
+
"font": "Helvetica Neue Bold",
|
482 |
+
"color": "#808080",
|
483 |
+
"background_color": "#00FFFF",
|
484 |
+
"capitalization": "NONE",
|
485 |
+
"display": "INLINE",
|
486 |
+
"line_height_scale": 1,
|
487 |
+
"text_size_scale": 1,
|
488 |
+
"margin": {
|
489 |
+
"right": {
|
490 |
+
"scaling_factor": 1,
|
491 |
+
"size": "DOCUMENT_MARGIN"
|
492 |
+
},
|
493 |
+
"left": {
|
494 |
+
"scaling_factor": 1,
|
495 |
+
"size": "DOCUMENT_MARGIN"
|
496 |
+
}
|
497 |
+
},
|
498 |
+
"border": {
|
499 |
+
"top": {
|
500 |
+
"width": 0
|
501 |
+
},
|
502 |
+
"right": {
|
503 |
+
"width": 0
|
504 |
+
},
|
505 |
+
"bottom": {
|
506 |
+
"width": 0
|
507 |
+
},
|
508 |
+
"left": {
|
509 |
+
"width": 0
|
510 |
+
}
|
511 |
+
},
|
512 |
+
"padding": {
|
513 |
+
"top": {
|
514 |
+
"scaling_factor": 1,
|
515 |
+
"size": "NONE"
|
516 |
+
},
|
517 |
+
"right": {
|
518 |
+
"scaling_factor": 1,
|
519 |
+
"size": "NONE"
|
520 |
+
},
|
521 |
+
"bottom": {
|
522 |
+
"scaling_factor": 1,
|
523 |
+
"size": "NONE"
|
524 |
+
},
|
525 |
+
"left": {
|
526 |
+
"scaling_factor": 1,
|
527 |
+
"size": "NONE"
|
528 |
+
}
|
529 |
+
}
|
530 |
+
},
|
531 |
+
"caption_description_small": {
|
532 |
+
"font": "Helvetica Neue",
|
533 |
+
"color": "#808080",
|
534 |
+
"background_color": "#00FFFFFF",
|
535 |
+
"capitalization": "NONE",
|
536 |
+
"display": "INLINE",
|
537 |
+
"line_height_scale": 1,
|
538 |
+
"text_size_scale": 1,
|
539 |
+
"margin": {
|
540 |
+
"right": {
|
541 |
+
"scaling_factor": 1,
|
542 |
+
"size": "DOCUMENT_MARGIN"
|
543 |
+
},
|
544 |
+
"left": {
|
545 |
+
"scaling_factor": 1,
|
546 |
+
"size": "DOCUMENT_MARGIN"
|
547 |
+
}
|
548 |
+
},
|
549 |
+
"border": {
|
550 |
+
"top": {
|
551 |
+
"width": 0
|
552 |
+
},
|
553 |
+
"right": {
|
554 |
+
"width": 0
|
555 |
+
},
|
556 |
+
"bottom": {
|
557 |
+
"width": 0
|
558 |
+
},
|
559 |
+
"left": {
|
560 |
+
"width": 0
|
561 |
+
}
|
562 |
+
},
|
563 |
+
"padding": {
|
564 |
+
"top": {
|
565 |
+
"scaling_factor": 1,
|
566 |
+
"size": "NONE"
|
567 |
+
},
|
568 |
+
"right": {
|
569 |
+
"scaling_factor": 1,
|
570 |
+
"size": "NONE"
|
571 |
+
},
|
572 |
+
"bottom": {
|
573 |
+
"scaling_factor": 1,
|
574 |
+
"size": "NONE"
|
575 |
+
},
|
576 |
+
"left": {
|
577 |
+
"scaling_factor": 1,
|
578 |
+
"size": "NONE"
|
579 |
+
}
|
580 |
+
}
|
581 |
+
},
|
582 |
+
"caption_credit": {
|
583 |
+
"font": "Helvetica Neue",
|
584 |
+
"color": "#BFBFBF",
|
585 |
+
"background_color": "#00FFFFFF",
|
586 |
+
"capitalization": "ALL_CAPS",
|
587 |
+
"display": "INLINE",
|
588 |
+
"line_height_scale": 1,
|
589 |
+
"text_size_scale": 1,
|
590 |
+
"margin": {
|
591 |
+
"right": {
|
592 |
+
"scaling_factor": 1,
|
593 |
+
"size": "DOCUMENT_MARGIN"
|
594 |
+
},
|
595 |
+
"left": {
|
596 |
+
"scaling_factor": 1,
|
597 |
+
"size": "DOCUMENT_MARGIN"
|
598 |
+
}
|
599 |
+
},
|
600 |
+
"border": {
|
601 |
+
"top": {
|
602 |
+
"width": 0
|
603 |
+
},
|
604 |
+
"right": {
|
605 |
+
"width": 0
|
606 |
+
},
|
607 |
+
"bottom": {
|
608 |
+
"width": 0
|
609 |
+
},
|
610 |
+
"left": {
|
611 |
+
"width": 0
|
612 |
+
}
|
613 |
+
},
|
614 |
+
"padding": {
|
615 |
+
"top": {
|
616 |
+
"scaling_factor": 1,
|
617 |
+
"size": "NONE"
|
618 |
+
},
|
619 |
+
"right": {
|
620 |
+
"scaling_factor": 1,
|
621 |
+
"size": "NONE"
|
622 |
+
},
|
623 |
+
"bottom": {
|
624 |
+
"scaling_factor": 1,
|
625 |
+
"size": "NONE"
|
626 |
+
},
|
627 |
+
"left": {
|
628 |
+
"scaling_factor": 1,
|
629 |
+
"size": "NONE"
|
630 |
+
}
|
631 |
+
}
|
632 |
+
},
|
633 |
+
"caption_title": {
|
634 |
+
"font": "Georgia",
|
635 |
+
"color": "#808080",
|
636 |
+
"background_color": "#00FFFFFF",
|
637 |
+
"capitalization": "NONE",
|
638 |
+
"display": "INLINE",
|
639 |
+
"line_height_scale": 1,
|
640 |
+
"text_size_scale": 1,
|
641 |
+
"margin": {
|
642 |
+
"right": {
|
643 |
+
"scaling_factor": 1,
|
644 |
+
"size": "DOCUMENT_MARGIN"
|
645 |
+
},
|
646 |
+
"left": {
|
647 |
+
"scaling_factor": 1,
|
648 |
+
"size": "DOCUMENT_MARGIN"
|
649 |
+
}
|
650 |
+
},
|
651 |
+
"border": {
|
652 |
+
"top": {
|
653 |
+
"width": 0
|
654 |
+
},
|
655 |
+
"right": {
|
656 |
+
"width": 0
|
657 |
+
},
|
658 |
+
"bottom": {
|
659 |
+
"width": 0
|
660 |
+
},
|
661 |
+
"left": {
|
662 |
+
"width": 0
|
663 |
+
}
|
664 |
+
},
|
665 |
+
"padding": {
|
666 |
+
"top": {
|
667 |
+
"scaling_factor": 1,
|
668 |
+
"size": "NONE"
|
669 |
+
},
|
670 |
+
"right": {
|
671 |
+
"scaling_factor": 1,
|
672 |
+
"size": "NONE"
|
673 |
+
},
|
674 |
+
"bottom": {
|
675 |
+
"scaling_factor": 1,
|
676 |
+
"size": "NONE"
|
677 |
+
},
|
678 |
+
"left": {
|
679 |
+
"scaling_factor": 1,
|
680 |
+
"size": "NONE"
|
681 |
+
}
|
682 |
+
}
|
683 |
+
},
|
684 |
+
"caption_description": {
|
685 |
+
"font": "Georgia",
|
686 |
+
"color": "#808080",
|
687 |
+
"background_color": "#00FFFFFF",
|
688 |
+
"capitalization": "NONE",
|
689 |
+
"display": "INLINE",
|
690 |
+
"line_height_scale": 1,
|
691 |
+
"text_size_scale": 1,
|
692 |
+
"margin": {
|
693 |
+
"right": {
|
694 |
+
"scaling_factor": 1,
|
695 |
+
"size": "DOCUMENT_MARGIN"
|
696 |
+
},
|
697 |
+
"left": {
|
698 |
+
"scaling_factor": 1,
|
699 |
+
"size": "DOCUMENT_MARGIN"
|
700 |
+
}
|
701 |
+
},
|
702 |
+
"border": {
|
703 |
+
"top": {
|
704 |
+
"width": 0
|
705 |
+
},
|
706 |
+
"right": {
|
707 |
+
"width": 0
|
708 |
+
},
|
709 |
+
"bottom": {
|
710 |
+
"width": 0
|
711 |
+
},
|
712 |
+
"left": {
|
713 |
+
"width": 0
|
714 |
+
}
|
715 |
+
},
|
716 |
+
"padding": {
|
717 |
+
"top": {
|
718 |
+
"scaling_factor": 1,
|
719 |
+
"size": "NONE"
|
720 |
+
},
|
721 |
+
"right": {
|
722 |
+
"scaling_factor": 1,
|
723 |
+
"size": "NONE"
|
724 |
+
},
|
725 |
+
"bottom": {
|
726 |
+
"scaling_factor": 1,
|
727 |
+
"size": "NONE"
|
728 |
+
},
|
729 |
+
"left": {
|
730 |
+
"scaling_factor": 1,
|
731 |
+
"size": "NONE"
|
732 |
+
}
|
733 |
+
}
|
734 |
+
},
|
735 |
+
"caption_title_large": {
|
736 |
+
"font": "Georgia",
|
737 |
+
"color": "#808080",
|
738 |
+
"background_color": "#00FFFFFF",
|
739 |
+
"capitalization": "NONE",
|
740 |
+
"display": "INLINE",
|
741 |
+
"line_height_scale": 1,
|
742 |
+
"text_size_scale": 1,
|
743 |
+
"margin": {
|
744 |
+
"right": {
|
745 |
+
"scaling_factor": 1,
|
746 |
+
"size": "DOCUMENT_MARGIN"
|
747 |
+
},
|
748 |
+
"left": {
|
749 |
+
"scaling_factor": 1,
|
750 |
+
"size": "DOCUMENT_MARGIN"
|
751 |
+
}
|
752 |
+
},
|
753 |
+
"border": {
|
754 |
+
"top": {
|
755 |
+
"width": 0
|
756 |
+
},
|
757 |
+
"right": {
|
758 |
+
"width": 0
|
759 |
+
},
|
760 |
+
"bottom": {
|
761 |
+
"width": 0
|
762 |
+
},
|
763 |
+
"left": {
|
764 |
+
"width": 0
|
765 |
+
}
|
766 |
+
},
|
767 |
+
"padding": {
|
768 |
+
"top": {
|
769 |
+
"scaling_factor": 1,
|
770 |
+
"size": "NONE"
|
771 |
+
},
|
772 |
+
"right": {
|
773 |
+
"scaling_factor": 1,
|
774 |
+
"size": "NONE"
|
775 |
+
},
|
776 |
+
"bottom": {
|
777 |
+
"scaling_factor": 1,
|
778 |
+
"size": "NONE"
|
779 |
+
},
|
780 |
+
"left": {
|
781 |
+
"scaling_factor": 1,
|
782 |
+
"size": "NONE"
|
783 |
+
}
|
784 |
+
}
|
785 |
+
},
|
786 |
+
"caption_description_large": {
|
787 |
+
"font": "Georgia",
|
788 |
+
"color": "#808080",
|
789 |
+
"background_color": "#00FFFFFF",
|
790 |
+
"capitalization": "NONE",
|
791 |
+
"display": "INLINE",
|
792 |
+
"line_height_scale": 1,
|
793 |
+
"text_size_scale": 1,
|
794 |
+
"margin": {
|
795 |
+
"right": {
|
796 |
+
"scaling_factor": 1,
|
797 |
+
"size": "DOCUMENT_MARGIN"
|
798 |
+
},
|
799 |
+
"left": {
|
800 |
+
"scaling_factor": 1,
|
801 |
+
"size": "DOCUMENT_MARGIN"
|
802 |
+
}
|
803 |
+
},
|
804 |
+
"border": {
|
805 |
+
"top": {
|
806 |
+
"width": 0
|
807 |
+
},
|
808 |
+
"right": {
|
809 |
+
"width": 0
|
810 |
+
},
|
811 |
+
"bottom": {
|
812 |
+
"width": 0
|
813 |
+
},
|
814 |
+
"left": {
|
815 |
+
"width": 0
|
816 |
+
}
|
817 |
+
},
|
818 |
+
"padding": {
|
819 |
+
"top": {
|
820 |
+
"scaling_factor": 1,
|
821 |
+
"size": "NONE"
|
822 |
+
},
|
823 |
+
"right": {
|
824 |
+
"scaling_factor": 1,
|
825 |
+
"size": "NONE"
|
826 |
+
},
|
827 |
+
"bottom": {
|
828 |
+
"scaling_factor": 1,
|
829 |
+
"size": "NONE"
|
830 |
+
},
|
831 |
+
"left": {
|
832 |
+
"scaling_factor": 1,
|
833 |
+
"size": "NONE"
|
834 |
+
}
|
835 |
+
}
|
836 |
+
},
|
837 |
+
"caption_title_extra_large": {
|
838 |
+
"font": "Georgia",
|
839 |
+
"color": "#808080",
|
840 |
+
"background_color": "#00FFFFFF",
|
841 |
+
"capitalization": "NONE",
|
842 |
+
"display": "INLINE",
|
843 |
+
"line_height_scale": 1,
|
844 |
+
"text_size_scale": 1,
|
845 |
+
"margin": {
|
846 |
+
"right": {
|
847 |
+
"scaling_factor": 1,
|
848 |
+
"size": "DOCUMENT_MARGIN"
|
849 |
+
},
|
850 |
+
"left": {
|
851 |
+
"scaling_factor": 1,
|
852 |
+
"size": "DOCUMENT_MARGIN"
|
853 |
+
}
|
854 |
+
},
|
855 |
+
"border": {
|
856 |
+
"top": {
|
857 |
+
"width": 0
|
858 |
+
},
|
859 |
+
"right": {
|
860 |
+
"width": 0
|
861 |
+
},
|
862 |
+
"bottom": {
|
863 |
+
"width": 0
|
864 |
+
},
|
865 |
+
"left": {
|
866 |
+
"width": 0
|
867 |
+
}
|
868 |
+
},
|
869 |
+
"padding": {
|
870 |
+
"top": {
|
871 |
+
"scaling_factor": 1,
|
872 |
+
"size": "NONE"
|
873 |
+
},
|
874 |
+
"right": {
|
875 |
+
"scaling_factor": 1,
|
876 |
+
"size": "NONE"
|
877 |
+
},
|
878 |
+
"bottom": {
|
879 |
+
"scaling_factor": 1,
|
880 |
+
"size": "NONE"
|
881 |
+
},
|
882 |
+
"left": {
|
883 |
+
"scaling_factor": 1,
|
884 |
+
"size": "NONE"
|
885 |
+
}
|
886 |
+
}
|
887 |
+
},
|
888 |
+
"caption_description_extra_large": {
|
889 |
+
"font": "Georgia",
|
890 |
+
"color": "#808080",
|
891 |
+
"background_color": "#00FFFFFF",
|
892 |
+
"capitalization": "NONE",
|
893 |
+
"display": "INLINE",
|
894 |
+
"line_height_scale": 1,
|
895 |
+
"text_size_scale": 1,
|
896 |
+
"margin": {
|
897 |
+
"right": {
|
898 |
+
"scaling_factor": 1,
|
899 |
+
"size": "DOCUMENT_MARGIN"
|
900 |
+
},
|
901 |
+
"left": {
|
902 |
+
"scaling_factor": 1,
|
903 |
+
"size": "DOCUMENT_MARGIN"
|
904 |
+
}
|
905 |
+
},
|
906 |
+
"border": {
|
907 |
+
"top": {
|
908 |
+
"width": 0
|
909 |
+
},
|
910 |
+
"right": {
|
911 |
+
"width": 0
|
912 |
+
},
|
913 |
+
"bottom": {
|
914 |
+
"width": 0
|
915 |
+
},
|
916 |
+
"left": {
|
917 |
+
"width": 0
|
918 |
+
}
|
919 |
+
},
|
920 |
+
"padding": {
|
921 |
+
"top": {
|
922 |
+
"scaling_factor": 1,
|
923 |
+
"size": "NONE"
|
924 |
+
},
|
925 |
+
"right": {
|
926 |
+
"scaling_factor": 1,
|
927 |
+
"size": "NONE"
|
928 |
+
},
|
929 |
+
"bottom": {
|
930 |
+
"scaling_factor": 1,
|
931 |
+
"size": "NONE"
|
932 |
+
},
|
933 |
+
"left": {
|
934 |
+
"scaling_factor": 1,
|
935 |
+
"size": "NONE"
|
936 |
+
}
|
937 |
+
}
|
938 |
+
},
|
939 |
+
"footer": {
|
940 |
+
"font": "Helvetica Neue",
|
941 |
+
"color": "#000000",
|
942 |
+
"background_color": "#00FFFFFF",
|
943 |
+
"capitalization": "NONE",
|
944 |
+
"text_alignment": "LEFT",
|
945 |
+
"display": "INLINE",
|
946 |
+
"line_height_scale": 1,
|
947 |
+
"text_size_scale": 1,
|
948 |
+
"margin": {
|
949 |
+
"right": {
|
950 |
+
"scaling_factor": 1,
|
951 |
+
"size": "DOCUMENT_MARGIN"
|
952 |
+
},
|
953 |
+
"left": {
|
954 |
+
"scaling_factor": 1,
|
955 |
+
"size": "DOCUMENT_MARGIN"
|
956 |
+
}
|
957 |
+
},
|
958 |
+
"border": {
|
959 |
+
"top": {
|
960 |
+
"width": 0
|
961 |
+
},
|
962 |
+
"right": {
|
963 |
+
"width": 0
|
964 |
+
},
|
965 |
+
"bottom": {
|
966 |
+
"width": 0
|
967 |
+
},
|
968 |
+
"left": {
|
969 |
+
"width": 0
|
970 |
+
}
|
971 |
+
},
|
972 |
+
"padding": {
|
973 |
+
"top": {
|
974 |
+
"scaling_factor": 1,
|
975 |
+
"size": "NONE"
|
976 |
+
},
|
977 |
+
"right": {
|
978 |
+
"scaling_factor": 1,
|
979 |
+
"size": "NONE"
|
980 |
+
},
|
981 |
+
"bottom": {
|
982 |
+
"scaling_factor": 1,
|
983 |
+
"size": "NONE"
|
984 |
+
},
|
985 |
+
"left": {
|
986 |
+
"scaling_factor": 1,
|
987 |
+
"size": "NONE"
|
988 |
+
}
|
989 |
+
}
|
990 |
+
},
|
991 |
+
"id": "1755859684428101",
|
992 |
+
"name": "wod-gray"
|
993 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/phpcs.xml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<ruleset name="facebook/facebook-instant-articles-sdk-extensions-php">
|
3 |
+
<file>.</file>
|
4 |
+
<exclude-pattern>vendor/</exclude-pattern>
|
5 |
+
<arg name="colors" />
|
6 |
+
<arg value="sn" />
|
7 |
+
<rule ref="PSR2" />
|
8 |
+
</ruleset>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/phpunit.xml
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="utf-8" ?>
|
2 |
+
<phpunit
|
3 |
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
4 |
+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
|
5 |
+
bootstrap="vendor/autoload.php"
|
6 |
+
colors="true"
|
7 |
+
>
|
8 |
+
<testsuites>
|
9 |
+
<testsuite name="The project's test suite">
|
10 |
+
<directory>./tests</directory>
|
11 |
+
</testsuite>
|
12 |
+
</testsuites>
|
13 |
+
<filter>
|
14 |
+
<whitelist>
|
15 |
+
<directory>./src</directory>
|
16 |
+
</whitelist>
|
17 |
+
</filter>
|
18 |
+
</phpunit>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPArticle.php
ADDED
@@ -0,0 +1,1460 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Elements\Element;
|
12 |
+
use Facebook\InstantArticles\Elements\Paragraph;
|
13 |
+
use Facebook\InstantArticles\Elements\Blockquote;
|
14 |
+
use Facebook\InstantArticles\Elements\Ad;
|
15 |
+
use Facebook\InstantArticles\Elements\Analytics;
|
16 |
+
use Facebook\InstantArticles\Elements\H1;
|
17 |
+
use Facebook\InstantArticles\Elements\H2;
|
18 |
+
use Facebook\InstantArticles\Elements\ListElement;
|
19 |
+
use Facebook\InstantArticles\Elements\Pullquote;
|
20 |
+
use Facebook\InstantArticles\Elements\Image;
|
21 |
+
use Facebook\InstantArticles\Elements\Caption;
|
22 |
+
use Facebook\InstantArticles\Elements\AnimatedGIF;
|
23 |
+
use Facebook\InstantArticles\Elements\Video;
|
24 |
+
use Facebook\InstantArticles\Elements\Audio;
|
25 |
+
use Facebook\InstantArticles\Elements\Slideshow;
|
26 |
+
use Facebook\InstantArticles\Elements\Interactive;
|
27 |
+
use Facebook\InstantArticles\Elements\SocialEmbed;
|
28 |
+
use Facebook\InstantArticles\Elements\Map;
|
29 |
+
use Facebook\InstantArticles\Elements\RelatedArticles;
|
30 |
+
use Facebook\InstantArticles\Elements\TextContainer;
|
31 |
+
use Facebook\InstantArticles\Elements\InstantArticleInterface;
|
32 |
+
use Facebook\InstantArticles\Elements\InstantArticle;
|
33 |
+
|
34 |
+
use Facebook\InstantArticles\Parser\Parser;
|
35 |
+
use Facebook\InstantArticles\Validators\Type;
|
36 |
+
use Facebook\InstantArticles\Utils\Observer;
|
37 |
+
|
38 |
+
class AMPArticle extends Element implements InstantArticleInterface
|
39 |
+
{
|
40 |
+
const DEFAULT_MARGIN = 16.4;
|
41 |
+
const DEFAULT_WIDTH = 380;
|
42 |
+
const DEFAULT_HEIGHT = 240;
|
43 |
+
const DEFAULT_LOGO_WIDTH = 230;
|
44 |
+
const DEFAULT_LOGO_HEIGHT = 44;
|
45 |
+
const DEFAULT_DATE_FORMAT = 'F d, Y';
|
46 |
+
const DEFAULT_CSS_PREFIX = 'ia2amp-';
|
47 |
+
|
48 |
+
const STYLES_FOLDER_KEY = 'styles-folder';
|
49 |
+
const OVERRIDE_STYLES_KEY = 'override-styles';
|
50 |
+
const MEDIA_CACHE_FOLDER_KEY = 'media-cache-folder';
|
51 |
+
const ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY = 'enable-download-for-media-sizing';
|
52 |
+
const DEFAULT_MEDIA_WIDTH_KEY = 'default-media-width';
|
53 |
+
const DEFAULT_MEDIA_HEIGHT_KEY = 'default-media-height';
|
54 |
+
const MEDIA_SIZES_KEY = 'media-sizes';
|
55 |
+
const PUBLISHER_KEY = 'publisher';
|
56 |
+
const GOOGLE_MAPS_KEY = 'google_maps_key';
|
57 |
+
const ANALYTICS_KEY = 'analytics';
|
58 |
+
|
59 |
+
const MEDIA_TYPE_IMAGE = 'image';
|
60 |
+
const MEDIA_TYPE_VIDEO = 'video';
|
61 |
+
|
62 |
+
const MEDIA_SIZE_MODE_RESPONSIVE = 'responsive';
|
63 |
+
const MEDIA_SIZE_MODE_VIEWPORT = 'viewport';
|
64 |
+
const MEDIA_SIZE_MODE_SCALED = 'scaled';
|
65 |
+
|
66 |
+
private $instantArticle;
|
67 |
+
/*
|
68 |
+
'lang' => 'en-US',
|
69 |
+
'css-selector-prefix' => 'ia2amp-',
|
70 |
+
'styles-folder' => '/articles/styles'
|
71 |
+
'media-cache-folder' => '/articles/media',
|
72 |
+
'enable-download-for-media-sizing' => FALSE,
|
73 |
+
'default-media-width' => 380,
|
74 |
+
'default-media-height' => 240,
|
75 |
+
'media-sizes' => array(),
|
76 |
+
'publisher' => array(),
|
77 |
+
'analytics' => array(),
|
78 |
+
*/
|
79 |
+
private $properties = array();
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @var Observer The instance for Observing and Hooking system for extensions
|
83 |
+
*/
|
84 |
+
private $observer;
|
85 |
+
|
86 |
+
private $dateFormat = AMPArticle::DEFAULT_DATE_FORMAT;
|
87 |
+
private $logo;
|
88 |
+
|
89 |
+
private $customCSSElement;
|
90 |
+
private $ampHeader;
|
91 |
+
|
92 |
+
private function __construct($instantArticle, $properties, $observer)
|
93 |
+
{
|
94 |
+
$this->instantArticle = $instantArticle;
|
95 |
+
$this->properties = $properties;
|
96 |
+
$this->observer = $observer;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Factory method to instantiate the AMPArticle converter.
|
101 |
+
* @param string|InstantArticle $instantArticle The instant article that will be parsed if informed as string.
|
102 |
+
* @param array() $properties the configuration for the AMP conversion. @see https://developers.facebook.com/docs/instant-articles/other-formats
|
103 |
+
* @param Observer $observer optional, will be created in case none informed. This is the hooking system for code level customizations.
|
104 |
+
*/
|
105 |
+
public static function create($instantArticle, $properties = array(), $observer = null)
|
106 |
+
{
|
107 |
+
// Treats if the informed content is string, parsing it into InstantArticle.
|
108 |
+
if (Type::is($instantArticle, Type::STRING)) {
|
109 |
+
libxml_use_internal_errors(true);
|
110 |
+
$document = new \DOMDocument('1.0');
|
111 |
+
$document->loadHTML($instantArticle);
|
112 |
+
libxml_use_internal_errors(false);
|
113 |
+
|
114 |
+
$parser = new Parser();
|
115 |
+
$instantArticle = $parser->parse($document);
|
116 |
+
}
|
117 |
+
|
118 |
+
// Enforces that $instantArticle is typeof InstantArticle class.
|
119 |
+
Type::enforce($instantArticle, InstantArticle::getClassName());
|
120 |
+
|
121 |
+
if ($properties === null) {
|
122 |
+
$properties = array();
|
123 |
+
}
|
124 |
+
|
125 |
+
if ($observer == null) {
|
126 |
+
$observer = Observer::create();
|
127 |
+
}
|
128 |
+
|
129 |
+
return new self($instantArticle, $properties, $observer);
|
130 |
+
}
|
131 |
+
|
132 |
+
public function getObserver()
|
133 |
+
{
|
134 |
+
return $this->observer;
|
135 |
+
}
|
136 |
+
|
137 |
+
public function getInstantArticle()
|
138 |
+
{
|
139 |
+
return $this->instantArticle;
|
140 |
+
}
|
141 |
+
|
142 |
+
public function render($doctype = '<!doctype html>', $format = true)
|
143 |
+
{
|
144 |
+
$doctype = is_null($doctype) ? '<!doctype html>' : $doctype;
|
145 |
+
$rendered = parent::render($doctype, $format);
|
146 |
+
|
147 |
+
// Makes empty value attribute definition, since we use DOMDocument::saveXML()
|
148 |
+
$rendered = str_replace('amp=""', 'amp', $rendered);
|
149 |
+
$rendered = str_replace('amp-custom=""', 'amp-custom', $rendered);
|
150 |
+
$rendered = str_replace('amp-boilerplate=""', 'amp-boilerplate', $rendered);
|
151 |
+
$rendered = str_replace('async=""', 'async', $rendered);
|
152 |
+
|
153 |
+
return $rendered;
|
154 |
+
}
|
155 |
+
|
156 |
+
public function toDOMElement($document = null)
|
157 |
+
{
|
158 |
+
if (isset($this->properties['css-selector-prefix'])) {
|
159 |
+
$prefix = $this->properties['css-selector-prefix'];
|
160 |
+
} else {
|
161 |
+
$prefix = self::DEFAULT_CSS_PREFIX;
|
162 |
+
}
|
163 |
+
|
164 |
+
$mediaSizes =
|
165 |
+
array_key_exists(self::MEDIA_SIZES_KEY, $this->properties) ?
|
166 |
+
$this->properties[self::MEDIA_SIZES_KEY] :
|
167 |
+
null;
|
168 |
+
|
169 |
+
$mediaCacheFolder =
|
170 |
+
array_key_exists(self::MEDIA_CACHE_FOLDER_KEY, $this->properties) ?
|
171 |
+
$this->properties[self::MEDIA_CACHE_FOLDER_KEY] :
|
172 |
+
null;
|
173 |
+
|
174 |
+
$enableDownloadForMediaSizing =
|
175 |
+
(array_key_exists(self::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY, $this->properties) &&
|
176 |
+
$this->properties[self::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY] === true);
|
177 |
+
|
178 |
+
$defaultWidth = array_key_exists(self::DEFAULT_MEDIA_WIDTH_KEY, $this->properties)
|
179 |
+
? $this->properties[self::DEFAULT_MEDIA_WIDTH_KEY]
|
180 |
+
: self::DEFAULT_WIDTH;
|
181 |
+
$defaultHeight = array_key_exists(self::DEFAULT_MEDIA_HEIGHT_KEY, $this->properties)
|
182 |
+
? $this->properties[self::DEFAULT_MEDIA_HEIGHT_KEY]
|
183 |
+
: self::DEFAULT_HEIGHT;
|
184 |
+
|
185 |
+
|
186 |
+
$context = AMPContext::create($document, $this->instantArticle, $prefix);
|
187 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
188 |
+
|
189 |
+
$ampDocument = $this->observer->applyFilters('AMP_DOCUMENT', $this->transformInstantArticle($context), $context);
|
190 |
+
|
191 |
+
return $ampDocument;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Builds the analytics tag from the strings on the properties.
|
196 |
+
*
|
197 |
+
* The format of the $properties['analytics'] should be a list of strings
|
198 |
+
* containing the raw markup of the analytics tags (either amp-analytics or amp-pixel).
|
199 |
+
*/
|
200 |
+
public function buildAnalytics($context = null)
|
201 |
+
{
|
202 |
+
if (!isset($this->properties[self::ANALYTICS_KEY])) {
|
203 |
+
return null;
|
204 |
+
}
|
205 |
+
|
206 |
+
if ($context === null) {
|
207 |
+
$context = $this->getContext();
|
208 |
+
if ($context === null) {
|
209 |
+
throw new Exception('No context found.');
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
$document = $context->getDocument();
|
214 |
+
$container = $document->createDocumentFragment();
|
215 |
+
|
216 |
+
foreach ($this->properties[self::ANALYTICS_KEY] as $analyticsString) {
|
217 |
+
$fragment = $document->createDocumentFragment();
|
218 |
+
$successs = $fragment->appendXML($analyticsString);
|
219 |
+
|
220 |
+
if (!$successs || // Broken XML
|
221 |
+
$fragment->childNodes->length !== 1 || // Not a single tag
|
222 |
+
!($fragment->firstChild instanceof \DOMElement) || // Not a tag
|
223 |
+
!(
|
224 |
+
$fragment->firstChild->tagName !== 'amp-analytics' || // Not a <amp-analytics> tag
|
225 |
+
$fragment->firstChild->tagName !== 'amp-pixel' // Or a <amp-pixel> tag
|
226 |
+
)
|
227 |
+
) {
|
228 |
+
$context->addWarning("Invalid Analytics markup. AMP Analytics code should be a single <amp-analytics> or <amp-pixel> tag.", $analyticsString);
|
229 |
+
return null;
|
230 |
+
}
|
231 |
+
|
232 |
+
$container->appendChild($this->observer->applyFilters('AMP_ANALYTICS', $fragment, $this->properties));
|
233 |
+
}
|
234 |
+
|
235 |
+
if ($container->childNodes->length === 0) {
|
236 |
+
return null;
|
237 |
+
}
|
238 |
+
|
239 |
+
return $container;
|
240 |
+
}
|
241 |
+
|
242 |
+
public function transformInstantArticle($context)
|
243 |
+
{
|
244 |
+
// Builds and appends head to the HTML document
|
245 |
+
$html = $context->createElement('html', null, null, array("amp" => ""));
|
246 |
+
if ($context->getInstantArticle()->isRTLEnabled()) {
|
247 |
+
$html->setAttribute('dir', 'rtl');
|
248 |
+
}
|
249 |
+
if (isset($this->properties['lang'])) {
|
250 |
+
$html->setAttribute('lang', $this->properties['lang']);
|
251 |
+
}
|
252 |
+
$context->withHtml($html);
|
253 |
+
|
254 |
+
$head = $this->observer->applyFilters('AMP_HEAD', $this->transformMetaInfoHead($context), $context);
|
255 |
+
$context->withHead($head);
|
256 |
+
|
257 |
+
// Build and append body and article tags to the HTML document
|
258 |
+
$body = $this->observer->applyFilters('AMP_BODY', $this->buildBody($context), $context);
|
259 |
+
$context->withBody($body);
|
260 |
+
|
261 |
+
$header = $this->observer->applyFilters('AMP_HEADER', $this->transformArticleHeader($context), $context);
|
262 |
+
$context->withHeader($header);
|
263 |
+
|
264 |
+
$article = $this->observer->applyFilters('AMP_ARTICLE', $this->transformArticleContent($context), $context);
|
265 |
+
$context->withArticle($article);
|
266 |
+
|
267 |
+
$footer = $this->observer->applyFilters('AMP_FOOTER', $this->transformArticleFooter($context), $context);
|
268 |
+
//$context->withFooter($footer);
|
269 |
+
|
270 |
+
// Set the Custom CSS content
|
271 |
+
$cssDeclarations = $this->getCustomCSS($context);
|
272 |
+
$cssTextContent = $context->getDocument()->createTextNode($cssDeclarations);
|
273 |
+
$this->customCSSElement->appendChild($cssTextContent);
|
274 |
+
|
275 |
+
// Create the logo image, if set
|
276 |
+
$this->ampHeader->genHeaderLogo($this->logo);
|
277 |
+
// Create the text element for the published date using parsed format from styles
|
278 |
+
$this->ampHeader->genArticlePublishDate($this->dateFormat);
|
279 |
+
|
280 |
+
// Add the analytics code
|
281 |
+
$analytics = $this->buildAnalytics();
|
282 |
+
if ($analytics !== null) {
|
283 |
+
$head->appendChild($this->buildCustomElementScriptEntry('amp-analytics', 'https://cdn.ampproject.org/v0/amp-analytics-0.1.js', $context));
|
284 |
+
$body->insertBefore($analytics, $body->firstChild);
|
285 |
+
}
|
286 |
+
|
287 |
+
return $html;
|
288 |
+
}
|
289 |
+
|
290 |
+
public function buildBody($context)
|
291 |
+
{
|
292 |
+
return $context->createElement('body', $context->getHtml(), 'body');
|
293 |
+
}
|
294 |
+
|
295 |
+
public function transformArticleHeader($context)
|
296 |
+
{
|
297 |
+
$this->ampHeader = new AMPHeader($context);
|
298 |
+
return $this->ampHeader->build();
|
299 |
+
}
|
300 |
+
|
301 |
+
public function transformMetaInfoHead($context)
|
302 |
+
{
|
303 |
+
// Builds the Head
|
304 |
+
$head = $context->createElement('head');
|
305 |
+
$context->getHtml()->appendChild($head);
|
306 |
+
|
307 |
+
// Builds meta charset and append to head
|
308 |
+
if ($context->getInstantArticle()->getCharset()) {
|
309 |
+
$context->createElement('meta', $head, null, array('charset' => $context->getInstantArticle()->getCharset()));
|
310 |
+
}
|
311 |
+
|
312 |
+
// Builds meta viewport and append to head
|
313 |
+
$context->createElement(
|
314 |
+
'meta',
|
315 |
+
$head,
|
316 |
+
null,
|
317 |
+
array(
|
318 |
+
'name' => 'viewport',
|
319 |
+
'content' => 'width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no'
|
320 |
+
)
|
321 |
+
);
|
322 |
+
|
323 |
+
// Builds ampjs script and append to head
|
324 |
+
$context->createElement('script', $head, null, array('src' => 'https://cdn.ampproject.org/v0.js', 'async' => ''));
|
325 |
+
|
326 |
+
// Builds boilerplate css style and append to head
|
327 |
+
$boilerplate = $context->createElement('style', $head, null, array('amp-boilerplate' => ''));
|
328 |
+
$boilerplateContent = $context->getDocument()->createTextNode('body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}');
|
329 |
+
$boilerplate->appendChild($boilerplateContent);
|
330 |
+
|
331 |
+
// Builds noscript css style and append to head
|
332 |
+
$noscript = $context->createElement('noscript', $head);
|
333 |
+
$noscriptBoilerplate = $context->createElement('style', $noscript, null, array('amp-boilerplate' => ''));
|
334 |
+
$noscriptBoilerplateContent = $context->getDocument()->createTextNode('body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}');
|
335 |
+
$noscriptBoilerplate->appendChild($noscriptBoilerplateContent);
|
336 |
+
|
337 |
+
// Builds canonical link and append to head
|
338 |
+
$link = $context->createElement('link', $head, null, array('rel' => 'canonical', 'href' => $context->getInstantArticle()->getCanonicalURL()));
|
339 |
+
|
340 |
+
// Builds custom css style and append to head
|
341 |
+
$ampCustomCSS = $this->buildCustomCSS($context);
|
342 |
+
$head->appendChild($ampCustomCSS);
|
343 |
+
// Save element, so we can add the custom CSS content after the whole article is processed
|
344 |
+
$this->customCSSElement = $ampCustomCSS;
|
345 |
+
|
346 |
+
// Builds Schema.org metadata and appends to head
|
347 |
+
$discoveryScript = $context->createElement('script', $head, null, array('type' => 'application/ld+json'));
|
348 |
+
$discoveryScriptContent = $this->buildSchemaOrgMetadata($context);
|
349 |
+
$discoveryScript->appendChild($context->getDocument()->createTextNode($discoveryScriptContent));
|
350 |
+
|
351 |
+
// Builds title and append to head
|
352 |
+
$title = $context->createElement('title', $head);
|
353 |
+
$titleText = $context->getInstantArticle()->getHeader()->getTitle()->textToDOMDocumentFragment($context->getDocument());
|
354 |
+
$title->appendChild($titleText);
|
355 |
+
|
356 |
+
return $head;
|
357 |
+
}
|
358 |
+
|
359 |
+
public function transformArticleContent($context)
|
360 |
+
{
|
361 |
+
$article = $context->createElement('article', $context->getBody(), 'article');
|
362 |
+
|
363 |
+
$containsIframe = false;
|
364 |
+
$containsSlideshow = false;
|
365 |
+
$containsAudio = false;
|
366 |
+
$containsVideo = false;
|
367 |
+
|
368 |
+
if ($context->getInstantArticle()->getChildren()) {
|
369 |
+
foreach ($context->getInstantArticle()->getChildren() as $child) {
|
370 |
+
if (Type::is($child, TextContainer::getClassName())) {
|
371 |
+
if (count($child->getTextChildren()) === 0) {
|
372 |
+
continue;
|
373 |
+
} elseif (count($child->getTextChildren()) === 1) {
|
374 |
+
if (Type::is($child->getTextChildren()[0], Type::STRING) &&
|
375 |
+
trim($child->getTextChildren()[0]) === '') {
|
376 |
+
continue;
|
377 |
+
}
|
378 |
+
}
|
379 |
+
}
|
380 |
+
if (Type::is($child, Paragraph::getClassName())) {
|
381 |
+
$childElement = $this->observer->applyFilters('IA_PARAGRAPH', $this->buildRegularDomElement($context, $child, 'p'), $child, $context);
|
382 |
+
} else if (Type::is($child, Blockquote::getClassName())) {
|
383 |
+
$childElement = $this->observer->applyFilters('IA_BLOCKQUOTE', $this->buildRegularDomElement($context, $child, 'blockquote'), $child, $context);
|
384 |
+
} else if (Type::is($child, H1::getClassName())) {
|
385 |
+
$childElement = $this->observer->applyFilters('IA_H1', $this->buildRegularDomElement($context, $child, 'h1'), $child, $context);
|
386 |
+
} else if (Type::is($child, H2::getClassName())) {
|
387 |
+
$childElement = $this->observer->applyFilters('IA_H2', $this->buildRegularDomElement($context, $child, 'h2'), $child, $context);
|
388 |
+
} else if (Type::is($child, ListElement::getClassName())) {
|
389 |
+
$childElement = $this->observer->applyFilters('IA_LIST', $this->buildRegularDomElement($context, $child, 'list'), $child, $context);
|
390 |
+
} else if (Type::is($child, Pullquote::getClassName())) {
|
391 |
+
$childElement = $this->observer->applyFilters('IA_PULLQUOTE', $this->buildRegularDomElement($context, $child, 'pullquote'), $child, $context);
|
392 |
+
} else if (Type::is($child, Image::getClassName())) {
|
393 |
+
$childElement = $this->observer->applyFilters('IA_IMAGE', $this->buildImage($child, $context, 'image'), $child, $context);
|
394 |
+
} else if (Type::is($child, AnimatedGIF::getClassName())) {
|
395 |
+
$childElement = $this->observer->applyFilters('IA_GIF', $this->buildGIF($child, $context, 'gif'), $child, $context);
|
396 |
+
} else if (Type::is($child, Video::getClassName())) {
|
397 |
+
if (!$containsVideo) {
|
398 |
+
$containsVideo = true;
|
399 |
+
$context->getHead()->appendChild($this->buildCustomElementScriptEntry('amp-video', 'https://cdn.ampproject.org/v0/amp-video-0.1.js', $context));
|
400 |
+
}
|
401 |
+
$childElement = $this->observer->applyFilters('IA_VIDEO', $this->buildVideo($child, $context, 'video'), $child, $context);
|
402 |
+
} else if (Type::is($child, Audio::getClassName())) {
|
403 |
+
if (!$containsAudio) {
|
404 |
+
$containsAudio = true;
|
405 |
+
$context->getHead()->appendChild($this->buildCustomElementScriptEntry('amp-audio', 'https://cdn.ampproject.org/v0/amp-audio-0.1.js', $context));
|
406 |
+
}
|
407 |
+
$childElement = $this->observer->applyFilters('IA_AUDIO', $this->buildAudio($child, $context, 'audio'), $child, $context);
|
408 |
+
} else if (Type::is($child, Slideshow::getClassName())) {
|
409 |
+
if (!$containsSlideshow) {
|
410 |
+
$containsSlideshow = true;
|
411 |
+
$context->getHead()->appendChild($this->buildCustomElementScriptEntry('amp-carousel', 'https://cdn.ampproject.org/v0/amp-carousel-0.1.js', $context));
|
412 |
+
}
|
413 |
+
$childElement = $this->observer->applyFilters('IA_SLIDESHOW', $this->buildSlideshow($child, $context, 'slideshow'), $child, $context);
|
414 |
+
} else if ((Type::is($child, Interactive::getClassName()) || Type::is($child, SocialEmbed::getClassName())) && !Type::isTextEmpty($child->getSource())) {
|
415 |
+
if (!$containsIframe) {
|
416 |
+
$containsIframe = true;
|
417 |
+
$context->getHead()->appendChild($this->buildCustomElementScriptEntry('amp-iframe', 'https://cdn.ampproject.org/v0/amp-iframe-0.1.js', $context));
|
418 |
+
}
|
419 |
+
$childElement = $this->observer->applyFilters('IA_INTERACTIVE', $this->buildIframe($child, $context, 'interactive', true), $child, $context);
|
420 |
+
} else if (Type::is($child, Map::getClassName())) {
|
421 |
+
if (!$containsIframe) {
|
422 |
+
$containsIframe = true;
|
423 |
+
$context->getHead()->appendChild($this->buildCustomElementScriptEntry('amp-iframe', 'https://cdn.ampproject.org/v0/amp-iframe-0.1.js', $context));
|
424 |
+
}
|
425 |
+
$childElement = $this->observer->applyFilters('IA_MAP', $this->buildMaps($child, $context, 'map'), $child, $context);
|
426 |
+
} else if (Type::is($child, RelatedArticles::getClassName())) {
|
427 |
+
$childElement->setAttribute('class', $context->buildCssClass('related-articles'));
|
428 |
+
// TODO RelatedArticles is not covered yet, since AMP didn't get a good structure for it up to date.
|
429 |
+
} else if (Type::is($child, Analytics::getClassName())) {
|
430 |
+
if ($this->buildAnalytics() === null) {
|
431 |
+
$context->addWarning(
|
432 |
+
'Your Instant Article has analytics code, and you didn\'t provide an AMP analytics json. Your data will not be tracked. See the documentation at https://www.ampproject.org/docs/reference/components/amp-analytics on how to build your analytics component for AMP.',
|
433 |
+
$child
|
434 |
+
);
|
435 |
+
}
|
436 |
+
continue;
|
437 |
+
} else if (Type::is($child, Ad::getClassName())) {
|
438 |
+
$childElement = $this->observer->applyFilters('IA_AD', $this->buildAd($child, $context, 'ad'), $child, $context);
|
439 |
+
} else {
|
440 |
+
// Not a know element, bypasses it
|
441 |
+
continue;
|
442 |
+
}
|
443 |
+
|
444 |
+
$context->addItem($childElement);
|
445 |
+
$article->appendChild($childElement);
|
446 |
+
$context->buildSpacingDiv($article);
|
447 |
+
}
|
448 |
+
}
|
449 |
+
|
450 |
+
return $article;
|
451 |
+
}
|
452 |
+
|
453 |
+
public function buildRegularDomElement($context, $child, $cssClass)
|
454 |
+
{
|
455 |
+
$element = $child->toDOMElement($context->getDocument());
|
456 |
+
$element->setAttribute('class', $context->buildCssClass($cssClass));
|
457 |
+
$context->withPreviousElementIdentifier($cssClass);
|
458 |
+
|
459 |
+
return $element;
|
460 |
+
}
|
461 |
+
|
462 |
+
public function transformArticleFooter($context)
|
463 |
+
{
|
464 |
+
$footer = $this->instantArticle->getFooter();
|
465 |
+
if ($footer && $footer->isValid()) {
|
466 |
+
$ampFooter = $context->createElement('footer', null, 'footer');
|
467 |
+
$context->getArticle()->appendChild($ampFooter);
|
468 |
+
|
469 |
+
// Credits
|
470 |
+
$credits = $footer->getCredits();
|
471 |
+
if ($credits) {
|
472 |
+
$ampCredits = $context->createElement('aside', $ampFooter);
|
473 |
+
if (is_array($credits)) {
|
474 |
+
foreach ($credits as $paragraph) {
|
475 |
+
$ampCredits->appendChild($paragraph->toDOMElement($context->getDocument()));
|
476 |
+
}
|
477 |
+
} else {
|
478 |
+
$ampCredits->appendChild($context->getDocument()->createTextNode($credits));
|
479 |
+
}
|
480 |
+
}
|
481 |
+
|
482 |
+
// Copyright
|
483 |
+
$copyright = $footer->getCopyright();
|
484 |
+
if ($copyright) {
|
485 |
+
$ampCopyright = $context->createElement('small', $ampFooter);
|
486 |
+
$ampCopyright->appendChild($copyright->textToDOMDocumentFragment($context->getDocument()));
|
487 |
+
}
|
488 |
+
|
489 |
+
return $ampFooter;
|
490 |
+
}
|
491 |
+
return null;
|
492 |
+
}
|
493 |
+
|
494 |
+
public function buildCustomElementScriptEntry($customElementName, $src, $context)
|
495 |
+
{
|
496 |
+
$script = $context->getDocument()->createElement('script');
|
497 |
+
$script->setAttribute('async', '');
|
498 |
+
$script->setAttribute('custom-element', $customElementName);
|
499 |
+
$script->setAttribute('src', $src);
|
500 |
+
return $script;
|
501 |
+
}
|
502 |
+
|
503 |
+
private function buildImage($image, $context, $cssClass, $withContainer = true, $mediaSizeMode = self::MEDIA_SIZE_MODE_RESPONSIVE)
|
504 |
+
{
|
505 |
+
if ($withContainer) {
|
506 |
+
$ampImgContainer = $context->createElement('div', null, $cssClass);
|
507 |
+
}
|
508 |
+
|
509 |
+
$ampImg = $context->getDocument()->createElement('amp-img');
|
510 |
+
$imageURL = $image->getUrl();
|
511 |
+
|
512 |
+
$imageDimensions = $this->getMediaDimensions($imageURL, AMPContext::MEDIA_TYPE_IMAGE);
|
513 |
+
$imageWidth = $imageDimensions[0];
|
514 |
+
$imageHeight = $imageDimensions[1];
|
515 |
+
|
516 |
+
if ($mediaSizeMode === self::MEDIA_SIZE_MODE_VIEWPORT) {
|
517 |
+
$horizontalScale = self::DEFAULT_WIDTH / $imageWidth;
|
518 |
+
$verticalScale = self::DEFAULT_HEIGHT / $imageHeight;
|
519 |
+
$maxScale = max($horizontalScale, $verticalScale);
|
520 |
+
|
521 |
+
$translateX = (int) (-($imageWidth * $maxScale - self::DEFAULT_WIDTH) / 2);
|
522 |
+
$translateY = (int) (-($imageHeight * $maxScale - self::DEFAULT_HEIGHT) / 2);
|
523 |
+
|
524 |
+
$imageCSSClass = $context->buildCssClass('header-cover-img');
|
525 |
+
$ampImg->setAttribute('class', $imageCSSClass);
|
526 |
+
|
527 |
+
$context->getCssBuilder()->addProperty("amp-img.$imageCSSClass", 'transform', "translate({$translateX}px, {$translateY}px)");
|
528 |
+
|
529 |
+
$containerCSSClass = $ampImgContainer->getAttribute('class');
|
530 |
+
$context->getCssBuilder()
|
531 |
+
->addProperty("div.$containerCSSClass", 'width', self::DEFAULT_WIDTH.'px')
|
532 |
+
->addProperty("div.$containerCSSClass", 'height', self::DEFAULT_HEIGHT.'px')
|
533 |
+
->addProperty("div.$containerCSSClass", 'overflow', 'hidden');
|
534 |
+
|
535 |
+
$imageWidth = (int) ($imageWidth * $maxScale);
|
536 |
+
$imageHeight = (int) ($imageHeight * $maxScale);
|
537 |
+
} else if ($mediaSizeMode === self::MEDIA_SIZE_MODE_SCALED) {
|
538 |
+
// Somehow the full width on mobile is 380, so I resize image height on same ratio
|
539 |
+
$resizedWidthFactor = (double) (self::DEFAULT_WIDTH / (int) $imageWidth);
|
540 |
+
$imageWidth = self::DEFAULT_WIDTH;
|
541 |
+
$imageHeight = (int) ($imageHeight * $resizedWidthFactor);
|
542 |
+
} else {
|
543 |
+
$ampImg->setAttribute('layout', 'responsive');
|
544 |
+
}
|
545 |
+
|
546 |
+
$ampImg->setAttribute('src', $imageURL);
|
547 |
+
$ampImg->setAttribute('width', (string) $imageWidth);
|
548 |
+
$ampImg->setAttribute('height', (string) $imageHeight);
|
549 |
+
|
550 |
+
$caption = $image->getCaption();
|
551 |
+
if ($caption) {
|
552 |
+
$ampFigure = $this->buildCaption($caption, $context, $ampImg);
|
553 |
+
|
554 |
+
// Replaces the top level image element with the figure
|
555 |
+
$ampImg = $ampFigure;
|
556 |
+
}
|
557 |
+
|
558 |
+
if ($withContainer) {
|
559 |
+
$ampImgContainer->appendChild($ampImg);
|
560 |
+
}
|
561 |
+
|
562 |
+
return ($withContainer) ? $ampImgContainer : $ampImg;
|
563 |
+
}
|
564 |
+
|
565 |
+
private function buildGIF($image, $context, $cssClass, $withContainer = true)
|
566 |
+
{
|
567 |
+
if ($withContainer) {
|
568 |
+
$ampImgContainer = $context->createElement('div', null, $cssClass);
|
569 |
+
}
|
570 |
+
|
571 |
+
$ampImg = $context->getDocument()->createElement('amp-anim');
|
572 |
+
$imageURL = $image->getUrl();
|
573 |
+
|
574 |
+
$imageDimensions = $this->getMediaDimensions($imageURL, AMPContext::MEDIA_TYPE_IMAGE);
|
575 |
+
$imageWidth = $imageDimensions[0];
|
576 |
+
$imageHeight = $imageDimensions[1];
|
577 |
+
|
578 |
+
$ampImg->setAttribute('src', $imageURL);
|
579 |
+
$ampImg->setAttribute('width', $imageWidth);
|
580 |
+
$ampImg->setAttribute('height', $imageHeight);
|
581 |
+
|
582 |
+
$caption = $image->getCaption();
|
583 |
+
if ($caption) {
|
584 |
+
$ampFigure = $this->buildCaption($caption, $context, $image);
|
585 |
+
|
586 |
+
// Replaces the top level image with the figure
|
587 |
+
$ampImg = $ampFigure;
|
588 |
+
}
|
589 |
+
|
590 |
+
if ($withContainer) {
|
591 |
+
$ampImgContainer->appendChild($ampImg);
|
592 |
+
}
|
593 |
+
|
594 |
+
return ($withContainer) ? $ampImgContainer : $ampImg;
|
595 |
+
}
|
596 |
+
|
597 |
+
private function buildVideo($video, $context, $cssClass)
|
598 |
+
{
|
599 |
+
$ampVideoContainer = $context->createElement('div', null, $cssClass);
|
600 |
+
|
601 |
+
$ampVideo = $context->getDocument()->createElement('amp-video');
|
602 |
+
$videoUrl = $video->getUrl();
|
603 |
+
|
604 |
+
$videoDimensions = $this->getMediaDimensions($videoUrl, AMPContext::MEDIA_TYPE_VIDEO);
|
605 |
+
$videoWidth = $videoDimensions[0];
|
606 |
+
$videoHeight = $videoDimensions[1];
|
607 |
+
|
608 |
+
$ampVideo->setAttribute('src', $this->ensureHttps($context, $videoUrl));
|
609 |
+
$ampVideo->setAttribute('width', $videoWidth);
|
610 |
+
$ampVideo->setAttribute('height', $videoHeight);
|
611 |
+
|
612 |
+
$caption = $video->getCaption();
|
613 |
+
if ($caption) {
|
614 |
+
$ampFigure = $this->buildCaption($caption, $context, $ampVideo);
|
615 |
+
|
616 |
+
// Replaces the top level video with the figure
|
617 |
+
$ampVideo = $ampFigure;
|
618 |
+
}
|
619 |
+
|
620 |
+
$ampVideoContainer->appendChild($ampVideo);
|
621 |
+
|
622 |
+
return $ampVideoContainer;
|
623 |
+
}
|
624 |
+
|
625 |
+
private function buildAudio($video, $context, $cssClass)
|
626 |
+
{
|
627 |
+
$ampAudio = $context->createElement('div', null, $cssClass);
|
628 |
+
|
629 |
+
// TODO Audio is not yet covered into first version of converter.
|
630 |
+
|
631 |
+
return $ampAudio;
|
632 |
+
}
|
633 |
+
|
634 |
+
private function buildSlideshow($slideshow, $context, $cssClass)
|
635 |
+
{
|
636 |
+
$ampCarouselContainer = $context->createElement('div', null, $cssClass);
|
637 |
+
|
638 |
+
$ampCarousel = $context->getDocument()->createElement('amp-carousel');
|
639 |
+
|
640 |
+
foreach ($slideshow->getArticleImages() as $image) {
|
641 |
+
$ampImage = $this->buildImage($image, $context, 'slideshow-image', true, self::MEDIA_SIZE_MODE_SCALED);
|
642 |
+
$ampCarousel->appendChild($ampImage);
|
643 |
+
|
644 |
+
if (!isset($imageWidth) && !isset($imageHeight)) {
|
645 |
+
$imageUrl = $image->getUrl();
|
646 |
+
$imageDimensions = $this->getMediaDimensions($imageUrl, AMPContext::MEDIA_TYPE_IMAGE);
|
647 |
+
$imageWidth = $imageDimensions[0];
|
648 |
+
$imageHeight = $imageDimensions[1];
|
649 |
+
}
|
650 |
+
}
|
651 |
+
$ampCarousel->setAttribute('width', (string) $imageWidth);
|
652 |
+
$ampCarousel->setAttribute('height', (string) $imageHeight);
|
653 |
+
|
654 |
+
$caption = $slideshow->getCaption();
|
655 |
+
if ($caption) {
|
656 |
+
$ampFigure = $this->buildCaption($caption, $context, $ampCarousel);
|
657 |
+
|
658 |
+
// Replaces the top level carousel with the figure
|
659 |
+
$ampCarousel = $ampFigure;
|
660 |
+
}
|
661 |
+
|
662 |
+
$ampCarouselContainer->appendChild($ampCarousel);
|
663 |
+
|
664 |
+
$context->withPreviousElementIdentifier($cssClass);
|
665 |
+
|
666 |
+
return $ampCarouselContainer;
|
667 |
+
}
|
668 |
+
|
669 |
+
private function buildCaption($caption, $context, $ampCaptionedElement)
|
670 |
+
{
|
671 |
+
$container = $context->createElement('figure', null, 'figure');
|
672 |
+
|
673 |
+
$fontSize = $caption->getFontSize();
|
674 |
+
$cssClass = 'figcaption-' . ($fontSize ? $fontSize : 'small');
|
675 |
+
|
676 |
+
$ampCaption = $context->createElement('figcaption', $container, $cssClass);
|
677 |
+
|
678 |
+
$position = $caption->getPosition();
|
679 |
+
if (!$position) {
|
680 |
+
$position = Caption::POSITION_BELOW;
|
681 |
+
}
|
682 |
+
|
683 |
+
if ($position === Caption::POSITION_BELOW) {
|
684 |
+
$container->appendChild($ampCaptionedElement);
|
685 |
+
$container->appendChild($ampCaption);
|
686 |
+
} else {
|
687 |
+
$container->appendChild($ampCaption);
|
688 |
+
$container->appendChild($ampCaptionedElement);
|
689 |
+
}
|
690 |
+
|
691 |
+
// Title
|
692 |
+
$title = $caption->getTitle();
|
693 |
+
if ($title) {
|
694 |
+
$ampCaptionTitle = $context->createElement('h1', $ampCaption);
|
695 |
+
$ampTitleText = $title->textToDOMDocumentFragment($context->getDocument());
|
696 |
+
$ampCaptionTitle->appendChild($ampTitleText);
|
697 |
+
}
|
698 |
+
|
699 |
+
// SubTitle
|
700 |
+
$subTitle = $caption->getSubTitle();
|
701 |
+
if ($subTitle) {
|
702 |
+
$ampCaptionSubTitle = $context->createElement('h2', $ampCaption);
|
703 |
+
$ampSubTitleText = $subTitle->textToDOMDocumentFragment($context->getDocument());
|
704 |
+
$ampCaptionSubTitle->appendChild($ampSubTitleText);
|
705 |
+
}
|
706 |
+
|
707 |
+
// Text
|
708 |
+
$ampCaptionText = $caption->textToDOMDocumentFragment($context->getDocument());
|
709 |
+
$ampCaption->appendChild($ampCaptionText);
|
710 |
+
|
711 |
+
// Credit
|
712 |
+
$credit = $caption->getCredit();
|
713 |
+
if ($credit) {
|
714 |
+
$ampCaptionCredit = $context->createElement('cite', $ampCaption);
|
715 |
+
$ampCreditText = $credit->textToDOMDocumentFragment($context->getDocument());
|
716 |
+
$ampCaptionCredit->appendChild($ampCreditText);
|
717 |
+
}
|
718 |
+
|
719 |
+
$ampCSSClasses = array();
|
720 |
+
$ampCSSClasses[] = $context->buildCssClass('figcaption');
|
721 |
+
|
722 |
+
if ($caption->getFontSize()) {
|
723 |
+
$ampCSSClasses[] = $context->buildCssClass($caption->getFontSize());
|
724 |
+
} else {
|
725 |
+
$ampCSSClasses[] = $context->buildCssClass(Caption::SIZE_SMALL);
|
726 |
+
}
|
727 |
+
if ($caption->getTextAlignment()) {
|
728 |
+
$ampCSSClasses[] = $context->buildCssClass($caption->getTextAlignment());
|
729 |
+
}
|
730 |
+
if ($caption->getPosition()) {
|
731 |
+
$ampCSSClasses[] = $context->buildCssClass($caption->getPosition());
|
732 |
+
}
|
733 |
+
if ($caption->getVerticalAlignment()) {
|
734 |
+
$ampCSSClasses[] = $context->buildCssClass($caption->getVerticalAlignment());
|
735 |
+
}
|
736 |
+
|
737 |
+
$ampCaption->setAttribute('class', implode(' ', $ampCSSClasses));
|
738 |
+
|
739 |
+
return $container;
|
740 |
+
}
|
741 |
+
|
742 |
+
private function buildIframe($interactive, $context, $cssClass, $isCaptionable)
|
743 |
+
{
|
744 |
+
$srcUrl = $interactive->getSource();
|
745 |
+
|
746 |
+
// Based on $srcUrl build:
|
747 |
+
// TODO check URLs for youtube, Facebook, Twitter, Instagram, Vimeo, Vine, playbuzz, soundcloud
|
748 |
+
|
749 |
+
$iframeContainer = $context->createElement('div', null, $cssClass);
|
750 |
+
|
751 |
+
$ampIframe = $context->getDocument()->createElement('amp-iframe');
|
752 |
+
$ampIframe->setAttribute('src', $this->ensureHttps($context, $srcUrl));
|
753 |
+
$ampIframe->setAttribute('width', self::DEFAULT_WIDTH);
|
754 |
+
$ampIframe->setAttribute('height', self::DEFAULT_HEIGHT);
|
755 |
+
$ampIframe->setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
756 |
+
$ampIframe->setAttribute('layout', 'responsive');
|
757 |
+
$ampIframe->setAttribute('frameborder', '0');
|
758 |
+
|
759 |
+
if ($isCaptionable) {
|
760 |
+
$caption = $interactive->getCaption();
|
761 |
+
if ($caption) {
|
762 |
+
$ampFigure = $this->buildCaption($caption, $context, $ampIframe);
|
763 |
+
|
764 |
+
// Replaces the top level iframe with the figure
|
765 |
+
$ampIframe = $ampFigure;
|
766 |
+
}
|
767 |
+
}
|
768 |
+
|
769 |
+
$iframeContainer->appendChild($ampIframe);
|
770 |
+
|
771 |
+
return $iframeContainer;
|
772 |
+
}
|
773 |
+
|
774 |
+
private function buildAd($ad, $context, $cssClass)
|
775 |
+
{
|
776 |
+
$srcUrl = $ad->getSource();
|
777 |
+
$html = $ad->getHtml();
|
778 |
+
$height = $ad->getHeight();
|
779 |
+
$width = $ad->getWidth();
|
780 |
+
|
781 |
+
$ampAdContainer = $context->createElement('div', null, $cssClass);
|
782 |
+
$ampAd = $context->createElement('amp-iframe', $ampAdContainer);
|
783 |
+
|
784 |
+
if (!Type::isTextEmpty($srcUrl)) {
|
785 |
+
$ampAd->setAttribute('src', $this->ensureHttps($context, $srcUrl));
|
786 |
+
}
|
787 |
+
$ampAd->setAttribute('width', $width ? $width : self::DEFAULT_WIDTH);
|
788 |
+
$ampAd->setAttribute('height', $height ? $height : self::DEFAULT_HEIGHT);
|
789 |
+
$ampAd->setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
790 |
+
$ampAd->setAttribute('layout', 'responsive');
|
791 |
+
$ampAd->setAttribute('frameborder', '0');
|
792 |
+
|
793 |
+
if ($html) {
|
794 |
+
$iframeBody = $context->getDocument()->importNode($html, true);
|
795 |
+
$ampAd->appendChild($iframeBody);
|
796 |
+
}
|
797 |
+
|
798 |
+
return $ampAdContainer;
|
799 |
+
}
|
800 |
+
|
801 |
+
private function buildMaps($map, $context, $cssClass)
|
802 |
+
{
|
803 |
+
$geoTag = $map->getGeotag();
|
804 |
+
if (!$geoTag) {
|
805 |
+
$context->addWarning('Map::getGeotag() returned an empty map definition.', $map);
|
806 |
+
return $context->createElement('div');
|
807 |
+
}
|
808 |
+
|
809 |
+
$googleAPIKey = isset($this->properties[self::GOOGLE_MAPS_KEY]) ? $this->properties[self::GOOGLE_MAPS_KEY] : null;
|
810 |
+
$googleAPIKey = $this->getObserver()->applyFilters('GET_GOOGLE_MAPS_KEY', $googleAPIKey, $this->properties, $context);
|
811 |
+
|
812 |
+
if (Type::isTextEmpty($googleAPIKey)) {
|
813 |
+
$context->addWarning('Facebook Instant Article Maps are converted into Google Maps by default. To accomplish that, you will need to inform into your $properties parameter the "google_maps_key" => "<your key>". Find more here how to get your Google Maps key: https://developers.google.com/maps/documentation/javascript/get-api-key', $map);
|
814 |
+
return $context->createElement('div');
|
815 |
+
}
|
816 |
+
|
817 |
+
$coordinates = $this->extractCoordinatesFromGeotag($geoTag->getScript());
|
818 |
+
if (!$coordinates || empty($coordinates)) {
|
819 |
+
$context->addWarning('Map::getGeotag invalid or incompatible. We could not extract latitud and/or longitud from it.', $geoTag->getScript());
|
820 |
+
return $context->createElement('div');
|
821 |
+
}
|
822 |
+
$latitud = $coordinates[0];
|
823 |
+
$longitud = $coordinates[1];
|
824 |
+
|
825 |
+
// By default it will use Google Maps as mapping system
|
826 |
+
// The URL should be: https://www.google.com/maps/embed/v1/place?key=<API_GOOGLE_KEY>q=%2244.0,122.0%22
|
827 |
+
$srcUrl = "https://www.google.com/maps/embed/v1/place?key=$googleAPIKey&q=%22$latitud,$longitud%22";
|
828 |
+
|
829 |
+
// <amp-iframe
|
830 |
+
// width="600"
|
831 |
+
// height="400"
|
832 |
+
// layout="responsive"
|
833 |
+
// sandbox="allow-scripts allow-same-origin allow-popups"
|
834 |
+
// frameborder="0"
|
835 |
+
// src="https://www.google.com/maps/embed/v1/place?key=<key>&q="44.0,122.0">
|
836 |
+
// </amp-iframe>
|
837 |
+
|
838 |
+
$ampMap = $context->createElement('div', null, $cssClass);
|
839 |
+
|
840 |
+
$ampIframe = $context->createElement('amp-iframe', $ampMap);
|
841 |
+
$ampIframe->setAttribute('src', $srcUrl);
|
842 |
+
$ampIframe->setAttribute('width', self::DEFAULT_WIDTH);
|
843 |
+
$ampIframe->setAttribute('height', self::DEFAULT_HEIGHT);
|
844 |
+
$ampIframe->setAttribute('sandbox', 'allow-scripts allow-same-origin allow-popups');
|
845 |
+
$ampIframe->setAttribute('layout', 'responsive');
|
846 |
+
$ampIframe->setAttribute('frameborder', '0');
|
847 |
+
|
848 |
+
$caption = $map->getCaption();
|
849 |
+
if ($caption) {
|
850 |
+
// Replace the top level map with the wrapped figure with caption
|
851 |
+
$ampMap = $this->buildCaption($caption, $context, $ampMap);
|
852 |
+
}
|
853 |
+
|
854 |
+
return $ampMap;
|
855 |
+
}
|
856 |
+
|
857 |
+
/**
|
858 |
+
* Extracts latitud and longitud from Geotag json.
|
859 |
+
* Example json expected on $mapJson:
|
860 |
+
* <code>
|
861 |
+
* {
|
862 |
+
* "type": "Feature",
|
863 |
+
* "geometry": {
|
864 |
+
* "type": "Point",
|
865 |
+
* "coordinates": [23.166667, 89.216667] // This is the content we are looking for.
|
866 |
+
* },
|
867 |
+
* "properties": {
|
868 |
+
* "title": "Jessore, Bangladesh",
|
869 |
+
* "radius": 750000,
|
870 |
+
* "pivot": true,
|
871 |
+
* "style": "satellite",
|
872 |
+
* }
|
873 |
+
* }
|
874 |
+
* </code>
|
875 |
+
* @param string $mapJson The geotag format json string. It will look for the geometry->coordinates attribute.
|
876 |
+
*/
|
877 |
+
private function extractCoordinatesFromGeotag($mapJson)
|
878 |
+
{
|
879 |
+
$geotag = json_decode($mapJson, true);
|
880 |
+
if (isset($geotag['type'])) {
|
881 |
+
if ($geotag['type'] === 'FeatureCollection' && isset($geotag['features'])) {
|
882 |
+
$features = $geotag['features'];
|
883 |
+
foreach ($features as $feature) {
|
884 |
+
if (isset($feature['geometry']) && isset($feature['geometry']['coordinates'])) {
|
885 |
+
return $feature['geometry']['coordinates'];
|
886 |
+
}
|
887 |
+
}
|
888 |
+
} else if (isset($geotag['geometry']) && isset($geotag['geometry']['coordinates'])) {
|
889 |
+
return $geotag['geometry']['coordinates'];
|
890 |
+
}
|
891 |
+
}
|
892 |
+
return null;
|
893 |
+
}
|
894 |
+
|
895 |
+
private function buildCustomCSS($context)
|
896 |
+
{
|
897 |
+
$ampCustomCSS = $context->getDocument()->createElement('style');
|
898 |
+
$ampCustomCSS->setAttribute('amp-custom', '');
|
899 |
+
// Note: Custom CSS content will be generated after the whole article is processed
|
900 |
+
return $ampCustomCSS;
|
901 |
+
}
|
902 |
+
|
903 |
+
/**
|
904 |
+
* Retrieves the Width and Height of the media.
|
905 |
+
* Media size lookup order:
|
906 |
+
* 1. The array $properties[MEDIA_SIZES_KEY][$mediaURL]
|
907 |
+
* 2. Local directory cache (from getMediaDimensionsFromCache(), configured by $properties[MEDIA_CACHE_FOLDER_KEY])
|
908 |
+
* 3. Download the image and get the size, if enabled by $properties[ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY]
|
909 |
+
* @param string $mediaURL The media's URL
|
910 |
+
* @param string $mediaType One of the MEDIA_TYPE_* constants (optional)
|
911 |
+
* @return array [ width, height ]
|
912 |
+
*/
|
913 |
+
public function getMediaDimensions($mediaURL, $mediaType = null)
|
914 |
+
{
|
915 |
+
if (array_key_exists(self::MEDIA_SIZES_KEY, $this->properties) &&
|
916 |
+
array_key_exists($mediaURL, $this->properties[self::MEDIA_SIZES_KEY])) {
|
917 |
+
return $this->properties[self::MEDIA_SIZES_KEY][$mediaURL];
|
918 |
+
}
|
919 |
+
|
920 |
+
$mediaDimensions = $this->getMediaDimensionsFromCache($mediaURL);
|
921 |
+
if ($mediaDimensions) {
|
922 |
+
return $mediaDimensions;
|
923 |
+
}
|
924 |
+
|
925 |
+
if ($mediaType === AMPContext::MEDIA_TYPE_IMAGE &&
|
926 |
+
array_key_exists(self::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY, $this->properties) &&
|
927 |
+
$this->properties[self::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY] === true) {
|
928 |
+
$retrievedSizes = getimagesize($mediaURL);
|
929 |
+
if ($retrievedSizes && !empty($retrievedSizes) && $retrievedSizes[0] !== 0) {
|
930 |
+
return $retrievedSizes;
|
931 |
+
}
|
932 |
+
}
|
933 |
+
|
934 |
+
$width = array_key_exists(self::DEFAULT_MEDIA_WIDTH_KEY, $this->properties)
|
935 |
+
? $this->properties[self::DEFAULT_MEDIA_WIDTH_KEY]
|
936 |
+
: self::DEFAULT_WIDTH;
|
937 |
+
$height = array_key_exists(self::DEFAULT_MEDIA_HEIGHT_KEY, $this->properties)
|
938 |
+
? $this->properties[self::DEFAULT_MEDIA_HEIGHT_KEY]
|
939 |
+
: self::DEFAULT_HEIGHT;
|
940 |
+
|
941 |
+
return array($width, $height);
|
942 |
+
}
|
943 |
+
|
944 |
+
private function getMediaDimensionsFromCache($mediaURL)
|
945 |
+
{
|
946 |
+
if (!array_key_exists(self::MEDIA_CACHE_FOLDER_KEY, $this->properties)) {
|
947 |
+
return null;
|
948 |
+
}
|
949 |
+
|
950 |
+
$mediaCacheFolder = $this->properties[self::MEDIA_CACHE_FOLDER_KEY];
|
951 |
+
if (!file_exists($mediaCacheFolder)) {
|
952 |
+
return null;
|
953 |
+
}
|
954 |
+
|
955 |
+
$fileName = basename($mediaURL);
|
956 |
+
if (!$fileName) {
|
957 |
+
return null;
|
958 |
+
}
|
959 |
+
|
960 |
+
$cachedFile = $mediaCacheFolder . DIRECTORY_SEPARATOR . $fileName;
|
961 |
+
if (!file_exists($cachedFile)) {
|
962 |
+
return null;
|
963 |
+
}
|
964 |
+
|
965 |
+
return getimagesize($cachedFile);
|
966 |
+
}
|
967 |
+
|
968 |
+
public function getCustomCSS($context)
|
969 |
+
{
|
970 |
+
$stylesFolder = (array_key_exists(AMPArticle::STYLES_FOLDER_KEY, $this->properties)
|
971 |
+
? $this->properties[AMPArticle::STYLES_FOLDER_KEY]
|
972 |
+
: __DIR__) . '/';
|
973 |
+
|
974 |
+
$styleName = $this->instantArticle->getStyle();
|
975 |
+
if ($styleName == null) {
|
976 |
+
$styleName = 'default';
|
977 |
+
}
|
978 |
+
// Try to get the Instant Articles styles from properties
|
979 |
+
if (array_key_exists(AMPArticle::OVERRIDE_STYLES_KEY, $this->properties)) {
|
980 |
+
$styles = $this->properties[AMPArticle::OVERRIDE_STYLES_KEY];
|
981 |
+
} else {
|
982 |
+
if (!file_exists($stylesFolder . $styleName . '.style.json')) {
|
983 |
+
$stylesFile = file_get_contents(__DIR__ . '/configuration/default-amp.style.json');
|
984 |
+
$styles = json_decode($stylesFile, true);
|
985 |
+
} else {
|
986 |
+
$stylesFile = file_get_contents($stylesFolder . $styleName . '.style.json');
|
987 |
+
$styles = json_decode($stylesFile, true);
|
988 |
+
}
|
989 |
+
}
|
990 |
+
|
991 |
+
if (file_exists($stylesFolder . 'global.amp-custom.css')) {
|
992 |
+
$globalCSSFile = file_get_contents($stylesFolder . 'global.amp-custom.css');
|
993 |
+
$globalCSSFile = str_replace(array("\r", "\n"), ' ', $globalCSSFile);
|
994 |
+
}
|
995 |
+
|
996 |
+
if (file_exists($stylesFolder . $styleName . '.amp-custom.css')) {
|
997 |
+
$customCSSFile = file_get_contents($stylesFolder . $styleName . '.amp-custom.css');
|
998 |
+
$customCSSFile = str_replace(array("\r", "\n"), ' ', $customCSSFile);
|
999 |
+
}
|
1000 |
+
|
1001 |
+
if (!isset($globalCSSFile) && !isset($customCSSFile)) {
|
1002 |
+
$defaultCSSFile = file_get_contents(__DIR__ . '/configuration/global.amp.css');
|
1003 |
+
$defaultCSSFile = str_replace(array("\r", "\n"), ' ', $defaultCSSFile);
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
$this->articleColorsStyles($styles, $context);
|
1007 |
+
$this->articleHeadStyles($styles, $context);
|
1008 |
+
$this->articleBodyStyles($styles, $context);
|
1009 |
+
$this->articleQuoteStyles($styles, $context);
|
1010 |
+
$this->articleCaptionStyles($styles, $context);
|
1011 |
+
$this->articleFooterStyles($styles, $context);
|
1012 |
+
return
|
1013 |
+
$context->getCssBuilder()->build(false).
|
1014 |
+
(isset($globalCSSFile) ? $globalCSSFile : '').
|
1015 |
+
(isset($customCSSFile) ? $customCSSFile : '').
|
1016 |
+
(!isset($globalCSSFile) && !isset($customCSSFile) ? $defaultCSSFile : '');
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
private function articleColorsStyles($styles, $context)
|
1020 |
+
{
|
1021 |
+
$backgroundColor = AMPArticle::toRGB($styles['background_color']);
|
1022 |
+
$context->getCssBuilder()->addProperty('html', 'background-color', $backgroundColor);
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
private function articleHeadStyles($styles, $context)
|
1026 |
+
{
|
1027 |
+
$mappings = array(
|
1028 |
+
$context->buildCssSelector('header-category') => 'kicker',
|
1029 |
+
$context->buildCssSelector('header-h1') => 'title',
|
1030 |
+
$context->buildCssSelector('header-h2') => 'subtitle',
|
1031 |
+
$context->buildCssSelector('header h3') => 'byline'
|
1032 |
+
);
|
1033 |
+
|
1034 |
+
$dateFormatMappings = array(
|
1035 |
+
'MONTH_AND_DAY' => 'F d',
|
1036 |
+
'MONTH_AND_YEAR' => 'F Y',
|
1037 |
+
'MONTH_DAY_YEAR' => 'F d, Y',
|
1038 |
+
'YEAR' => 'Y',
|
1039 |
+
'MONTH_DAY_YEAR_TIME' => 'F d, Y H:i A',
|
1040 |
+
);
|
1041 |
+
if (array_key_exists('date_style', $styles)) {
|
1042 |
+
$dateFormat = $styles['date_style'];
|
1043 |
+
if (array_key_exists($dateFormat, $dateFormatMappings)) {
|
1044 |
+
$this->dateFormat = $dateFormatMappings[$dateFormat];
|
1045 |
+
}
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
return $this->buildCSSRulesFromMappings($mappings, $styles, $context) .
|
1049 |
+
$this->articleLogo($styles, $context);
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
private function tryGetColor($sourceStyles, $colorStylePropertyName)
|
1053 |
+
{
|
1054 |
+
if (array_key_exists($colorStylePropertyName, $sourceStyles)) {
|
1055 |
+
$color = $sourceStyles[$colorStylePropertyName];
|
1056 |
+
if ($color) {
|
1057 |
+
return self::toRGB($color);
|
1058 |
+
}
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
return null;
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
private function articleLogo($styles, $context)
|
1065 |
+
{
|
1066 |
+
$headerStyles = $styles['header'];
|
1067 |
+
|
1068 |
+
$backgroundColor = $this->tryGetColor($headerStyles, 'background_color');
|
1069 |
+
if ($backgroundColor) {
|
1070 |
+
$context->getCssBuilder()->addToSelector('header-bar', 'background-color', $backgroundColor);
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
$barColor = $this->tryGetColor($headerStyles, 'bar_color');
|
1074 |
+
if ($barColor) {
|
1075 |
+
$cssSelector= '.' . $context->buildCssClass('spacing') . '.after-header-bar';
|
1076 |
+
$context->getCssBuilder()->addProperty($cssSelector, 'border-top-color', $barColor);
|
1077 |
+
$context->getCssBuilder()->addProperty($cssSelector, 'border-top-style', 'solid');
|
1078 |
+
$context->getCssBuilder()->addProperty($cssSelector, 'border-top-width', '1px');
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
if (!array_key_exists('logo', $headerStyles)) {
|
1082 |
+
return '';
|
1083 |
+
}
|
1084 |
+
$logoStyles = $headerStyles['logo'];
|
1085 |
+
|
1086 |
+
$dataURL = array_key_exists('dataURL', $logoStyles)
|
1087 |
+
? $logoStyles['dataURL']
|
1088 |
+
: null;
|
1089 |
+
$fullResURL = $logoStyles['full_resolution_url'];
|
1090 |
+
|
1091 |
+
$defaultLogoHeight = $this->observer->applyFilters('DEFAULT_LOGO_HEIGHT', self::DEFAULT_LOGO_HEIGHT);
|
1092 |
+
$defaultLogoWidth = $this->observer->applyFilters('DEFAULT_LOGO_WIDTH', self::DEFAULT_LOGO_WIDTH);
|
1093 |
+
$logoWidth = $logoStyles['full_resolution_width'];
|
1094 |
+
$logoHeight = $logoStyles['full_resolution_height'];
|
1095 |
+
$resizeScale = $headerStyles['logo_scale'] || 1.0;
|
1096 |
+
$resizeScale *= min(
|
1097 |
+
$defaultLogoHeight / $logoHeight,
|
1098 |
+
$defaultLogoWidth / $logoWidth
|
1099 |
+
);
|
1100 |
+
|
1101 |
+
$logoURL = $dataURL ? $dataURL : $fullResURL;
|
1102 |
+
$scaledLogoWidth = (int) ($logoWidth * $resizeScale);
|
1103 |
+
$scaledLogoHeight = (int) ($logoHeight * $resizeScale);
|
1104 |
+
$this->logo = new AMPImage($logoURL, $scaledLogoWidth, $scaledLogoHeight);
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
private function articleBodyStyles($styles, $context)
|
1108 |
+
{
|
1109 |
+
$mappings = array(
|
1110 |
+
$context->buildCssSelector('h1') => 'primary_heading',
|
1111 |
+
$context->buildCssSelector('h2') => 'secondary_heading',
|
1112 |
+
$context->buildCssSelector('p') => 'body_text',
|
1113 |
+
$context->buildCssSelector('article a') => 'inline_link',
|
1114 |
+
);
|
1115 |
+
$this->buildCSSRulesFromMappings($mappings, $styles, $context);
|
1116 |
+
}
|
1117 |
+
|
1118 |
+
private function articleQuoteStyles($styles, $context)
|
1119 |
+
{
|
1120 |
+
$mappings = array(
|
1121 |
+
$context->buildCssSelector('blockquote') => 'block_quote',
|
1122 |
+
$context->buildCssSelector('pullquote') => 'pull_quote',
|
1123 |
+
$context->buildCssSelector('pullquote cite') => 'pull_quote_attribution',
|
1124 |
+
);
|
1125 |
+
$this->buildCSSRulesFromMappings($mappings, $styles, $context);
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
private function articleCaptionStyles($styles, $context)
|
1129 |
+
{
|
1130 |
+
$mappings = array(
|
1131 |
+
'.ia2amp-op-small h1' => 'caption_title_small',
|
1132 |
+
'.ia2amp-op-small h2' => 'caption_description_small',
|
1133 |
+
|
1134 |
+
'.ia2amp-op-medium h1' => 'caption_title',
|
1135 |
+
'.ia2amp-op-medium h2' => 'caption_description',
|
1136 |
+
|
1137 |
+
'.ia2amp-op-large h1' => 'caption_title_large',
|
1138 |
+
'.ia2amp-op-large h2' => 'caption_description_large',
|
1139 |
+
|
1140 |
+
'.ia2amp-op-extra-large h1' => 'caption_title_extra_large',
|
1141 |
+
'.ia2amp-op-extra-large h2' => 'caption_description_extra_large',
|
1142 |
+
|
1143 |
+
'.ia2amp-figcaption cite' => 'caption_credit',
|
1144 |
+
);
|
1145 |
+
$this->buildCSSRulesFromMappings($mappings, $styles, $context);
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
private function articleFooterStyles($styles, $context)
|
1149 |
+
{
|
1150 |
+
$mappings = array(
|
1151 |
+
$context->buildCssSelector('footer') => 'footer',
|
1152 |
+
);
|
1153 |
+
$this->buildCSSRulesFromMappings($mappings, $styles, $context);
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
private function buildTextCSSDeclarationBlock($selector, $textStyles, $textType, $context)
|
1157 |
+
{
|
1158 |
+
$mappings = array(
|
1159 |
+
'font-family' => 'font',
|
1160 |
+
'text-align' => 'text_alignment',
|
1161 |
+
'display' => 'display',
|
1162 |
+
);
|
1163 |
+
$filteredMappings = AMPArticle::filterMappings($mappings, $textStyles);
|
1164 |
+
|
1165 |
+
$textTransformMappings = array(
|
1166 |
+
'ALL_CAPS' => 'uppercase',
|
1167 |
+
'ALL_LOWER_CASE' => 'lowercase',
|
1168 |
+
'NONE' => 'none',
|
1169 |
+
);
|
1170 |
+
if (array_key_exists('capitalization', $textStyles)) {
|
1171 |
+
$filteredMappings['text-transform'] = $textTransformMappings[$textStyles['capitalization']];
|
1172 |
+
}
|
1173 |
+
|
1174 |
+
if (array_key_exists('underline', $textStyles) && $textStyles['underline'] != 'NONE') {
|
1175 |
+
$filteredMappings['text-decoration'] = 'underline';
|
1176 |
+
}
|
1177 |
+
|
1178 |
+
if (array_key_exists('background_color', $textStyles)) {
|
1179 |
+
$filteredMappings['background-color'] = AMPArticle::toRGB($textStyles['background_color']);
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
if (array_key_exists('color', $textStyles)) {
|
1183 |
+
$filteredMappings['color'] = AMPArticle::toRGB($textStyles['color']);
|
1184 |
+
}
|
1185 |
+
|
1186 |
+
$spacingMappings = array(
|
1187 |
+
'NONE' => 0,
|
1188 |
+
'DOCUMENT_MARGIN' => AMPArticle::DEFAULT_MARGIN,
|
1189 |
+
'EXTRA_SMALL' => 16,
|
1190 |
+
'SMALL' => 32,
|
1191 |
+
'MEDIUM' => 46,
|
1192 |
+
'LARGE' => 64,
|
1193 |
+
'EXTRA_LARGE' => 96,
|
1194 |
+
);
|
1195 |
+
$marginMappings = AMPArticle::getSpacingDeclarationBlocks($spacingMappings, 'margin', $textStyles);
|
1196 |
+
$filteredMappings = array_merge($filteredMappings, $marginMappings);
|
1197 |
+
$paddingMappings = AMPArticle::getSpacingDeclarationBlocks($spacingMappings, 'padding', $textStyles);
|
1198 |
+
$filteredMappings = array_merge($filteredMappings, $paddingMappings);
|
1199 |
+
|
1200 |
+
$borderMappings = AMPArticle::getBorderDeclarationBlocks($textStyles);
|
1201 |
+
$filteredMappings = array_merge($filteredMappings, $borderMappings);
|
1202 |
+
|
1203 |
+
foreach ($filteredMappings as $filteredKey => $cssValue) {
|
1204 |
+
$context->getCssBuilder()->addProperty($selector, $filteredKey, $cssValue);
|
1205 |
+
}
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
private static function filterMappings($mappings, $styles)
|
1209 |
+
{
|
1210 |
+
$result = array();
|
1211 |
+
foreach ($mappings as $cssKey => $styleKey) {
|
1212 |
+
if (array_key_exists($styleKey, $styles)) {
|
1213 |
+
$result[$cssKey] = $styles[$styleKey];
|
1214 |
+
}
|
1215 |
+
}
|
1216 |
+
return $result;
|
1217 |
+
}
|
1218 |
+
|
1219 |
+
private static function getSpacingDeclarationBlocks($spacingMappings, $spacingType, $textStyles)
|
1220 |
+
{
|
1221 |
+
$directions = array(
|
1222 |
+
'top',
|
1223 |
+
'right',
|
1224 |
+
'bottom',
|
1225 |
+
'left',
|
1226 |
+
);
|
1227 |
+
if (!array_key_exists($spacingType, $textStyles)) {
|
1228 |
+
return array();
|
1229 |
+
}
|
1230 |
+
$spacingStyles = $textStyles[$spacingType];
|
1231 |
+
$spacings = array();
|
1232 |
+
foreach ($directions as $direction) {
|
1233 |
+
$spacing = AMPArticle::getDirectionSpacing($spacingMappings, $direction, $spacingStyles);
|
1234 |
+
$spacings[] = $spacing != 0 ? $spacing . 'px' : '0';
|
1235 |
+
}
|
1236 |
+
return array($spacingType => implode(' ', $spacings));
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
private function buildCSSRulesFromMappings($mappings, $styles, $context)
|
1240 |
+
{
|
1241 |
+
foreach ($mappings as $selector => $objectKey) {
|
1242 |
+
if (array_key_exists($objectKey, $styles)) {
|
1243 |
+
$this->buildTextCSSDeclarationBlock($selector, $styles[$objectKey], $objectKey, $context);
|
1244 |
+
}
|
1245 |
+
}
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
private static function getDirectionSpacing($spacingMappings, $direction, $spacingStyles)
|
1249 |
+
{
|
1250 |
+
return array_key_exists($direction, $spacingStyles)
|
1251 |
+
? AMPArticle::getSpacing($spacingMappings, $spacingStyles[$direction])
|
1252 |
+
: 0;
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
private static function getSpacing($spacingMappings, $spacingDirectionStyles)
|
1256 |
+
{
|
1257 |
+
$size = $spacingDirectionStyles['size'];
|
1258 |
+
$scalingFactor = $spacingDirectionStyles['scaling_factor'];
|
1259 |
+
return $spacingMappings[$size] * $scalingFactor;
|
1260 |
+
}
|
1261 |
+
|
1262 |
+
private static function getBorderDeclarationBlocks($textStyles)
|
1263 |
+
{
|
1264 |
+
$directions = array(
|
1265 |
+
'top',
|
1266 |
+
'right',
|
1267 |
+
'bottom',
|
1268 |
+
'left',
|
1269 |
+
);
|
1270 |
+
if (!array_key_exists('border', $textStyles)) {
|
1271 |
+
return array();
|
1272 |
+
}
|
1273 |
+
$borderStyles = $textStyles['border'];
|
1274 |
+
$declarationBlocks = array();
|
1275 |
+
$borderWidths = array();
|
1276 |
+
foreach ($directions as $direction) {
|
1277 |
+
if (array_key_exists($direction, $borderStyles)) {
|
1278 |
+
$borderDirectionStyles = $borderStyles[$direction];
|
1279 |
+
$borderWidth = $borderDirectionStyles['width'];
|
1280 |
+
|
1281 |
+
if (array_key_exists('color', $borderDirectionStyles)) {
|
1282 |
+
$declarationBlocks["border-$direction-color"] = AMPArticle::toRGB($borderDirectionStyles['color']);
|
1283 |
+
}
|
1284 |
+
} else {
|
1285 |
+
$borderWidth = 0;
|
1286 |
+
}
|
1287 |
+
$borderWidths[] = $borderWidth !== 0 ? $borderWidth . 'px' : '0';
|
1288 |
+
}
|
1289 |
+
$declarationBlocks['border-width'] = implode(' ', $borderWidths);
|
1290 |
+
$declarationBlocks['border-style'] = 'solid';
|
1291 |
+
return $declarationBlocks;
|
1292 |
+
}
|
1293 |
+
|
1294 |
+
public static function toRGB($color)
|
1295 |
+
{
|
1296 |
+
// Normalize #FFFFFF to ffffff
|
1297 |
+
$color = strtolower($color);
|
1298 |
+
if (substr($color, 0, 1) == '#') {
|
1299 |
+
$color = substr($color, 1);
|
1300 |
+
}
|
1301 |
+
|
1302 |
+
// Match correct patter for each strlen
|
1303 |
+
switch (strlen($color)) {
|
1304 |
+
case 3:
|
1305 |
+
// RGB
|
1306 |
+
$a = null;
|
1307 |
+
$r = hexdec(substr($color, 0, 1) . substr($color, 0, 1));
|
1308 |
+
$g = hexdec(substr($color, 1, 1) . substr($color, 1, 1));
|
1309 |
+
$b = hexdec(substr($color, 2, 1) . substr($color, 2, 1));
|
1310 |
+
break;
|
1311 |
+
case 4:
|
1312 |
+
// ARGB
|
1313 |
+
$a = hexdec(substr($color, 0, 1) . substr($color, 0, 1));
|
1314 |
+
$r = hexdec(substr($color, 1, 1) . substr($color, 1, 1));
|
1315 |
+
$g = hexdec(substr($color, 2, 1) . substr($color, 2, 1));
|
1316 |
+
$b = hexdec(substr($color, 3, 1) . substr($color, 3, 1));
|
1317 |
+
break;
|
1318 |
+
case 6:
|
1319 |
+
// RRGGBB
|
1320 |
+
$a = null;
|
1321 |
+
$r = hexdec(substr($color, 0, 2));
|
1322 |
+
$g = hexdec(substr($color, 2, 2));
|
1323 |
+
$b = hexdec(substr($color, 4, 2));
|
1324 |
+
break;
|
1325 |
+
case 8:
|
1326 |
+
// AARRGGBB
|
1327 |
+
$a = hexdec(substr($color, 0, 2));
|
1328 |
+
$r = hexdec(substr($color, 2, 2));
|
1329 |
+
$g = hexdec(substr($color, 4, 2));
|
1330 |
+
$b = hexdec(substr($color, 6, 2));
|
1331 |
+
break;
|
1332 |
+
}
|
1333 |
+
|
1334 |
+
$alpha = 1.0;
|
1335 |
+
// Alpha range is 0-1, not 0-255: https://www.w3.org/TR/css-color-4/
|
1336 |
+
if ($a !== null) {
|
1337 |
+
$alpha = round($a / 255.0, 2);
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
$rgb = [ $r, $g, $b ];
|
1341 |
+
$rgb = implode(',', $rgb);
|
1342 |
+
|
1343 |
+
return $alpha === 1.0
|
1344 |
+
? 'rgb(' . $rgb . ')'
|
1345 |
+
: 'rgba(' . $rgb . ',' . $alpha . ')';
|
1346 |
+
}
|
1347 |
+
|
1348 |
+
public function buildSchemaOrgMetadata($context)
|
1349 |
+
{
|
1350 |
+
$header = $this->instantArticle->getHeader();
|
1351 |
+
$published = $header->getPublished();
|
1352 |
+
$modified = $header->getModified();
|
1353 |
+
|
1354 |
+
$metadata = array(
|
1355 |
+
'@context' => 'http://schema.org',
|
1356 |
+
'@type' => 'NewsArticle',
|
1357 |
+
'mainEntityOfPage' => $this->instantArticle->getCanonicalURL(),
|
1358 |
+
'headline' => $this->instantArticle->getHeader()->getTitle()->getPlainText(),
|
1359 |
+
'datePublished' => date_format($published->getDatetime(), 'c'),
|
1360 |
+
'description' => $this->instantArticle->getFirstParagraph()->getPlainText(),
|
1361 |
+
);
|
1362 |
+
|
1363 |
+
if ($modified) {
|
1364 |
+
$metadata['dateModified'] = date_format($modified->getDatetime(), 'c');
|
1365 |
+
}
|
1366 |
+
|
1367 |
+
$authors = $header->getAuthors();
|
1368 |
+
foreach ($authors as $author) {
|
1369 |
+
$metadata['author'] = array(
|
1370 |
+
'@type' => 'Person',
|
1371 |
+
'name' => $author->getName(),
|
1372 |
+
);
|
1373 |
+
break;
|
1374 |
+
}
|
1375 |
+
|
1376 |
+
$cover = $this->observer->applyFilters('AMP_GETMETADATAIMAGE', $this->getMetadataImage($this->properties), $this->properties);
|
1377 |
+
if ($cover) {
|
1378 |
+
$metadata['image'] = $cover;
|
1379 |
+
}
|
1380 |
+
|
1381 |
+
$publisher = $this->observer->applyFilters('AMP_GETPUBLISHER', $this->getPublisher($this->properties), $this->properties);
|
1382 |
+
if ($publisher) {
|
1383 |
+
$metadata['publisher'] = $publisher;
|
1384 |
+
}
|
1385 |
+
|
1386 |
+
// Prevent URL slashes to be escaped
|
1387 |
+
return json_encode($metadata, JSON_UNESCAPED_SLASHES);
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
public function getPublisher($properties)
|
1391 |
+
{
|
1392 |
+
$publisher = array_key_exists(self::PUBLISHER_KEY, $properties) ? $properties[self::PUBLISHER_KEY] : null;
|
1393 |
+
|
1394 |
+
if ($publisher && Type::is($publisher, Type::STRING)) {
|
1395 |
+
// String values will be treated as organization names
|
1396 |
+
$publisher = array(
|
1397 |
+
'@type' => 'Organization',
|
1398 |
+
'name' => $publisher,
|
1399 |
+
);
|
1400 |
+
}
|
1401 |
+
|
1402 |
+
return $publisher;
|
1403 |
+
}
|
1404 |
+
|
1405 |
+
public function getMetadataImage($properties)
|
1406 |
+
{
|
1407 |
+
$imageURL = null;
|
1408 |
+
$header = $this->instantArticle->getHeader();
|
1409 |
+
|
1410 |
+
$cover = $header->getCover();
|
1411 |
+
if ($cover) {
|
1412 |
+
$imageURL = $this->getImageURLFromElement($cover);
|
1413 |
+
}
|
1414 |
+
if (!$imageURL) {
|
1415 |
+
// Article does not have cover image, look for the first suitable children
|
1416 |
+
foreach ($this->instantArticle->getChildren() as $child) {
|
1417 |
+
$imageURL = $this->getImageURLFromElement($child);
|
1418 |
+
if ($imageURL) {
|
1419 |
+
break;
|
1420 |
+
}
|
1421 |
+
}
|
1422 |
+
}
|
1423 |
+
|
1424 |
+
if ($imageURL) {
|
1425 |
+
$imageDimensions = $this->getMediaDimensions($imageURL, AMPContext::MEDIA_TYPE_IMAGE);
|
1426 |
+
|
1427 |
+
return array(
|
1428 |
+
'@type' => 'ImageObject',
|
1429 |
+
'url' => $imageURL,
|
1430 |
+
'width' => $imageDimensions[0],
|
1431 |
+
'height' => $imageDimensions[1],
|
1432 |
+
);
|
1433 |
+
}
|
1434 |
+
|
1435 |
+
return null;
|
1436 |
+
}
|
1437 |
+
|
1438 |
+
private function getImageURLFromElement($element)
|
1439 |
+
{
|
1440 |
+
if (Type::is($element, Image::getClassName())) {
|
1441 |
+
return $element->getUrl();
|
1442 |
+
} else if (Type::is($element, Slideshow::getClassName())) {
|
1443 |
+
foreach ($element->getArticleImages() as $articleImage) {
|
1444 |
+
if ($articleImage->isValid()) {
|
1445 |
+
return $articleImage->getUrl();
|
1446 |
+
}
|
1447 |
+
}
|
1448 |
+
}
|
1449 |
+
|
1450 |
+
return null;
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
private function ensureHttps($context, $url)
|
1454 |
+
{
|
1455 |
+
if (strpos($url, 'http:') !== false) {
|
1456 |
+
$context->addWarning('URLs for videos, iframes, analytics and ads should be HTTPS. Double check if this one is still valid using HTTPS protocol', $url);
|
1457 |
+
}
|
1458 |
+
return Type::isTextEmpty($url) ? $url : preg_replace("/^http:/i", "https:", $url);
|
1459 |
+
}
|
1460 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPCaption.php
ADDED
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Elements\Caption;
|
12 |
+
|
13 |
+
class AMPCaption
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* @var Context the conversion context holder
|
17 |
+
*/
|
18 |
+
private $context;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var Caption the Element Caption
|
22 |
+
*/
|
23 |
+
private $caption;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var DOMNode The DOMNode html element being captionized
|
27 |
+
*/
|
28 |
+
private $ampTag;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var DOMNode The Final container for Caption
|
32 |
+
*/
|
33 |
+
private $container;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var DOMNode The figcaption DOMNode that will hold the text content.
|
37 |
+
*/
|
38 |
+
private $ampCaption;
|
39 |
+
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param Caption $caption The element from SDK that contains all Caption data.
|
43 |
+
* @param Context $context Conversion context var.
|
44 |
+
*/
|
45 |
+
public function __construct($caption, $context, $ampCaptionedElement)
|
46 |
+
{
|
47 |
+
$this->caption = $caption;
|
48 |
+
$this->context = $context;
|
49 |
+
$this->ampTag = $ampCaptionedElement;
|
50 |
+
}
|
51 |
+
|
52 |
+
public static function create($caption, $context, $ampCaptionedElement)
|
53 |
+
{
|
54 |
+
return new AMPCaption($caption, $context, $ampCaptionedElement);
|
55 |
+
}
|
56 |
+
|
57 |
+
private function genContainer()
|
58 |
+
{
|
59 |
+
$this->container = $this->context->createElement('figure', null, 'figure');
|
60 |
+
}
|
61 |
+
|
62 |
+
private function appendCaptioned()
|
63 |
+
{
|
64 |
+
$fontSize = $this->caption->getFontSize();
|
65 |
+
$cssClass = 'figcaption-' . ($fontSize ? $fontSize : 'small');
|
66 |
+
|
67 |
+
$this->ampCaption = $this->context->createElement('figcaption', null, $cssClass);
|
68 |
+
|
69 |
+
$position = $this->caption->getPosition();
|
70 |
+
if (!$position) {
|
71 |
+
$position = Caption::POSITION_BELOW;
|
72 |
+
}
|
73 |
+
|
74 |
+
if ($position === Caption::POSITION_BELOW) {
|
75 |
+
$this->container->appendChild($this->ampTag);
|
76 |
+
$this->container->appendChild($this->ampCaption);
|
77 |
+
} else {
|
78 |
+
$this->container->appendChild($this->ampCaption);
|
79 |
+
$this->container->appendChild($this->ampTag);
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
private function genTitle()
|
84 |
+
{
|
85 |
+
// Title
|
86 |
+
$title = $this->caption->getTitle();
|
87 |
+
if ($title) {
|
88 |
+
$ampTitle = $this->context->createElement('h1', $this->ampCaption);
|
89 |
+
$ampTitleText = $title->textToDOMDocumentFragment($this->context->getDocument());
|
90 |
+
$ampTitle->appendChild($ampTitleText);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
private function genSubtitle()
|
95 |
+
{
|
96 |
+
// SubTitle
|
97 |
+
$subTitle = $this->caption->getSubTitle();
|
98 |
+
if ($subTitle) {
|
99 |
+
$ampSubTitle = $this->context->createElement('h2', $this->ampCaption);
|
100 |
+
$ampSubTitleText = $subTitle->textToDOMDocumentFragment($this->context->getDocument());
|
101 |
+
$ampSubTitle->appendChild($ampSubTitleText);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
private function genText()
|
106 |
+
{
|
107 |
+
// Text
|
108 |
+
$ampText = $this->caption->textToDOMDocumentFragment($this->context->getDocument());
|
109 |
+
$this->ampCaption->appendChild($ampText);
|
110 |
+
}
|
111 |
+
|
112 |
+
private function genCredit()
|
113 |
+
{
|
114 |
+
// Credit
|
115 |
+
$credit = $this->caption->getCredit();
|
116 |
+
if ($credit) {
|
117 |
+
$ampCredit = $this->context->createElement('cite', $this->ampCaption);
|
118 |
+
$ampCreditText = $credit->textToDOMDocumentFragment($this->context->getDocument());
|
119 |
+
$ampCredit->appendChild($ampCreditText);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
private function applyStyleClasses()
|
124 |
+
{
|
125 |
+
$ampCSSClasses = array();
|
126 |
+
$ampCSSClasses[] = $this->context->buildCssClass('figcaption');
|
127 |
+
|
128 |
+
if ($this->caption->getFontSize()) {
|
129 |
+
$ampCSSClasses[] = $this->context->buildCssClass($this->caption->getFontSize());
|
130 |
+
} else {
|
131 |
+
$ampCSSClasses[] = $this->context->buildCssClass(Caption::SIZE_SMALL);
|
132 |
+
}
|
133 |
+
if ($this->caption->getTextAlignment()) {
|
134 |
+
$ampCSSClasses[] = $this->context->buildCssClass($this->caption->getTextAlignment());
|
135 |
+
}
|
136 |
+
if ($this->caption->getPosition()) {
|
137 |
+
$ampCSSClasses[] = $this->context->buildCssClass($this->caption->getPosition());
|
138 |
+
}
|
139 |
+
if ($this->caption->getVerticalAlignment()) {
|
140 |
+
$ampCSSClasses[] = $this->context->buildCssClass($this->caption->getVerticalAlignment());
|
141 |
+
}
|
142 |
+
|
143 |
+
$this->ampCaption->setAttribute('class', implode(' ', $ampCSSClasses));
|
144 |
+
}
|
145 |
+
|
146 |
+
public function build()
|
147 |
+
{
|
148 |
+
$this->genContainer();
|
149 |
+
$this->appendCaptioned();
|
150 |
+
$this->genTitle();
|
151 |
+
$this->genSubtitle();
|
152 |
+
$this->genText();
|
153 |
+
$this->genCredit();
|
154 |
+
$this->applyStyleClasses();
|
155 |
+
|
156 |
+
return $this->container;
|
157 |
+
}
|
158 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPContext.php
ADDED
@@ -0,0 +1,709 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Elements\InstantArticle;
|
12 |
+
|
13 |
+
use Facebook\InstantArticles\Validators\Type;
|
14 |
+
use Facebook\InstantArticles\Utils\Warning;
|
15 |
+
use Facebook\InstantArticles\Utils\CSSBuilder;
|
16 |
+
|
17 |
+
class AMPContext
|
18 |
+
{
|
19 |
+
private $instantArticle;
|
20 |
+
private $document;
|
21 |
+
|
22 |
+
private $html;
|
23 |
+
private $head;
|
24 |
+
private $body;
|
25 |
+
private $article;
|
26 |
+
private $header;
|
27 |
+
private $headerBar;
|
28 |
+
private $headerBarLogo;
|
29 |
+
private $headerTitle;
|
30 |
+
private $headerAuthor;
|
31 |
+
private $headerKicker;
|
32 |
+
private $headerDate;
|
33 |
+
private $articleItems = array();
|
34 |
+
private $footer;
|
35 |
+
|
36 |
+
private $cssPrefix;
|
37 |
+
private $previousElementIdentifier;
|
38 |
+
private $previousSpacing;
|
39 |
+
|
40 |
+
private $warnings = array();
|
41 |
+
|
42 |
+
private $cssBuilder;
|
43 |
+
|
44 |
+
private $mediaSizes;
|
45 |
+
private $mediaCacheFolder;
|
46 |
+
private $enableDownloadForMediaSizing;
|
47 |
+
private $defaultWidth;
|
48 |
+
private $defaultHeight;
|
49 |
+
|
50 |
+
const MEDIA_TYPE_IMAGE = 'image';
|
51 |
+
const MEDIA_TYPE_VIDEO = 'video';
|
52 |
+
|
53 |
+
const DEFAULT_WIDTH = AMPArticle::DEFAULT_WIDTH;
|
54 |
+
const DEFAULT_HEIGHT = AMPArticle::DEFAULT_HEIGHT;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Private constructor. Use self::create($document, $instantArticle)
|
58 |
+
*/
|
59 |
+
private function __construct()
|
60 |
+
{
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Factory method to create the AMPContext
|
65 |
+
* @param DOMDocument $document The root document used on the context. If null informed, a new one will be created.
|
66 |
+
* @param InstantArticle $instantArticle The Element InstantArticle that will be used during conversion.
|
67 |
+
* @param string $cssPrefix The css prefix for building element classes.
|
68 |
+
*/
|
69 |
+
public static function create($document, $instantArticle, $cssPrefix = "ia2amp-")
|
70 |
+
{
|
71 |
+
$context = new self();
|
72 |
+
|
73 |
+
return $context->withDocument($document)
|
74 |
+
->withInstantArticle($instantArticle)
|
75 |
+
->withCssPrefix($cssPrefix)
|
76 |
+
->withCssBuilder(new CSSBuilder($cssPrefix));
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Sets the document. Private method since this should be unmodifiable.
|
81 |
+
* @param DOMDocument $document The root document to be used.
|
82 |
+
* @return $this reference.
|
83 |
+
*/
|
84 |
+
private function withDocument($document)
|
85 |
+
{
|
86 |
+
if (!isset($document) || $document === null) {
|
87 |
+
$document = new \DOMDocument();
|
88 |
+
}
|
89 |
+
Type::enforce($document, \DOMDocument::class);
|
90 |
+
$this->document = $document;
|
91 |
+
return $this;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Sets the css prefix. Private method since this should be unmodifiable.
|
96 |
+
* @param string $cssPrefix The css prefix to construct element classes.
|
97 |
+
* @return $this reference.
|
98 |
+
*/
|
99 |
+
private function withCssPrefix($cssPrefix)
|
100 |
+
{
|
101 |
+
Type::enforce($cssPrefix, Type::STRING);
|
102 |
+
$this->cssPrefix = $cssPrefix;
|
103 |
+
return $this;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Sets the CSSBuilder.
|
108 |
+
* @param CSSBuilder $cssBuilder The css builder instance to be used.
|
109 |
+
* @return $this reference.
|
110 |
+
*/
|
111 |
+
public function withCssBuilder($cssBuilder)
|
112 |
+
{
|
113 |
+
Type::enforce($cssBuilder, CSSBuilder::getClassName());
|
114 |
+
$this->cssBuilder = $cssBuilder;
|
115 |
+
return $this;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Gets the CssBuilder being used in this context.
|
120 |
+
* @return CSSBuilder being used in this context.
|
121 |
+
*/
|
122 |
+
public function getCssBuilder()
|
123 |
+
{
|
124 |
+
return $this->cssBuilder;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Gets the root document being used in this context.
|
129 |
+
* @return DOMDocument $document The root document.
|
130 |
+
*/
|
131 |
+
public function getDocument()
|
132 |
+
{
|
133 |
+
return $this->document;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Creates an element named by $tagName using the $document.
|
138 |
+
* @param string $tagName The tag name that will be used: <tagName>
|
139 |
+
* @param array(<string>=><string>) $attributes mapped array of attributes to be set to this Element being created.
|
140 |
+
* @param string $cssClass The element class for styling purposes.
|
141 |
+
* @param $DOMNode $container The container element where the new created element will be appended. Optional.
|
142 |
+
* @return DOMElement <$tagName> element using the DOMDocument $document from context.
|
143 |
+
*/
|
144 |
+
public function createElement($tagName, $container = null, $cssClass = null, $attributes = null)
|
145 |
+
{
|
146 |
+
$element = $this->getDocument()->createElement($tagName);
|
147 |
+
if (!isset($attributes) || !$attributes) {
|
148 |
+
$attributes = array();
|
149 |
+
}
|
150 |
+
if (!Type::isTextEmpty($cssClass)) {
|
151 |
+
$attributes['class'] = $this->buildCssClass($cssClass);
|
152 |
+
}
|
153 |
+
foreach ($attributes as $name => $value) {
|
154 |
+
$element->setAttribute($name, $value);
|
155 |
+
}
|
156 |
+
$this->withPreviousElementIdentifier($cssClass);
|
157 |
+
|
158 |
+
if (isset($container) && $container) {
|
159 |
+
Type::enforce($container, get_class(new \DOMNode()));
|
160 |
+
$container->appendChild($element);
|
161 |
+
}
|
162 |
+
|
163 |
+
return $element;
|
164 |
+
}
|
165 |
+
|
166 |
+
|
167 |
+
public function buildCssClass($cssClassName)
|
168 |
+
{
|
169 |
+
return $this->cssPrefix.$cssClassName;
|
170 |
+
}
|
171 |
+
|
172 |
+
public function buildCssSelector($cssClassName)
|
173 |
+
{
|
174 |
+
return '.'.$this->buildCssClass($cssClassName);
|
175 |
+
}
|
176 |
+
|
177 |
+
public function withPreviousElementIdentifier($identifier)
|
178 |
+
{
|
179 |
+
$this->previousElementIdentifier = $identifier;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* This will create a div with spacing, telling on class about the previous element.
|
184 |
+
* @param \DOMElement $container where this spacing will be appended to.
|
185 |
+
*/
|
186 |
+
public function buildSpacingDiv($container)
|
187 |
+
{
|
188 |
+
if ($this->previousSpacing) {
|
189 |
+
if (!Type::isTextEmpty($this->previousElementIdentifier)) {
|
190 |
+
$class = $this->previousSpacing->getAttribute('class');
|
191 |
+
$class = $class.' before-'.$this->previousElementIdentifier;
|
192 |
+
$this->previousSpacing->setAttribute('class', $class);
|
193 |
+
}
|
194 |
+
}
|
195 |
+
$previousClass = Type::isTextEmpty($this->previousElementIdentifier) ? '' : ' after-'.$this->previousElementIdentifier;
|
196 |
+
$this->previousSpacing = $this->createElement('div', $container, 'spacing'.$previousClass);
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Sets the InstantArticle reference. Private method since this should be unmodifiable.
|
201 |
+
* @param InstantArticle $instantArticle The element being used as conversion.
|
202 |
+
* @return $this reference.
|
203 |
+
*/
|
204 |
+
private function withInstantArticle($instantArticle)
|
205 |
+
{
|
206 |
+
Type::enforce($instantArticle, InstantArticle::class);
|
207 |
+
$this->instantArticle = $instantArticle;
|
208 |
+
return $this;
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Gets the InstantArticle being used in this context.
|
213 |
+
* @return InstantArticle $instantArticle conversion instance.
|
214 |
+
*/
|
215 |
+
public function getInstantArticle()
|
216 |
+
{
|
217 |
+
return $this->instantArticle;
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Sets the <html> full document.
|
222 |
+
* WARNING: by setting this, will overwrite the full document, be sure to
|
223 |
+
* have a valid AMP document while setting.
|
224 |
+
* @param DOMElement $html The html tag, should be a <html> tag.
|
225 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <html> tag.
|
226 |
+
* @return $this instance.
|
227 |
+
*/
|
228 |
+
public function withHtml($html)
|
229 |
+
{
|
230 |
+
Type::enforceElementTag($html, 'html');
|
231 |
+
$this->html = $html;
|
232 |
+
return $this;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Checks the existence of <html> tag.
|
237 |
+
* @return boolean true if <html> tag was set, false otherwise.
|
238 |
+
*/
|
239 |
+
public function hasHtml()
|
240 |
+
{
|
241 |
+
return isset($this->html) && $this->html !== null;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Gets the <html> tag.
|
246 |
+
* @return DOMElement $html The <html> tag.
|
247 |
+
*/
|
248 |
+
public function getHtml()
|
249 |
+
{
|
250 |
+
return $this->html;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Sets the <head> tag.
|
255 |
+
* WARNING: by setting this, will overwrite the head from document, be sure to
|
256 |
+
* have a valid AMP head while setting.
|
257 |
+
* @param DOMElement $head The head tag, should be a <head> tag.
|
258 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <head> tag.
|
259 |
+
* @return $this instance.
|
260 |
+
*/
|
261 |
+
public function withHead($head)
|
262 |
+
{
|
263 |
+
Type::enforceElementTag($head, 'head');
|
264 |
+
$this->head = $head;
|
265 |
+
return $this;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Checks the existence of <head> tag.
|
270 |
+
* @return boolean true if <head> tag was set, false otherwise.
|
271 |
+
*/
|
272 |
+
public function hasHead()
|
273 |
+
{
|
274 |
+
return isset($this->head) && $this->head !== null;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Gets the <head> tag.
|
279 |
+
* @return DOMElement $head The <head> tag.
|
280 |
+
*/
|
281 |
+
public function getHead()
|
282 |
+
{
|
283 |
+
return $this->head;
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Sets the <body> tag.
|
288 |
+
* WARNING: by setting this, will overwrite the body from document, be sure to
|
289 |
+
* have a valid AMP body while setting.
|
290 |
+
* @param DOMElement $body The body tag, should be a <body> tag.
|
291 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <body> tag.
|
292 |
+
* @return $this instance.
|
293 |
+
*/
|
294 |
+
public function withBody($body)
|
295 |
+
{
|
296 |
+
Type::enforceElementTag($body, 'body');
|
297 |
+
$this->body = $body;
|
298 |
+
return $this;
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Checks the existence of <body> tag.
|
303 |
+
* @return boolean true if <body> tag was set, false otherwise.
|
304 |
+
*/
|
305 |
+
public function hasBody()
|
306 |
+
{
|
307 |
+
return isset($this->body) && $this->body !== null;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Gets the <body> tag.
|
312 |
+
* @return DOMElement $body The <body> tag.
|
313 |
+
*/
|
314 |
+
public function getBody()
|
315 |
+
{
|
316 |
+
return $this->body;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Sets the <article> tag.
|
321 |
+
* WARNING: by setting this, will overwrite the article from document, be sure to
|
322 |
+
* have a valid AMP article while setting.
|
323 |
+
* @param DOMElement $article The article tag, should be a <article> tag.
|
324 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <article> tag.
|
325 |
+
* @return $this instance.
|
326 |
+
*/
|
327 |
+
public function withArticle($article)
|
328 |
+
{
|
329 |
+
Type::enforceElementTag($article, 'article');
|
330 |
+
$this->article = $article;
|
331 |
+
return $this;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Checks the existence of <article> tag.
|
336 |
+
* @return boolean true if <article> tag was set, false otherwise.
|
337 |
+
*/
|
338 |
+
public function hasArticle()
|
339 |
+
{
|
340 |
+
return isset($this->article) && $this->article !== null;
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Gets the <article> tag.
|
345 |
+
* @return DOMElement $article The <article> tag.
|
346 |
+
*/
|
347 |
+
public function getArticle()
|
348 |
+
{
|
349 |
+
return $this->article;
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Sets the <header> tag.
|
354 |
+
* WARNING: by setting this, will overwrite the header from document, be sure to
|
355 |
+
* have a valid AMP header while setting.
|
356 |
+
* @param DOMElement $header The header tag, should be a <header> tag.
|
357 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <header> tag.
|
358 |
+
* @return $this instance.
|
359 |
+
*/
|
360 |
+
public function withHeader($header)
|
361 |
+
{
|
362 |
+
Type::enforceElementTag($header, 'header');
|
363 |
+
$this->header = $header;
|
364 |
+
return $this;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Checks the existence of <header> tag.
|
369 |
+
* @return boolean true if <header> tag was set, false otherwise.
|
370 |
+
*/
|
371 |
+
public function hasHeader()
|
372 |
+
{
|
373 |
+
return isset($this->header) && $this->header !== null;
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Gets the <header> tag.
|
378 |
+
* @return DOMElement $header The <header> tag.
|
379 |
+
*/
|
380 |
+
public function getHeader()
|
381 |
+
{
|
382 |
+
return $this->header;
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Sets the headerBar <div> tag.
|
387 |
+
* WARNING: by setting this, will overwrite the headerBar from document, be sure to
|
388 |
+
* have a valid AMP headerBar while setting.
|
389 |
+
* @param DOMElement $headerBar The headerBar tag, should be a <div> tag.
|
390 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <div> tag.
|
391 |
+
* @return $this instance.
|
392 |
+
*/
|
393 |
+
public function withHeaderBar($headerBar)
|
394 |
+
{
|
395 |
+
Type::enforceElementTag($headerBar, 'div');
|
396 |
+
$this->headerBar = $headerBar;
|
397 |
+
return $this;
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Checks the existence of headerBar <div> tag.
|
402 |
+
* @return boolean true if headerBar <div> tag was set, false otherwise.
|
403 |
+
*/
|
404 |
+
public function hasHeaderBar()
|
405 |
+
{
|
406 |
+
return isset($this->headerBar) && $this->headerBar !== null;
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Gets the <headerBar> tag.
|
411 |
+
* @return DOMElement $headerBar The <headerBar> tag.
|
412 |
+
*/
|
413 |
+
public function getHeaderBar()
|
414 |
+
{
|
415 |
+
return $this->headerBar;
|
416 |
+
}
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Sets the headerBarLogo <div> tag.
|
420 |
+
* WARNING: by setting this, will overwrite the headerBarLogo from document, be sure to
|
421 |
+
* have a valid AMP headerBarLogo while setting.
|
422 |
+
* @param DOMElement $headerBarLogo The headerBarLogo tag, should be a <div> tag.
|
423 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <div> tag.
|
424 |
+
* @return $this instance.
|
425 |
+
*/
|
426 |
+
public function withHeaderBarLogo($headerBarLogo)
|
427 |
+
{
|
428 |
+
Type::enforceElementTag($headerBarLogo, 'div');
|
429 |
+
$this->headerBarLogo = $headerBarLogo;
|
430 |
+
return $this;
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* Checks the existence of headerBarLogo <div> tag.
|
435 |
+
* @return boolean true if headerBarLogo <div> tag was set, false otherwise.
|
436 |
+
*/
|
437 |
+
public function hasHeaderBarLogo()
|
438 |
+
{
|
439 |
+
return isset($this->headerBarLogo) && $this->headerBarLogo !== null;
|
440 |
+
}
|
441 |
+
|
442 |
+
/**
|
443 |
+
* Gets the <headerBarLogo> tag.
|
444 |
+
* @return DOMElement $headerBarLogo The <headerBarLogo> tag.
|
445 |
+
*/
|
446 |
+
public function getHeaderBarLogo()
|
447 |
+
{
|
448 |
+
return $this->headerBarLogo;
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Sets the <h1> title tag.
|
453 |
+
* WARNING: by setting this, will overwrite the title from document, be sure to
|
454 |
+
* have a valid AMP title while setting.
|
455 |
+
* @param DOMElement $h1 The title tag, should be a <h1> tag.
|
456 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <h1> tag.
|
457 |
+
* @return $this instance.
|
458 |
+
*/
|
459 |
+
public function withHeaderTitle($h1)
|
460 |
+
{
|
461 |
+
Type::enforceElementTag($h1, 'h1');
|
462 |
+
$this->headerTitle = $h1;
|
463 |
+
return $this;
|
464 |
+
}
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Checks the existence of <h1> title tag.
|
468 |
+
* @return boolean true if <h1> title tag was set, false otherwise.
|
469 |
+
*/
|
470 |
+
public function hasHeaderTitle()
|
471 |
+
{
|
472 |
+
return isset($this->headerTitle) && $this->headerTitle !== null;
|
473 |
+
}
|
474 |
+
|
475 |
+
/**
|
476 |
+
* Gets the <h1> title tag.
|
477 |
+
* @return DOMElement $headerTitle The <h1> title tag.
|
478 |
+
*/
|
479 |
+
public function getHeaderTitle()
|
480 |
+
{
|
481 |
+
return $this->headerTitle;
|
482 |
+
}
|
483 |
+
|
484 |
+
/**
|
485 |
+
* Sets the <h3> author tag.
|
486 |
+
* WARNING: by setting this, will overwrite the author from document, be sure to
|
487 |
+
* have a valid AMP author while setting.
|
488 |
+
* @param DOMElement $h3 The author tag, should be a <h3> tag.
|
489 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <h3> tag.
|
490 |
+
* @return $this instance.
|
491 |
+
*/
|
492 |
+
public function withHeaderAuthor($h3)
|
493 |
+
{
|
494 |
+
Type::enforceElementTag($h3, 'h3');
|
495 |
+
$this->headerAuthor = $h3;
|
496 |
+
return $this;
|
497 |
+
}
|
498 |
+
|
499 |
+
/**
|
500 |
+
* Checks the existence of <h3> author tag.
|
501 |
+
* @return boolean true if <h3> author tag was set, false otherwise.
|
502 |
+
*/
|
503 |
+
public function hasHeaderAuthor()
|
504 |
+
{
|
505 |
+
return isset($this->headerAuthor) && $this->headerAuthor !== null;
|
506 |
+
}
|
507 |
+
|
508 |
+
/**
|
509 |
+
* Gets the <h3> author tag.
|
510 |
+
* @return DOMElement $headerAuthor The <h3> tag.
|
511 |
+
*/
|
512 |
+
public function getHeaderAuthor()
|
513 |
+
{
|
514 |
+
return $this->headerAuthor;
|
515 |
+
}
|
516 |
+
|
517 |
+
/**
|
518 |
+
* Sets the <h2> kicker tag.
|
519 |
+
* WARNING: by setting this, will overwrite the kicker from document, be sure to
|
520 |
+
* have a valid AMP kicker while setting.
|
521 |
+
* @param DOMElement $h2 The kicker tag, should be a <h2> tag.
|
522 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <h2> tag.
|
523 |
+
* @return $this instance.
|
524 |
+
*/
|
525 |
+
public function withHeaderKicker($h2)
|
526 |
+
{
|
527 |
+
Type::enforceElementTag($h2, 'h2');
|
528 |
+
$this->headerKicker = $h2;
|
529 |
+
return $this;
|
530 |
+
}
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Checks the existence of <h2> kicker tag.
|
534 |
+
* @return boolean true if <h2> kicker tag was set, false otherwise.
|
535 |
+
*/
|
536 |
+
public function hasHeaderKicker()
|
537 |
+
{
|
538 |
+
return isset($this->headerKicker) && $this->headerKicker !== null;
|
539 |
+
}
|
540 |
+
|
541 |
+
/**
|
542 |
+
* Gets the <h2> kicker tag.
|
543 |
+
* @return DOMElement $headerKicker The <h2> kicker tag.
|
544 |
+
*/
|
545 |
+
public function getHeaderKicker()
|
546 |
+
{
|
547 |
+
return $this->headerKicker;
|
548 |
+
}
|
549 |
+
|
550 |
+
/**
|
551 |
+
* Sets the <h3> date tag.
|
552 |
+
* WARNING: by setting this, will overwrite the date from document, be sure to
|
553 |
+
* have a valid AMP date while setting.
|
554 |
+
* @param DOMElement $h3 The date tag, should be a <h3> tag.
|
555 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <h3> tag.
|
556 |
+
* @return $this instance.
|
557 |
+
*/
|
558 |
+
public function withHeaderDate($h3)
|
559 |
+
{
|
560 |
+
Type::enforceElementTag($h3, 'h3');
|
561 |
+
$this->headerDate = $h3;
|
562 |
+
return $this;
|
563 |
+
}
|
564 |
+
|
565 |
+
/**
|
566 |
+
* Checks the existence of <h3> date tag.
|
567 |
+
* @return boolean true if <h3> date tag was set, false otherwise.
|
568 |
+
*/
|
569 |
+
public function hasHeaderDate()
|
570 |
+
{
|
571 |
+
return isset($this->headerDate) && $this->headerDate !== null;
|
572 |
+
}
|
573 |
+
|
574 |
+
/**
|
575 |
+
* Gets the <h3> date tag.
|
576 |
+
* @return DOMElement $headerDate The <h3> tag.
|
577 |
+
*/
|
578 |
+
public function getHeaderDate()
|
579 |
+
{
|
580 |
+
return $this->headerDate;
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Add new items to the document
|
585 |
+
*/
|
586 |
+
public function addItem($item)
|
587 |
+
{
|
588 |
+
$element = new \DOMElement('dummy');
|
589 |
+
Type::enforce($item, get_class($element));
|
590 |
+
$this->articleItems[] = $item;
|
591 |
+
}
|
592 |
+
|
593 |
+
/**
|
594 |
+
* Sets the <footer> tag.
|
595 |
+
* WARNING: by setting this, will overwrite the footer from document, be sure to
|
596 |
+
* have a valid AMP footer while setting.
|
597 |
+
* @param DOMElement $footer The footer tag, should be a <footer> tag.
|
598 |
+
* @throws InvalidArgumentException case not a DOMElement or not a <footer> tag.
|
599 |
+
* @return $this instance.
|
600 |
+
*/
|
601 |
+
public function withFooter($footer)
|
602 |
+
{
|
603 |
+
Type::enforceElementTag($footer, 'footer');
|
604 |
+
$this->footer = $footer;
|
605 |
+
return $this;
|
606 |
+
}
|
607 |
+
|
608 |
+
/**
|
609 |
+
* Checks the existence of <footer> tag.
|
610 |
+
* @return boolean true if <footer> tag was set, false otherwise.
|
611 |
+
*/
|
612 |
+
public function hasFooter()
|
613 |
+
{
|
614 |
+
return isset($this->footer) && $this->footer !== null;
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Gets the <footer> tag.
|
619 |
+
* @return DOMElement $footer The <footer> tag.
|
620 |
+
*/
|
621 |
+
public function getFooter()
|
622 |
+
{
|
623 |
+
return $this->footer;
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Use this method to add a new warning message to the context when something unexpected happened.
|
628 |
+
* @param string $message The message warning.
|
629 |
+
* @param mixed $contextObj an object to be stringified to better understand the context where this warning was generated.
|
630 |
+
* @param Exception $exception **optional** The exception that generated this warning.
|
631 |
+
*/
|
632 |
+
public function addWarning($message, $contextObj, $exception = null)
|
633 |
+
{
|
634 |
+
$this->warnings[] = new Warning($message, $contextObj, $exception);
|
635 |
+
return $this;
|
636 |
+
}
|
637 |
+
|
638 |
+
/**
|
639 |
+
* @return The warnings from the context.
|
640 |
+
*/
|
641 |
+
public function getWarnings()
|
642 |
+
{
|
643 |
+
return $this->warnings;
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* @param array $mediaSizes The map of URLs and sizes already defined.
|
648 |
+
* @param string|file $mediaCacheFolder Where the cache is stored.
|
649 |
+
* @param boolean $enableDownloadForMediaSizing Indicates wheather the images will be downloaded or not to check sizes.
|
650 |
+
* @param int $defaultWidth The default width that will be used to image in case no dimensions is found for this image.
|
651 |
+
* @param int $defaultHeight The default height that will be used to image in case no dimensions is found for this image.
|
652 |
+
* @return $this instance.
|
653 |
+
*/
|
654 |
+
public function withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight)
|
655 |
+
{
|
656 |
+
$this->mediaSizes = $mediaSizes;
|
657 |
+
$this->mediaCacheFolder = $mediaCacheFolder;
|
658 |
+
$this->enableDownloadForMediaSizing = $enableDownloadForMediaSizing;
|
659 |
+
$this->defaultWidth = $defaultWidth;
|
660 |
+
$this->defaultHeight = $defaultHeight;
|
661 |
+
return $this;
|
662 |
+
}
|
663 |
+
|
664 |
+
/**
|
665 |
+
* Returns an array(width, height) based on that image URL.
|
666 |
+
* @param string $mediaURL
|
667 |
+
* @param string $mediaType: Possible values: AMPContext::MEDIA_TYPE_IMAGE and AMPContext::MEDIA_TYPE_VIDEO.
|
668 |
+
* @return array with 2 possitions, first being width, second being the height.
|
669 |
+
*/
|
670 |
+
public function getMediaDimensions($mediaURL, $mediaType = null)
|
671 |
+
{
|
672 |
+
if ($this->mediaSizes && array_key_exists($mediaURL, $this->mediaSizes)) {
|
673 |
+
return $this->mediaSizes[$mediaURL];
|
674 |
+
}
|
675 |
+
|
676 |
+
$mediaDimensions = $this->getMediaDimensionsFromCache($mediaURL);
|
677 |
+
if ($mediaDimensions) {
|
678 |
+
return $mediaDimensions;
|
679 |
+
}
|
680 |
+
|
681 |
+
if ($mediaType === AMPContext::MEDIA_TYPE_IMAGE && $this->enableDownloadForMediaSizing) {
|
682 |
+
$retrievedSizes = getimagesize($mediaURL);
|
683 |
+
if ($retrievedSizes && !empty($retrievedSizes) && $retrievedSizes[0] !== 0) {
|
684 |
+
return $retrievedSizes;
|
685 |
+
}
|
686 |
+
}
|
687 |
+
|
688 |
+
return array($this->defaultWidth, $this->defaultHeight);
|
689 |
+
}
|
690 |
+
|
691 |
+
private function getMediaDimensionsFromCache($mediaURL)
|
692 |
+
{
|
693 |
+
if (!$this->mediaCacheFolder || !file_exists($this->mediaCacheFolder)) {
|
694 |
+
return null;
|
695 |
+
}
|
696 |
+
|
697 |
+
$fileName = basename($mediaURL);
|
698 |
+
if (!$fileName) {
|
699 |
+
return null;
|
700 |
+
}
|
701 |
+
|
702 |
+
$cachedFile = $this->mediaCacheFolder . DIRECTORY_SEPARATOR . $fileName;
|
703 |
+
if (!file_exists($cachedFile)) {
|
704 |
+
return null;
|
705 |
+
}
|
706 |
+
|
707 |
+
return getimagesize($cachedFile);
|
708 |
+
}
|
709 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPCover.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Validators\Type;
|
12 |
+
use Facebook\InstantArticles\Elements\Image;
|
13 |
+
use Facebook\InstantArticles\Elements\Slideshow;
|
14 |
+
use Facebook\InstantArticles\Elements\Video;
|
15 |
+
|
16 |
+
class AMPCover
|
17 |
+
{
|
18 |
+
/**
|
19 |
+
* @var Context the conversion context holder
|
20 |
+
*/
|
21 |
+
private $context;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var Image|Video|Slideshow The element cover
|
25 |
+
*/
|
26 |
+
private $coverElement;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var DOMNode The html tag holding the final element;
|
30 |
+
*/
|
31 |
+
private $coverTag;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param Context $context Conversion context var.
|
35 |
+
* @param Image|Video|Slideshow $coverElement The element from SDK that will generate the cover.
|
36 |
+
*/
|
37 |
+
public function __construct($context, $coverElement)
|
38 |
+
{
|
39 |
+
$this->context = $context;
|
40 |
+
$this->coverElement = $coverElement;
|
41 |
+
}
|
42 |
+
|
43 |
+
private function genContainer()
|
44 |
+
{
|
45 |
+
if (Type::is($this->coverElement, Image::getClassName())) {
|
46 |
+
$this->coverTag = AMPCoverImage::create($this->coverElement, $this->context, 'cover-image')->build();
|
47 |
+
} else if (Type::is($this->coverElement, Slideshow::getClassName())) {
|
48 |
+
//return $this->buildSlideshow($this->coverElement, $context, 'cover-slideshow');
|
49 |
+
} else if (Type::is($this->coverElement, Video::getClassName())) {
|
50 |
+
//return $this->buildVideo($this->coverElement, $context, 'cover-video');
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
public function build()
|
55 |
+
{
|
56 |
+
$this->genContainer();
|
57 |
+
return $this->coverTag;
|
58 |
+
}
|
59 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPCoverImage.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
class AMPCoverImage
|
12 |
+
{
|
13 |
+
// Constructor setup
|
14 |
+
private $image;
|
15 |
+
private $context;
|
16 |
+
private $cssClass;
|
17 |
+
|
18 |
+
// Generator fill in
|
19 |
+
private $containerTag;
|
20 |
+
private $ampImgTag;
|
21 |
+
|
22 |
+
private function __construct($image, $context, $cssClass)
|
23 |
+
{
|
24 |
+
$this->image = $image;
|
25 |
+
$this->context = $context;
|
26 |
+
$this->cssClass = $cssClass;
|
27 |
+
}
|
28 |
+
|
29 |
+
public static function create($image, $context, $cssClass)
|
30 |
+
{
|
31 |
+
return new self($image, $context, $cssClass);
|
32 |
+
}
|
33 |
+
|
34 |
+
private function genContainer()
|
35 |
+
{
|
36 |
+
$this->containerTag = $this->context->createElement('div', null, $this->cssClass);
|
37 |
+
}
|
38 |
+
|
39 |
+
private function genCaptionContainer()
|
40 |
+
{
|
41 |
+
$caption = $this->image->getCaption();
|
42 |
+
if ($caption) {
|
43 |
+
$this->ampImgTag =
|
44 |
+
AMPCaption::create($caption, $this->context, $this->ampImgTag)->build();
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
private function genAmpImage()
|
49 |
+
{
|
50 |
+
$this->ampImgTag = $this->context->createElement('amp-img', null, 'header-cover-img');
|
51 |
+
$imageURL = $this->image->getUrl();
|
52 |
+
|
53 |
+
$imageDimensions = $this->context->getMediaDimensions($imageURL, AMPContext::MEDIA_TYPE_IMAGE);
|
54 |
+
$imageWidth = $imageDimensions[0];
|
55 |
+
$imageHeight = $imageDimensions[1];
|
56 |
+
|
57 |
+
$horizontalScale = AMPContext::DEFAULT_WIDTH / $imageWidth;
|
58 |
+
$verticalScale = AMPContext::DEFAULT_HEIGHT / $imageHeight;
|
59 |
+
$maxScale = max($horizontalScale, $verticalScale);
|
60 |
+
|
61 |
+
$translateX = (int) (-($imageWidth * $maxScale - AMPContext::DEFAULT_WIDTH) / 2);
|
62 |
+
$translateY = (int) (-($imageHeight * $maxScale - AMPContext::DEFAULT_HEIGHT) / 2);
|
63 |
+
|
64 |
+
$imageWidth = (int) ($imageWidth * $maxScale);
|
65 |
+
$imageHeight = (int) ($imageHeight * $maxScale);
|
66 |
+
|
67 |
+
$this->ampImgTag->setAttribute('src', $imageURL);
|
68 |
+
$this->ampImgTag->setAttribute('width', (string) $imageWidth);
|
69 |
+
$this->ampImgTag->setAttribute('height', (string) $imageHeight);
|
70 |
+
|
71 |
+
$imageCSSClass = $this->ampImgTag->getAttribute('class');
|
72 |
+
$containerCSSClass = $this->containerTag->getAttribute('class');
|
73 |
+
$this->context->getCssBuilder()
|
74 |
+
->addProperty("amp-img.$imageCSSClass", 'transform', "translate({$translateX}px, {$translateY}px)")
|
75 |
+
->addProperty("div.$containerCSSClass", 'width', AMPContext::DEFAULT_WIDTH.'px')
|
76 |
+
->addProperty("div.$containerCSSClass", 'height', AMPContext::DEFAULT_HEIGHT.'px')
|
77 |
+
->addProperty("div.$containerCSSClass", 'overflow', 'hidden');
|
78 |
+
|
79 |
+
}
|
80 |
+
|
81 |
+
public function build()
|
82 |
+
{
|
83 |
+
$this->genContainer();
|
84 |
+
$this->genAmpImage();
|
85 |
+
$this->genCaptionContainer();
|
86 |
+
|
87 |
+
$this->containerTag->appendChild($this->ampImgTag);
|
88 |
+
return $this->containerTag;
|
89 |
+
}
|
90 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPHeader.php
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
class AMPHeader
|
12 |
+
{
|
13 |
+
private $header;
|
14 |
+
private $context;
|
15 |
+
private $publishDateElement;
|
16 |
+
|
17 |
+
public function __construct($context)
|
18 |
+
{
|
19 |
+
$this->context = $context;
|
20 |
+
}
|
21 |
+
|
22 |
+
private function iaHeader()
|
23 |
+
{
|
24 |
+
return $this->context->getInstantArticle()->getHeader();
|
25 |
+
}
|
26 |
+
|
27 |
+
private function genKicker()
|
28 |
+
{
|
29 |
+
if ($this->iaHeader()->getKicker()) {
|
30 |
+
$kicker = $this->context->createElement('h2', $this->header, 'header-category');
|
31 |
+
$kicker->appendChild($this->context->getInstantArticle()
|
32 |
+
->getHeader()
|
33 |
+
->getKicker()
|
34 |
+
->textToDOMDocumentFragment($this->context->getDocument()));
|
35 |
+
$this->context->buildSpacingDiv($this->header);
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
private function genTitle()
|
40 |
+
{
|
41 |
+
$iaTitle = $this->iaHeader()
|
42 |
+
->getTitle()
|
43 |
+
->textToDOMDocumentFragment($this->context->getDocument());
|
44 |
+
|
45 |
+
$h1 = $this->context->createElement('h1', $this->header, 'header-h1');
|
46 |
+
$h1->appendChild($iaTitle);
|
47 |
+
$this->context->buildSpacingDiv($this->header);
|
48 |
+
}
|
49 |
+
|
50 |
+
private function genHeaderBar()
|
51 |
+
{
|
52 |
+
$this->headerBar = $this->context->createElement('div', $this->header, 'header-bar');
|
53 |
+
$this->context->buildSpacingDiv($this->header);
|
54 |
+
// Note: The logo will be added after the whole article is processed
|
55 |
+
}
|
56 |
+
|
57 |
+
private function genSubtitle()
|
58 |
+
{
|
59 |
+
if ($this->iaHeader()->getSubtitle()) {
|
60 |
+
$iaHeaderSubtitle = $this->iaHeader()->getSubtitle()->textToDOMDocumentFragment($this->context->getDocument());
|
61 |
+
$subtitle = $this->context->createElement('h2', $this->header, 'header-h2');
|
62 |
+
$subtitle->appendChild($iaHeaderSubtitle);
|
63 |
+
|
64 |
+
$this->context->buildSpacingDiv($this->header);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
private function genArticlePublishDateElement()
|
69 |
+
{
|
70 |
+
$this->publishDateElement = $this->context->createElement('h3', $this->header, 'header-date');
|
71 |
+
// Note: The published date will be added after the whole article is processed
|
72 |
+
$this->context->buildSpacingDiv($this->header);
|
73 |
+
}
|
74 |
+
|
75 |
+
private function genAuthors()
|
76 |
+
{
|
77 |
+
$authors = $this->context->createElement('h3', $this->header, 'header-author');
|
78 |
+
$authorsElement = $this->iaHeader()->getAuthors();
|
79 |
+
$authorsString = [];
|
80 |
+
foreach ($authorsElement as $author) {
|
81 |
+
$authorsString[] = $author->getName();
|
82 |
+
}
|
83 |
+
$authors->appendChild($this->context->getDocument()->createTextNode('By '.implode($authorsString, ', ')));
|
84 |
+
$this->context->buildSpacingDiv($this->header);
|
85 |
+
}
|
86 |
+
|
87 |
+
private function genContainer()
|
88 |
+
{
|
89 |
+
// Builds the content Header, with proper colors and image, adding to body
|
90 |
+
$this->header = $this->context->createElement('header', $this->context->getBody(), 'header');
|
91 |
+
// Creates the cover content for the cover and appends to the header
|
92 |
+
if ($this->context->getInstantArticle()->getHeader()->getCover()) {
|
93 |
+
$ampCover = new AMPCover($this->context, $this->context->getInstantArticle()->getHeader()->getCover());
|
94 |
+
$this->header->appendChild($ampCover->build());
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
public function genHeaderLogo($logo)
|
99 |
+
{
|
100 |
+
if (!isset($logo->url)) {
|
101 |
+
return;
|
102 |
+
}
|
103 |
+
|
104 |
+
$ampImageContainer = $this->context->createElement(
|
105 |
+
'div',
|
106 |
+
$this->headerBar,
|
107 |
+
'header-bar-img-container'
|
108 |
+
);
|
109 |
+
$ampImage = $this->context->createElement(
|
110 |
+
'amp-img',
|
111 |
+
$ampImageContainer,
|
112 |
+
null,
|
113 |
+
array(
|
114 |
+
'src' => $logo->url,
|
115 |
+
'width' => $logo->width,
|
116 |
+
'height' => $logo->height
|
117 |
+
)
|
118 |
+
);
|
119 |
+
}
|
120 |
+
|
121 |
+
public function genArticlePublishDate($dateFormat)
|
122 |
+
{
|
123 |
+
$datetime = $this->iaHeader()->getPublished()->getDatetime();
|
124 |
+
$this->publishDateElement->appendChild(
|
125 |
+
$this->context->getDocument()->createTextNode(date_format($datetime, $dateFormat))
|
126 |
+
);
|
127 |
+
}
|
128 |
+
|
129 |
+
public function build()
|
130 |
+
{
|
131 |
+
$this->genContainer();
|
132 |
+
$this->genHeaderBar();
|
133 |
+
$this->genKicker();
|
134 |
+
$this->genTitle();
|
135 |
+
$this->genSubtitle();
|
136 |
+
$this->genAuthors();
|
137 |
+
$this->genArticlePublishDateElement();
|
138 |
+
|
139 |
+
return $this->header;
|
140 |
+
}
|
141 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/AMPImage.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
class AMPImage
|
12 |
+
{
|
13 |
+
public $url;
|
14 |
+
public $width;
|
15 |
+
public $height;
|
16 |
+
|
17 |
+
public function __construct($url, $width, $height)
|
18 |
+
{
|
19 |
+
$this->url = $url;
|
20 |
+
$this->width = $width;
|
21 |
+
$this->height = $height;
|
22 |
+
}
|
23 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/configuration/default-amp.style.json
ADDED
@@ -0,0 +1,1133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"background_color": "#FFFFFF",
|
3 |
+
"title": {
|
4 |
+
"background_color": "#FFFFFF",
|
5 |
+
"border": {
|
6 |
+
"bottom": {
|
7 |
+
"width": 0
|
8 |
+
},
|
9 |
+
"left": {
|
10 |
+
"width": 0
|
11 |
+
},
|
12 |
+
"right": {
|
13 |
+
"width": 0
|
14 |
+
},
|
15 |
+
"top": {
|
16 |
+
"width": 0
|
17 |
+
}
|
18 |
+
},
|
19 |
+
"capitalization": "NONE",
|
20 |
+
"color": "#000000",
|
21 |
+
"display": "INLINE",
|
22 |
+
"font": "Georgia",
|
23 |
+
"line_height_scale": 1,
|
24 |
+
"margin": {
|
25 |
+
"left": {
|
26 |
+
"scaling_factor": 1,
|
27 |
+
"size": "DOCUMENT_MARGIN"
|
28 |
+
},
|
29 |
+
"right": {
|
30 |
+
"scaling_factor": 1,
|
31 |
+
"size": "DOCUMENT_MARGIN"
|
32 |
+
}
|
33 |
+
},
|
34 |
+
"padding": {
|
35 |
+
"bottom": {
|
36 |
+
"scaling_factor": 1,
|
37 |
+
"size": "NONE"
|
38 |
+
},
|
39 |
+
"left": {
|
40 |
+
"scaling_factor": 1,
|
41 |
+
"size": "NONE"
|
42 |
+
},
|
43 |
+
"right": {
|
44 |
+
"scaling_factor": 1,
|
45 |
+
"size": "NONE"
|
46 |
+
},
|
47 |
+
"top": {
|
48 |
+
"scaling_factor": 1,
|
49 |
+
"size": "NONE"
|
50 |
+
}
|
51 |
+
},
|
52 |
+
"text_alignment": "LEFT",
|
53 |
+
"text_size_scale": 1,
|
54 |
+
"underline": "NONE"
|
55 |
+
},
|
56 |
+
"subtitle": {
|
57 |
+
"background_color": "#FFFFFF",
|
58 |
+
"border": {
|
59 |
+
"bottom": {
|
60 |
+
"width": 0
|
61 |
+
},
|
62 |
+
"left": {
|
63 |
+
"width": 0
|
64 |
+
},
|
65 |
+
"right": {
|
66 |
+
"width": 0
|
67 |
+
},
|
68 |
+
"top": {
|
69 |
+
"width": 0
|
70 |
+
}
|
71 |
+
},
|
72 |
+
"capitalization": "NONE",
|
73 |
+
"color": "#000000",
|
74 |
+
"display": "INLINE",
|
75 |
+
"font": "Georgia",
|
76 |
+
"line_height_scale": 1,
|
77 |
+
"margin": {
|
78 |
+
"left": {
|
79 |
+
"scaling_factor": 1,
|
80 |
+
"size": "DOCUMENT_MARGIN"
|
81 |
+
},
|
82 |
+
"right": {
|
83 |
+
"scaling_factor": 1,
|
84 |
+
"size": "DOCUMENT_MARGIN"
|
85 |
+
}
|
86 |
+
},
|
87 |
+
"padding": {
|
88 |
+
"bottom": {
|
89 |
+
"scaling_factor": 1,
|
90 |
+
"size": "NONE"
|
91 |
+
},
|
92 |
+
"left": {
|
93 |
+
"scaling_factor": 1,
|
94 |
+
"size": "NONE"
|
95 |
+
},
|
96 |
+
"right": {
|
97 |
+
"scaling_factor": 1,
|
98 |
+
"size": "NONE"
|
99 |
+
},
|
100 |
+
"top": {
|
101 |
+
"scaling_factor": 1,
|
102 |
+
"size": "NONE"
|
103 |
+
}
|
104 |
+
},
|
105 |
+
"text_alignment": "LEFT",
|
106 |
+
"text_size_scale": 1,
|
107 |
+
"underline": "NONE"
|
108 |
+
},
|
109 |
+
"kicker": {
|
110 |
+
"background_color": "#FFFFFF",
|
111 |
+
"border": {
|
112 |
+
"bottom": {
|
113 |
+
"width": 0
|
114 |
+
},
|
115 |
+
"left": {
|
116 |
+
"width": 0
|
117 |
+
},
|
118 |
+
"right": {
|
119 |
+
"width": 0
|
120 |
+
},
|
121 |
+
"top": {
|
122 |
+
"width": 0
|
123 |
+
}
|
124 |
+
},
|
125 |
+
"capitalization": "ALL_CAPS",
|
126 |
+
"color": "#000000",
|
127 |
+
"display": "INLINE",
|
128 |
+
"font": "Helvetica Neue",
|
129 |
+
"line_height_scale": 1,
|
130 |
+
"margin": {
|
131 |
+
"left": {
|
132 |
+
"scaling_factor": 1,
|
133 |
+
"size": "DOCUMENT_MARGIN"
|
134 |
+
},
|
135 |
+
"right": {
|
136 |
+
"scaling_factor": 1,
|
137 |
+
"size": "DOCUMENT_MARGIN"
|
138 |
+
}
|
139 |
+
},
|
140 |
+
"padding": {
|
141 |
+
"bottom": {
|
142 |
+
"scaling_factor": 1,
|
143 |
+
"size": "NONE"
|
144 |
+
},
|
145 |
+
"left": {
|
146 |
+
"scaling_factor": 1,
|
147 |
+
"size": "NONE"
|
148 |
+
},
|
149 |
+
"right": {
|
150 |
+
"scaling_factor": 1,
|
151 |
+
"size": "NONE"
|
152 |
+
},
|
153 |
+
"top": {
|
154 |
+
"scaling_factor": 1,
|
155 |
+
"size": "NONE"
|
156 |
+
}
|
157 |
+
},
|
158 |
+
"text_alignment": "LEFT",
|
159 |
+
"text_size_scale": 1,
|
160 |
+
"underline": "NONE"
|
161 |
+
},
|
162 |
+
"byline": {
|
163 |
+
"border": {
|
164 |
+
"bottom": {
|
165 |
+
"width": 0
|
166 |
+
},
|
167 |
+
"left": {
|
168 |
+
"width": 0
|
169 |
+
},
|
170 |
+
"right": {
|
171 |
+
"width": 0
|
172 |
+
},
|
173 |
+
"top": {
|
174 |
+
"width": 0
|
175 |
+
}
|
176 |
+
},
|
177 |
+
"capitalization": "ALL_CAPS",
|
178 |
+
"color": "#000000",
|
179 |
+
"display": "INLINE",
|
180 |
+
"font": "Helvetica Neue",
|
181 |
+
"line_height_scale": 1,
|
182 |
+
"margin": {
|
183 |
+
"left": {
|
184 |
+
"scaling_factor": 1,
|
185 |
+
"size": "DOCUMENT_MARGIN"
|
186 |
+
},
|
187 |
+
"right": {
|
188 |
+
"scaling_factor": 1,
|
189 |
+
"size": "DOCUMENT_MARGIN"
|
190 |
+
}
|
191 |
+
},
|
192 |
+
"padding": {
|
193 |
+
"bottom": {
|
194 |
+
"scaling_factor": 1,
|
195 |
+
"size": "NONE"
|
196 |
+
},
|
197 |
+
"left": {
|
198 |
+
"scaling_factor": 1,
|
199 |
+
"size": "NONE"
|
200 |
+
},
|
201 |
+
"right": {
|
202 |
+
"scaling_factor": 1,
|
203 |
+
"size": "NONE"
|
204 |
+
},
|
205 |
+
"top": {
|
206 |
+
"scaling_factor": 1,
|
207 |
+
"size": "NONE"
|
208 |
+
}
|
209 |
+
},
|
210 |
+
"text_alignment": "LEFT",
|
211 |
+
"text_size_scale": 1,
|
212 |
+
"underline": "NONE"
|
213 |
+
},
|
214 |
+
"date_style": "MONTH_DAY_YEAR",
|
215 |
+
"primary_heading": {
|
216 |
+
"background_color": "#FFFFFF",
|
217 |
+
"border": {
|
218 |
+
"bottom": {
|
219 |
+
"width": 0
|
220 |
+
},
|
221 |
+
"left": {
|
222 |
+
"width": 0
|
223 |
+
},
|
224 |
+
"right": {
|
225 |
+
"width": 0
|
226 |
+
},
|
227 |
+
"top": {
|
228 |
+
"width": 0
|
229 |
+
}
|
230 |
+
},
|
231 |
+
"capitalization": "NONE",
|
232 |
+
"color": "#000000",
|
233 |
+
"display": "INLINE",
|
234 |
+
"font": "Georgia",
|
235 |
+
"line_height_scale": 1,
|
236 |
+
"margin": {
|
237 |
+
"left": {
|
238 |
+
"scaling_factor": 1,
|
239 |
+
"size": "DOCUMENT_MARGIN"
|
240 |
+
},
|
241 |
+
"right": {
|
242 |
+
"scaling_factor": 1,
|
243 |
+
"size": "DOCUMENT_MARGIN"
|
244 |
+
}
|
245 |
+
},
|
246 |
+
"padding": {
|
247 |
+
"bottom": {
|
248 |
+
"scaling_factor": 1,
|
249 |
+
"size": "NONE"
|
250 |
+
},
|
251 |
+
"left": {
|
252 |
+
"scaling_factor": 1,
|
253 |
+
"size": "NONE"
|
254 |
+
},
|
255 |
+
"right": {
|
256 |
+
"scaling_factor": 1,
|
257 |
+
"size": "NONE"
|
258 |
+
},
|
259 |
+
"top": {
|
260 |
+
"scaling_factor": 1,
|
261 |
+
"size": "NONE"
|
262 |
+
}
|
263 |
+
},
|
264 |
+
"text_alignment": "LEFT",
|
265 |
+
"text_size_scale": 1,
|
266 |
+
"underline": "NONE"
|
267 |
+
},
|
268 |
+
"secondary_heading": {
|
269 |
+
"background_color": "#FFFFFF",
|
270 |
+
"border": {
|
271 |
+
"bottom": {
|
272 |
+
"width": 0
|
273 |
+
},
|
274 |
+
"left": {
|
275 |
+
"width": 0
|
276 |
+
},
|
277 |
+
"right": {
|
278 |
+
"width": 0
|
279 |
+
},
|
280 |
+
"top": {
|
281 |
+
"width": 0
|
282 |
+
}
|
283 |
+
},
|
284 |
+
"capitalization": "NONE",
|
285 |
+
"color": "#000000",
|
286 |
+
"display": "INLINE",
|
287 |
+
"font": "Georgia",
|
288 |
+
"line_height_scale": 1,
|
289 |
+
"margin": {
|
290 |
+
"left": {
|
291 |
+
"scaling_factor": 1,
|
292 |
+
"size": "DOCUMENT_MARGIN"
|
293 |
+
},
|
294 |
+
"right": {
|
295 |
+
"scaling_factor": 1,
|
296 |
+
"size": "DOCUMENT_MARGIN"
|
297 |
+
}
|
298 |
+
},
|
299 |
+
"padding": {
|
300 |
+
"bottom": {
|
301 |
+
"scaling_factor": 1,
|
302 |
+
"size": "NONE"
|
303 |
+
},
|
304 |
+
"left": {
|
305 |
+
"scaling_factor": 1,
|
306 |
+
"size": "NONE"
|
307 |
+
},
|
308 |
+
"right": {
|
309 |
+
"scaling_factor": 1,
|
310 |
+
"size": "NONE"
|
311 |
+
},
|
312 |
+
"top": {
|
313 |
+
"scaling_factor": 1,
|
314 |
+
"size": "NONE"
|
315 |
+
}
|
316 |
+
},
|
317 |
+
"text_alignment": "LEFT",
|
318 |
+
"text_size_scale": 1,
|
319 |
+
"underline": "NONE"
|
320 |
+
},
|
321 |
+
"body_text": {
|
322 |
+
"border": {
|
323 |
+
"bottom": {
|
324 |
+
"width": 0
|
325 |
+
},
|
326 |
+
"left": {
|
327 |
+
"width": 0
|
328 |
+
},
|
329 |
+
"right": {
|
330 |
+
"width": 0
|
331 |
+
},
|
332 |
+
"top": {
|
333 |
+
"width": 0
|
334 |
+
}
|
335 |
+
},
|
336 |
+
"capitalization": "NONE",
|
337 |
+
"color": "#000000",
|
338 |
+
"display": "INLINE",
|
339 |
+
"font": "Georgia",
|
340 |
+
"line_height_scale": 1,
|
341 |
+
"margin": {
|
342 |
+
"left": {
|
343 |
+
"scaling_factor": 1,
|
344 |
+
"size": "DOCUMENT_MARGIN"
|
345 |
+
},
|
346 |
+
"right": {
|
347 |
+
"scaling_factor": 1,
|
348 |
+
"size": "DOCUMENT_MARGIN"
|
349 |
+
}
|
350 |
+
},
|
351 |
+
"padding": {
|
352 |
+
"bottom": {
|
353 |
+
"scaling_factor": 1,
|
354 |
+
"size": "NONE"
|
355 |
+
},
|
356 |
+
"left": {
|
357 |
+
"scaling_factor": 1,
|
358 |
+
"size": "NONE"
|
359 |
+
},
|
360 |
+
"right": {
|
361 |
+
"scaling_factor": 1,
|
362 |
+
"size": "NONE"
|
363 |
+
},
|
364 |
+
"top": {
|
365 |
+
"scaling_factor": 1,
|
366 |
+
"size": "NONE"
|
367 |
+
}
|
368 |
+
},
|
369 |
+
"text_alignment": "LEFT",
|
370 |
+
"text_size_scale": 1,
|
371 |
+
"underline": "NONE"
|
372 |
+
},
|
373 |
+
"inline_link": {
|
374 |
+
"border": {
|
375 |
+
"bottom": {
|
376 |
+
"width": 0
|
377 |
+
},
|
378 |
+
"left": {
|
379 |
+
"width": 0
|
380 |
+
},
|
381 |
+
"right": {
|
382 |
+
"width": 0
|
383 |
+
},
|
384 |
+
"top": {
|
385 |
+
"width": 0
|
386 |
+
}
|
387 |
+
},
|
388 |
+
"capitalization": "NONE",
|
389 |
+
"color": "#000000",
|
390 |
+
"display": "INLINE",
|
391 |
+
"font": "Georgia",
|
392 |
+
"line_height_scale": 1,
|
393 |
+
"margin": {
|
394 |
+
"left": {
|
395 |
+
"scaling_factor": 1,
|
396 |
+
"size": "DOCUMENT_MARGIN"
|
397 |
+
},
|
398 |
+
"right": {
|
399 |
+
"scaling_factor": 1,
|
400 |
+
"size": "DOCUMENT_MARGIN"
|
401 |
+
}
|
402 |
+
},
|
403 |
+
"padding": {
|
404 |
+
"bottom": {
|
405 |
+
"scaling_factor": 1,
|
406 |
+
"size": "NONE"
|
407 |
+
},
|
408 |
+
"left": {
|
409 |
+
"scaling_factor": 1,
|
410 |
+
"size": "NONE"
|
411 |
+
},
|
412 |
+
"right": {
|
413 |
+
"scaling_factor": 1,
|
414 |
+
"size": "NONE"
|
415 |
+
},
|
416 |
+
"top": {
|
417 |
+
"scaling_factor": 1,
|
418 |
+
"size": "NONE"
|
419 |
+
}
|
420 |
+
},
|
421 |
+
"text_alignment": "LEFT",
|
422 |
+
"text_size_scale": 1,
|
423 |
+
"underline": "SIMPLE_UNDERLINE"
|
424 |
+
},
|
425 |
+
"block_quote": {
|
426 |
+
"background_color": "#FFFFFF",
|
427 |
+
"border": {
|
428 |
+
"bottom": {
|
429 |
+
"color": "#000000",
|
430 |
+
"width": 0
|
431 |
+
},
|
432 |
+
"left": {
|
433 |
+
"color": "#000000",
|
434 |
+
"width": 2
|
435 |
+
},
|
436 |
+
"right": {
|
437 |
+
"color": "#000000",
|
438 |
+
"width": 0
|
439 |
+
},
|
440 |
+
"top": {
|
441 |
+
"color": "#000000",
|
442 |
+
"width": 0
|
443 |
+
}
|
444 |
+
},
|
445 |
+
"capitalization": "NONE",
|
446 |
+
"color": "#000000",
|
447 |
+
"display": "INLINE",
|
448 |
+
"font": "Georgia",
|
449 |
+
"line_height_scale": 1,
|
450 |
+
"margin": {
|
451 |
+
"left": {
|
452 |
+
"scaling_factor": 1,
|
453 |
+
"size": "DOCUMENT_MARGIN"
|
454 |
+
},
|
455 |
+
"right": {
|
456 |
+
"scaling_factor": 1,
|
457 |
+
"size": "DOCUMENT_MARGIN"
|
458 |
+
}
|
459 |
+
},
|
460 |
+
"padding": {
|
461 |
+
"bottom": {
|
462 |
+
"scaling_factor": 1,
|
463 |
+
"size": "NONE"
|
464 |
+
},
|
465 |
+
"left": {
|
466 |
+
"scaling_factor": 1,
|
467 |
+
"size": "MEDIUM"
|
468 |
+
},
|
469 |
+
"right": {
|
470 |
+
"scaling_factor": 1,
|
471 |
+
"size": "SMALL"
|
472 |
+
},
|
473 |
+
"top": {
|
474 |
+
"scaling_factor": 1,
|
475 |
+
"size": "NONE"
|
476 |
+
}
|
477 |
+
},
|
478 |
+
"text_alignment": "LEFT",
|
479 |
+
"text_size_scale": 1,
|
480 |
+
"underline": "NONE"
|
481 |
+
},
|
482 |
+
"pull_quote": {
|
483 |
+
"background_color": "#FFFFFF",
|
484 |
+
"border": {
|
485 |
+
"bottom": {
|
486 |
+
"width": 0
|
487 |
+
},
|
488 |
+
"left": {
|
489 |
+
"width": 0
|
490 |
+
},
|
491 |
+
"right": {
|
492 |
+
"width": 0
|
493 |
+
},
|
494 |
+
"top": {
|
495 |
+
"width": 0
|
496 |
+
}
|
497 |
+
},
|
498 |
+
"capitalization": "NONE",
|
499 |
+
"color": "#000000",
|
500 |
+
"display": "INLINE",
|
501 |
+
"font": "Georgia",
|
502 |
+
"line_height_scale": 1,
|
503 |
+
"margin": {
|
504 |
+
"left": {
|
505 |
+
"scaling_factor": 1,
|
506 |
+
"size": "DOCUMENT_MARGIN"
|
507 |
+
},
|
508 |
+
"right": {
|
509 |
+
"scaling_factor": 1,
|
510 |
+
"size": "DOCUMENT_MARGIN"
|
511 |
+
}
|
512 |
+
},
|
513 |
+
"padding": {
|
514 |
+
"bottom": {
|
515 |
+
"scaling_factor": 1,
|
516 |
+
"size": "NONE"
|
517 |
+
},
|
518 |
+
"left": {
|
519 |
+
"scaling_factor": 1,
|
520 |
+
"size": "NONE"
|
521 |
+
},
|
522 |
+
"right": {
|
523 |
+
"scaling_factor": 1,
|
524 |
+
"size": "NONE"
|
525 |
+
},
|
526 |
+
"top": {
|
527 |
+
"scaling_factor": 1,
|
528 |
+
"size": "NONE"
|
529 |
+
}
|
530 |
+
},
|
531 |
+
"text_alignment": "LEFT",
|
532 |
+
"text_size_scale": 1,
|
533 |
+
"underline": "NONE"
|
534 |
+
},
|
535 |
+
"pull_quote_attribution": {
|
536 |
+
"background_color": "#FFFFFF",
|
537 |
+
"border": {
|
538 |
+
"bottom": {
|
539 |
+
"width": 0
|
540 |
+
},
|
541 |
+
"left": {
|
542 |
+
"width": 0
|
543 |
+
},
|
544 |
+
"right": {
|
545 |
+
"width": 0
|
546 |
+
},
|
547 |
+
"top": {
|
548 |
+
"width": 0
|
549 |
+
}
|
550 |
+
},
|
551 |
+
"capitalization": "ALL_CAPS",
|
552 |
+
"color": "#000000",
|
553 |
+
"display": "INLINE",
|
554 |
+
"font": "Helvetica Neue",
|
555 |
+
"line_height_scale": 1,
|
556 |
+
"margin": {
|
557 |
+
"left": {
|
558 |
+
"scaling_factor": 1,
|
559 |
+
"size": "DOCUMENT_MARGIN"
|
560 |
+
},
|
561 |
+
"right": {
|
562 |
+
"scaling_factor": 1,
|
563 |
+
"size": "DOCUMENT_MARGIN"
|
564 |
+
}
|
565 |
+
},
|
566 |
+
"padding": {
|
567 |
+
"bottom": {
|
568 |
+
"scaling_factor": 1,
|
569 |
+
"size": "NONE"
|
570 |
+
},
|
571 |
+
"left": {
|
572 |
+
"scaling_factor": 1,
|
573 |
+
"size": "NONE"
|
574 |
+
},
|
575 |
+
"right": {
|
576 |
+
"scaling_factor": 1,
|
577 |
+
"size": "NONE"
|
578 |
+
},
|
579 |
+
"top": {
|
580 |
+
"scaling_factor": 1,
|
581 |
+
"size": "NONE"
|
582 |
+
}
|
583 |
+
},
|
584 |
+
"text_alignment": "LEFT",
|
585 |
+
"text_size_scale": 1,
|
586 |
+
"underline": "NONE"
|
587 |
+
},
|
588 |
+
"caption_title_small": {
|
589 |
+
"background_color": "#FFFFFF",
|
590 |
+
"border": {
|
591 |
+
"bottom": {
|
592 |
+
"width": 0
|
593 |
+
},
|
594 |
+
"left": {
|
595 |
+
"width": 0
|
596 |
+
},
|
597 |
+
"right": {
|
598 |
+
"width": 0
|
599 |
+
},
|
600 |
+
"top": {
|
601 |
+
"width": 0
|
602 |
+
}
|
603 |
+
},
|
604 |
+
"capitalization": "NONE",
|
605 |
+
"color": "#808080",
|
606 |
+
"display": "INLINE",
|
607 |
+
"font": "Helvetica Neue Bold",
|
608 |
+
"line_height_scale": 1,
|
609 |
+
"margin": {
|
610 |
+
"left": {
|
611 |
+
"scaling_factor": 1,
|
612 |
+
"size": "DOCUMENT_MARGIN"
|
613 |
+
},
|
614 |
+
"right": {
|
615 |
+
"scaling_factor": 1,
|
616 |
+
"size": "DOCUMENT_MARGIN"
|
617 |
+
}
|
618 |
+
},
|
619 |
+
"padding": {
|
620 |
+
"bottom": {
|
621 |
+
"scaling_factor": 1,
|
622 |
+
"size": "NONE"
|
623 |
+
},
|
624 |
+
"left": {
|
625 |
+
"scaling_factor": 1,
|
626 |
+
"size": "NONE"
|
627 |
+
},
|
628 |
+
"right": {
|
629 |
+
"scaling_factor": 1,
|
630 |
+
"size": "NONE"
|
631 |
+
},
|
632 |
+
"top": {
|
633 |
+
"scaling_factor": 1,
|
634 |
+
"size": "NONE"
|
635 |
+
}
|
636 |
+
},
|
637 |
+
"text_alignment": "LEFT",
|
638 |
+
"text_size_scale": 1,
|
639 |
+
"underline": "NONE"
|
640 |
+
},
|
641 |
+
"caption_title": {
|
642 |
+
"background_color": "#FFFFFF",
|
643 |
+
"border": {
|
644 |
+
"bottom": {
|
645 |
+
"width": 0
|
646 |
+
},
|
647 |
+
"left": {
|
648 |
+
"width": 0
|
649 |
+
},
|
650 |
+
"right": {
|
651 |
+
"width": 0
|
652 |
+
},
|
653 |
+
"top": {
|
654 |
+
"width": 0
|
655 |
+
}
|
656 |
+
},
|
657 |
+
"capitalization": "NONE",
|
658 |
+
"color": "#808080",
|
659 |
+
"display": "INLINE",
|
660 |
+
"font": "Georgia",
|
661 |
+
"line_height_scale": 1,
|
662 |
+
"margin": {
|
663 |
+
"left": {
|
664 |
+
"scaling_factor": 1,
|
665 |
+
"size": "DOCUMENT_MARGIN"
|
666 |
+
},
|
667 |
+
"right": {
|
668 |
+
"scaling_factor": 1,
|
669 |
+
"size": "DOCUMENT_MARGIN"
|
670 |
+
}
|
671 |
+
},
|
672 |
+
"padding": {
|
673 |
+
"bottom": {
|
674 |
+
"scaling_factor": 1,
|
675 |
+
"size": "NONE"
|
676 |
+
},
|
677 |
+
"left": {
|
678 |
+
"scaling_factor": 1,
|
679 |
+
"size": "NONE"
|
680 |
+
},
|
681 |
+
"right": {
|
682 |
+
"scaling_factor": 1,
|
683 |
+
"size": "NONE"
|
684 |
+
},
|
685 |
+
"top": {
|
686 |
+
"scaling_factor": 1,
|
687 |
+
"size": "NONE"
|
688 |
+
}
|
689 |
+
},
|
690 |
+
"text_alignment": "LEFT",
|
691 |
+
"text_size_scale": 1,
|
692 |
+
"underline": "NONE"
|
693 |
+
},
|
694 |
+
"caption_title_large": {
|
695 |
+
"background_color": "#FFFFFF",
|
696 |
+
"border": {
|
697 |
+
"bottom": {
|
698 |
+
"width": 0
|
699 |
+
},
|
700 |
+
"left": {
|
701 |
+
"width": 0
|
702 |
+
},
|
703 |
+
"right": {
|
704 |
+
"width": 0
|
705 |
+
},
|
706 |
+
"top": {
|
707 |
+
"width": 0
|
708 |
+
}
|
709 |
+
},
|
710 |
+
"capitalization": "NONE",
|
711 |
+
"color": "#808080",
|
712 |
+
"display": "INLINE",
|
713 |
+
"font": "Georgia",
|
714 |
+
"line_height_scale": 1,
|
715 |
+
"margin": {
|
716 |
+
"left": {
|
717 |
+
"scaling_factor": 1,
|
718 |
+
"size": "DOCUMENT_MARGIN"
|
719 |
+
},
|
720 |
+
"right": {
|
721 |
+
"scaling_factor": 1,
|
722 |
+
"size": "DOCUMENT_MARGIN"
|
723 |
+
}
|
724 |
+
},
|
725 |
+
"padding": {
|
726 |
+
"bottom": {
|
727 |
+
"scaling_factor": 1,
|
728 |
+
"size": "NONE"
|
729 |
+
},
|
730 |
+
"left": {
|
731 |
+
"scaling_factor": 1,
|
732 |
+
"size": "NONE"
|
733 |
+
},
|
734 |
+
"right": {
|
735 |
+
"scaling_factor": 1,
|
736 |
+
"size": "NONE"
|
737 |
+
},
|
738 |
+
"top": {
|
739 |
+
"scaling_factor": 1,
|
740 |
+
"size": "NONE"
|
741 |
+
}
|
742 |
+
},
|
743 |
+
"text_alignment": "LEFT",
|
744 |
+
"text_size_scale": 1,
|
745 |
+
"underline": "NONE"
|
746 |
+
},
|
747 |
+
"caption_title_extra_large": {
|
748 |
+
"background_color": "#FFFFFF",
|
749 |
+
"border": {
|
750 |
+
"bottom": {
|
751 |
+
"width": 0
|
752 |
+
},
|
753 |
+
"left": {
|
754 |
+
"width": 0
|
755 |
+
},
|
756 |
+
"right": {
|
757 |
+
"width": 0
|
758 |
+
},
|
759 |
+
"top": {
|
760 |
+
"width": 0
|
761 |
+
}
|
762 |
+
},
|
763 |
+
"capitalization": "NONE",
|
764 |
+
"color": "#808080",
|
765 |
+
"display": "INLINE",
|
766 |
+
"font": "Georgia",
|
767 |
+
"line_height_scale": 1,
|
768 |
+
"margin": {
|
769 |
+
"left": {
|
770 |
+
"scaling_factor": 1,
|
771 |
+
"size": "DOCUMENT_MARGIN"
|
772 |
+
},
|
773 |
+
"right": {
|
774 |
+
"scaling_factor": 1,
|
775 |
+
"size": "DOCUMENT_MARGIN"
|
776 |
+
}
|
777 |
+
},
|
778 |
+
"padding": {
|
779 |
+
"bottom": {
|
780 |
+
"scaling_factor": 1,
|
781 |
+
"size": "NONE"
|
782 |
+
},
|
783 |
+
"left": {
|
784 |
+
"scaling_factor": 1,
|
785 |
+
"size": "NONE"
|
786 |
+
},
|
787 |
+
"right": {
|
788 |
+
"scaling_factor": 1,
|
789 |
+
"size": "NONE"
|
790 |
+
},
|
791 |
+
"top": {
|
792 |
+
"scaling_factor": 1,
|
793 |
+
"size": "NONE"
|
794 |
+
}
|
795 |
+
},
|
796 |
+
"text_alignment": "LEFT",
|
797 |
+
"text_size_scale": 1,
|
798 |
+
"underline": "NONE"
|
799 |
+
},
|
800 |
+
"caption_credit": {
|
801 |
+
"background_color": "#FFFFFF",
|
802 |
+
"border": {
|
803 |
+
"bottom": {
|
804 |
+
"width": 0
|
805 |
+
},
|
806 |
+
"left": {
|
807 |
+
"width": 0
|
808 |
+
},
|
809 |
+
"right": {
|
810 |
+
"width": 0
|
811 |
+
},
|
812 |
+
"top": {
|
813 |
+
"width": 0
|
814 |
+
}
|
815 |
+
},
|
816 |
+
"capitalization": "ALL_CAPS",
|
817 |
+
"color": "#BFBFBF",
|
818 |
+
"display": "INLINE",
|
819 |
+
"font": "Helvetica Neue",
|
820 |
+
"line_height_scale": 1,
|
821 |
+
"margin": {
|
822 |
+
"left": {
|
823 |
+
"scaling_factor": 1,
|
824 |
+
"size": "DOCUMENT_MARGIN"
|
825 |
+
},
|
826 |
+
"right": {
|
827 |
+
"scaling_factor": 1,
|
828 |
+
"size": "DOCUMENT_MARGIN"
|
829 |
+
}
|
830 |
+
},
|
831 |
+
"padding": {
|
832 |
+
"bottom": {
|
833 |
+
"scaling_factor": 1,
|
834 |
+
"size": "NONE"
|
835 |
+
},
|
836 |
+
"left": {
|
837 |
+
"scaling_factor": 1,
|
838 |
+
"size": "NONE"
|
839 |
+
},
|
840 |
+
"right": {
|
841 |
+
"scaling_factor": 1,
|
842 |
+
"size": "NONE"
|
843 |
+
},
|
844 |
+
"top": {
|
845 |
+
"scaling_factor": 1,
|
846 |
+
"size": "NONE"
|
847 |
+
}
|
848 |
+
},
|
849 |
+
"text_alignment": "LEFT",
|
850 |
+
"text_size_scale": 1,
|
851 |
+
"underline": "NONE"
|
852 |
+
},
|
853 |
+
"caption_description_small": {
|
854 |
+
"background_color": "#FFFFFF",
|
855 |
+
"border": {
|
856 |
+
"bottom": {
|
857 |
+
"width": 0
|
858 |
+
},
|
859 |
+
"left": {
|
860 |
+
"width": 0
|
861 |
+
},
|
862 |
+
"right": {
|
863 |
+
"width": 0
|
864 |
+
},
|
865 |
+
"top": {
|
866 |
+
"width": 0
|
867 |
+
}
|
868 |
+
},
|
869 |
+
"capitalization": "NONE",
|
870 |
+
"color": "#808080",
|
871 |
+
"display": "INLINE",
|
872 |
+
"font": "Helvetica Neue",
|
873 |
+
"line_height_scale": 1,
|
874 |
+
"margin": {
|
875 |
+
"left": {
|
876 |
+
"scaling_factor": 1,
|
877 |
+
"size": "DOCUMENT_MARGIN"
|
878 |
+
},
|
879 |
+
"right": {
|
880 |
+
"scaling_factor": 1,
|
881 |
+
"size": "DOCUMENT_MARGIN"
|
882 |
+
}
|
883 |
+
},
|
884 |
+
"padding": {
|
885 |
+
"bottom": {
|
886 |
+
"scaling_factor": 1,
|
887 |
+
"size": "NONE"
|
888 |
+
},
|
889 |
+
"left": {
|
890 |
+
"scaling_factor": 1,
|
891 |
+
"size": "NONE"
|
892 |
+
},
|
893 |
+
"right": {
|
894 |
+
"scaling_factor": 1,
|
895 |
+
"size": "NONE"
|
896 |
+
},
|
897 |
+
"top": {
|
898 |
+
"scaling_factor": 1,
|
899 |
+
"size": "NONE"
|
900 |
+
}
|
901 |
+
},
|
902 |
+
"text_alignment": "LEFT",
|
903 |
+
"text_size_scale": 1,
|
904 |
+
"underline": "NONE"
|
905 |
+
},
|
906 |
+
"caption_description": {
|
907 |
+
"background_color": "#FFFFFF",
|
908 |
+
"border": {
|
909 |
+
"bottom": {
|
910 |
+
"width": 0
|
911 |
+
},
|
912 |
+
"left": {
|
913 |
+
"width": 0
|
914 |
+
},
|
915 |
+
"right": {
|
916 |
+
"width": 0
|
917 |
+
},
|
918 |
+
"top": {
|
919 |
+
"width": 0
|
920 |
+
}
|
921 |
+
},
|
922 |
+
"capitalization": "NONE",
|
923 |
+
"color": "#808080",
|
924 |
+
"display": "INLINE",
|
925 |
+
"font": "Georgia",
|
926 |
+
"line_height_scale": 1,
|
927 |
+
"margin": {
|
928 |
+
"left": {
|
929 |
+
"scaling_factor": 1,
|
930 |
+
"size": "DOCUMENT_MARGIN"
|
931 |
+
},
|
932 |
+
"right": {
|
933 |
+
"scaling_factor": 1,
|
934 |
+
"size": "DOCUMENT_MARGIN"
|
935 |
+
}
|
936 |
+
},
|
937 |
+
"padding": {
|
938 |
+
"bottom": {
|
939 |
+
"scaling_factor": 1,
|
940 |
+
"size": "NONE"
|
941 |
+
},
|
942 |
+
"left": {
|
943 |
+
"scaling_factor": 1,
|
944 |
+
"size": "NONE"
|
945 |
+
},
|
946 |
+
"right": {
|
947 |
+
"scaling_factor": 1,
|
948 |
+
"size": "NONE"
|
949 |
+
},
|
950 |
+
"top": {
|
951 |
+
"scaling_factor": 1,
|
952 |
+
"size": "NONE"
|
953 |
+
}
|
954 |
+
},
|
955 |
+
"text_alignment": "LEFT",
|
956 |
+
"text_size_scale": 1,
|
957 |
+
"underline": "NONE"
|
958 |
+
},
|
959 |
+
"caption_description_large": {
|
960 |
+
"background_color": "#FFFFFF",
|
961 |
+
"border": {
|
962 |
+
"bottom": {
|
963 |
+
"width": 0
|
964 |
+
},
|
965 |
+
"left": {
|
966 |
+
"width": 0
|
967 |
+
},
|
968 |
+
"right": {
|
969 |
+
"width": 0
|
970 |
+
},
|
971 |
+
"top": {
|
972 |
+
"width": 0
|
973 |
+
}
|
974 |
+
},
|
975 |
+
"capitalization": "NONE",
|
976 |
+
"color": "#808080",
|
977 |
+
"display": "INLINE",
|
978 |
+
"font": "Georgia",
|
979 |
+
"line_height_scale": 1,
|
980 |
+
"margin": {
|
981 |
+
"left": {
|
982 |
+
"scaling_factor": 1,
|
983 |
+
"size": "DOCUMENT_MARGIN"
|
984 |
+
},
|
985 |
+
"right": {
|
986 |
+
"scaling_factor": 1,
|
987 |
+
"size": "DOCUMENT_MARGIN"
|
988 |
+
}
|
989 |
+
},
|
990 |
+
"padding": {
|
991 |
+
"bottom": {
|
992 |
+
"scaling_factor": 1,
|
993 |
+
"size": "NONE"
|
994 |
+
},
|
995 |
+
"left": {
|
996 |
+
"scaling_factor": 1,
|
997 |
+
"size": "NONE"
|
998 |
+
},
|
999 |
+
"right": {
|
1000 |
+
"scaling_factor": 1,
|
1001 |
+
"size": "NONE"
|
1002 |
+
},
|
1003 |
+
"top": {
|
1004 |
+
"scaling_factor": 1,
|
1005 |
+
"size": "NONE"
|
1006 |
+
}
|
1007 |
+
},
|
1008 |
+
"text_alignment": "LEFT",
|
1009 |
+
"text_size_scale": 1,
|
1010 |
+
"underline": "NONE"
|
1011 |
+
},
|
1012 |
+
"caption_description_extra_large": {
|
1013 |
+
"background_color": "#FFFFFF",
|
1014 |
+
"border": {
|
1015 |
+
"bottom": {
|
1016 |
+
"width": 0
|
1017 |
+
},
|
1018 |
+
"left": {
|
1019 |
+
"width": 0
|
1020 |
+
},
|
1021 |
+
"right": {
|
1022 |
+
"width": 0
|
1023 |
+
},
|
1024 |
+
"top": {
|
1025 |
+
"width": 0
|
1026 |
+
}
|
1027 |
+
},
|
1028 |
+
"capitalization": "NONE",
|
1029 |
+
"color": "#808080",
|
1030 |
+
"display": "INLINE",
|
1031 |
+
"font": "Georgia",
|
1032 |
+
"line_height_scale": 1,
|
1033 |
+
"margin": {
|
1034 |
+
"left": {
|
1035 |
+
"scaling_factor": 1,
|
1036 |
+
"size": "DOCUMENT_MARGIN"
|
1037 |
+
},
|
1038 |
+
"right": {
|
1039 |
+
"scaling_factor": 1,
|
1040 |
+
"size": "DOCUMENT_MARGIN"
|
1041 |
+
}
|
1042 |
+
},
|
1043 |
+
"padding": {
|
1044 |
+
"bottom": {
|
1045 |
+
"scaling_factor": 1,
|
1046 |
+
"size": "NONE"
|
1047 |
+
},
|
1048 |
+
"left": {
|
1049 |
+
"scaling_factor": 1,
|
1050 |
+
"size": "NONE"
|
1051 |
+
},
|
1052 |
+
"right": {
|
1053 |
+
"scaling_factor": 1,
|
1054 |
+
"size": "NONE"
|
1055 |
+
},
|
1056 |
+
"top": {
|
1057 |
+
"scaling_factor": 1,
|
1058 |
+
"size": "NONE"
|
1059 |
+
}
|
1060 |
+
},
|
1061 |
+
"text_alignment": "LEFT",
|
1062 |
+
"text_size_scale": 1,
|
1063 |
+
"underline": "NONE"
|
1064 |
+
},
|
1065 |
+
"footer": {
|
1066 |
+
"background_color": "#00FFFFFF",
|
1067 |
+
"border": {
|
1068 |
+
"bottom": {
|
1069 |
+
"width": 0
|
1070 |
+
},
|
1071 |
+
"left": {
|
1072 |
+
"width": 0
|
1073 |
+
},
|
1074 |
+
"right": {
|
1075 |
+
"width": 0
|
1076 |
+
},
|
1077 |
+
"top": {
|
1078 |
+
"width": 0
|
1079 |
+
}
|
1080 |
+
},
|
1081 |
+
"capitalization": "NONE",
|
1082 |
+
"color": "#000000",
|
1083 |
+
"display": "INLINE",
|
1084 |
+
"font": "Helvetica Neue",
|
1085 |
+
"line_height_scale": 1,
|
1086 |
+
"margin": {
|
1087 |
+
"left": {
|
1088 |
+
"scaling_factor": 1,
|
1089 |
+
"size": "DOCUMENT_MARGIN"
|
1090 |
+
},
|
1091 |
+
"right": {
|
1092 |
+
"scaling_factor": 1,
|
1093 |
+
"size": "DOCUMENT_MARGIN"
|
1094 |
+
}
|
1095 |
+
},
|
1096 |
+
"padding": {
|
1097 |
+
"bottom": {
|
1098 |
+
"scaling_factor": 1,
|
1099 |
+
"size": "NONE"
|
1100 |
+
},
|
1101 |
+
"left": {
|
1102 |
+
"scaling_factor": 1,
|
1103 |
+
"size": "NONE"
|
1104 |
+
},
|
1105 |
+
"right": {
|
1106 |
+
"scaling_factor": 1,
|
1107 |
+
"size": "NONE"
|
1108 |
+
},
|
1109 |
+
"top": {
|
1110 |
+
"scaling_factor": 1,
|
1111 |
+
"size": "NONE"
|
1112 |
+
}
|
1113 |
+
},
|
1114 |
+
"text_alignment": "LEFT",
|
1115 |
+
"text_size_scale": 1,
|
1116 |
+
"underline": "NONE"
|
1117 |
+
},
|
1118 |
+
"id": "1331594966932732",
|
1119 |
+
"name": "default",
|
1120 |
+
"is_default": false,
|
1121 |
+
"header": {
|
1122 |
+
"accent_color": "#989898",
|
1123 |
+
"background_color": "#0f5aa5",
|
1124 |
+
"logo": {
|
1125 |
+
"full_resolution_url": "https://scontent.xx.fbcdn.net/v/t39.5687-6/18601675_1346062722145630_7520526922577608704_n.png?_nc_log=1&oh=da39b645a2451707922783ca9216798c&oe=59ABEE74",
|
1126 |
+
"full_resolution_width": 690,
|
1127 |
+
"full_resolution_height": 132,
|
1128 |
+
"thumbnail_url": "https://fb-s-c-a.akamaihd.net/h-ak-fbx/v/t39.5687-6/18316413_1479102688826582_6425345085692444672_n.png?_nc_log=1&oh=bdbfc80602af9814d5ded9fa697c2541&oe=59BA0B55&__gda__=1503683893_41eab7141458daff7d6e0ad0d8ad7506",
|
1129 |
+
"id": "1346062718812297"
|
1130 |
+
},
|
1131 |
+
"logo_scale": 1
|
1132 |
+
}
|
1133 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/AMP/configuration/global.amp.css
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*Global Styles*/
|
2 |
+
.ia2amp-header-bar {
|
3 |
+
margin: -5px 0 0 0;
|
4 |
+
height: 55px;
|
5 |
+
font: 0/0 a;
|
6 |
+
}
|
7 |
+
.ia2amp-header-bar:before {
|
8 |
+
content: ' ';
|
9 |
+
display: inline-block;
|
10 |
+
vertical-align: middle;
|
11 |
+
height: 100%;
|
12 |
+
width: 16.4px;
|
13 |
+
}
|
14 |
+
.ia2amp-header-bar-img-container {
|
15 |
+
display: inline-block;
|
16 |
+
vertical-align: middle;
|
17 |
+
}
|
18 |
+
.ia2amp-header-category {
|
19 |
+
font-size: 10px;
|
20 |
+
line-height: 12px;
|
21 |
+
display: block;
|
22 |
+
font-weight: normal;
|
23 |
+
}
|
24 |
+
.ia2amp-header-h1 {
|
25 |
+
font-size: 24px;
|
26 |
+
line-height: 30px;
|
27 |
+
display: block;
|
28 |
+
font-weight: normal;
|
29 |
+
}
|
30 |
+
.ia2amp-header-h2 {
|
31 |
+
font-size: 16px;
|
32 |
+
line-height: 20px;
|
33 |
+
display: block;
|
34 |
+
font-weight: normal;
|
35 |
+
}
|
36 |
+
.ia2amp-header h3 {
|
37 |
+
font-size: 8px;
|
38 |
+
line-height: 12px;
|
39 |
+
display: block;
|
40 |
+
font-weight: normal;
|
41 |
+
}
|
42 |
+
|
43 |
+
.ia2amp-h1, .ia2amp-h2, .ia2amp-h3 {
|
44 |
+
display: block;
|
45 |
+
font-weight: normal;
|
46 |
+
}
|
47 |
+
|
48 |
+
.ia2amp-h1 {
|
49 |
+
font-size: 19px;
|
50 |
+
line-height: 23px;
|
51 |
+
}
|
52 |
+
|
53 |
+
.ia2amp-h2 {
|
54 |
+
font-size: 16px;
|
55 |
+
line-height: 20px;
|
56 |
+
}
|
57 |
+
|
58 |
+
.ia2amp-p {
|
59 |
+
font-size: 14px;
|
60 |
+
line-height: 20px;
|
61 |
+
display: inline-block;
|
62 |
+
|
63 |
+
|
64 |
+
}
|
65 |
+
.ia2amp-p a {
|
66 |
+
margin: 0;
|
67 |
+
}
|
68 |
+
|
69 |
+
.ia2amp-blockquote {
|
70 |
+
font-size: 14px;
|
71 |
+
line-height: 20px;
|
72 |
+
padding: 0px 13.2px 0px 18.8px;
|
73 |
+
}
|
74 |
+
|
75 |
+
.ia2amp-spacing {
|
76 |
+
display: block;
|
77 |
+
height: 18.8px;
|
78 |
+
margin: 0 16.4px 0 16.4px;
|
79 |
+
}
|
80 |
+
|
81 |
+
header figure figcaption {
|
82 |
+
display: none;
|
83 |
+
}
|
84 |
+
|
85 |
+
.ia2amp-figure {
|
86 |
+
margin: 0;
|
87 |
+
}
|
88 |
+
|
89 |
+
.ia2amp-op-small h1, .ia2amp-op-small h2 {
|
90 |
+
font-size: 10px;
|
91 |
+
display: block;
|
92 |
+
}
|
93 |
+
|
94 |
+
.ia2amp-op-medium h1, .ia2amp-op-medium h2 {
|
95 |
+
font-size: 14px;
|
96 |
+
display: block;
|
97 |
+
}
|
98 |
+
|
99 |
+
.ia2amp-op-large h1, .ia2amp-op-large h2 {
|
100 |
+
font-size: 16px;
|
101 |
+
display: block;
|
102 |
+
}
|
103 |
+
|
104 |
+
.ia2amp-op-extra-large h1, .ia2amp-op-extra-large h2 {
|
105 |
+
font-size: 23px;
|
106 |
+
display: block;
|
107 |
+
}
|
108 |
+
|
109 |
+
.ia2amp-figcaption cite {
|
110 |
+
font-size: 8px;
|
111 |
+
display: block;
|
112 |
+
}
|
113 |
+
|
114 |
+
.ia2amp-op-left {
|
115 |
+
text-align: left;
|
116 |
+
}
|
117 |
+
|
118 |
+
.ia2amp-op-center {
|
119 |
+
text-align: center;
|
120 |
+
}
|
121 |
+
|
122 |
+
.ia2amp-op-right {
|
123 |
+
text-align: right;
|
124 |
+
}
|
125 |
+
|
126 |
+
.ia2amp-figure {
|
127 |
+
position: relative;
|
128 |
+
}
|
129 |
+
|
130 |
+
figcaption.ia2amp-op-vertical-center {
|
131 |
+
position: absolute;
|
132 |
+
z-index: 1000;
|
133 |
+
}
|
134 |
+
|
135 |
+
.ia2amp-footer {
|
136 |
+
display: block;
|
137 |
+
font-size: 12px;
|
138 |
+
line-height: 17px;
|
139 |
+
}
|
140 |
+
|
141 |
+
.ia2amp-footer aside p {
|
142 |
+
margin: 0;
|
143 |
+
}
|
144 |
+
|
145 |
+
.ia2amp-spacing.after-header-bar.before-header-category {
|
146 |
+
height: 18.8px;
|
147 |
+
}
|
148 |
+
|
149 |
+
.ia2amp-spacing.after-header-category.before-header-h1,
|
150 |
+
.ia2amp-spacing.after-header-h1.before-header-h2 {
|
151 |
+
height: 13.2px;
|
152 |
+
}
|
153 |
+
|
154 |
+
.ia2amp-spacing.after-h1.before-h2 {
|
155 |
+
height: 13.2px;
|
156 |
+
}
|
157 |
+
|
158 |
+
.ia2amp-spacing.after-li.before-li {
|
159 |
+
height: 13.2px;
|
160 |
+
}
|
161 |
+
|
162 |
+
.ia2amp-spacing.after-footer.before-footer {
|
163 |
+
height: 18.8px;
|
164 |
+
}
|
165 |
+
|
166 |
+
.ia2amp-spacing.after-header-h1.before-header-author,
|
167 |
+
.ia2amp-spacing.after-header-h2.before-header-author {
|
168 |
+
height: 18.8px;
|
169 |
+
}
|
170 |
+
|
171 |
+
.ia2amp-spacing.after-header-author.before-header-date {
|
172 |
+
height: 0;
|
173 |
+
}
|
174 |
+
|
175 |
+
.ia2amp-spacing.after-header-date.before-h1,
|
176 |
+
.ia2amp-spacing.after-header-date.before-h2,
|
177 |
+
.ia2amp-spacing.after-header-date.before-p {
|
178 |
+
height: 26.4px;
|
179 |
+
}
|
180 |
+
|
181 |
+
.ia2amp-spacing.after-h1.before-p,
|
182 |
+
.ia2amp-spacing.after-h2.before-p,
|
183 |
+
.ia2amp-spacing.after-h3.before-p {
|
184 |
+
height: 18.8px;
|
185 |
+
}
|
186 |
+
|
187 |
+
.ia2amp-spacing.after-blockquote.before-p {
|
188 |
+
height: 18.8px;
|
189 |
+
}
|
190 |
+
|
191 |
+
.ia2amp-spacing.after-slideshow,
|
192 |
+
.ia2amp-spacing.before-slideshow,
|
193 |
+
.ia2amp-spacing.after-interactive,
|
194 |
+
.ia2amp-spacing.before-interactive,
|
195 |
+
.ia2amp-spacing.after-image,
|
196 |
+
.ia2amp-spacing.before-image,
|
197 |
+
.ia2amp-spacing.after-figcaption-small,
|
198 |
+
.ia2amp-spacing.after-figcaption-medium,
|
199 |
+
.ia2amp-spacing.after-figcaption-large,
|
200 |
+
.ia2amp-spacing.after-figcaption-extra-large {
|
201 |
+
height: 26.4px;
|
202 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/CSSBuilder.php
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Helper class to build up CSS structure file.
|
13 |
+
* Usage example:
|
14 |
+
* <code>
|
15 |
+
* $cssBuilder = new CSSBuilder();
|
16 |
+
* $cssBuilder->addProperty('.someClass', 'width', '300px')
|
17 |
+
* ->addProperty('.someClass', 'height', '400px')
|
18 |
+
* ->addProperty('.otherClass', 'background-color', '#aabbcc')
|
19 |
+
* ->addProperty('.otherClass', 'border-width', '2px');
|
20 |
+
* $result = $cssBuilder->build(true);
|
21 |
+
* </code>
|
22 |
+
*/
|
23 |
+
class CSSBuilder
|
24 |
+
{
|
25 |
+
/**
|
26 |
+
* @var array('string'=>array('string' => properties))
|
27 |
+
*/
|
28 |
+
private $selectors = array();
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var string prefix for css selector classes
|
32 |
+
*/
|
33 |
+
private $prefix;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var string spacing For height on the separator divs
|
37 |
+
*/
|
38 |
+
private $spacing;
|
39 |
+
|
40 |
+
public function __construct($prefix = 'ia2amp-', $spacing = 'spacing')
|
41 |
+
{
|
42 |
+
$this->prefix = $prefix;
|
43 |
+
$this->spacing = $spacing;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Simple key => value method setting for CSS properties. This method does not apply any validation
|
48 |
+
* be cautious about using it.
|
49 |
+
* @param string $selector The selector for the CSS, free format accepted. Be cautious.
|
50 |
+
* @param string $property The property name on CSS, free format accepted. Be cautious.
|
51 |
+
* @param string $value The property value on CSS, free format accepted. Be cautious.
|
52 |
+
* @return CSSBuilder $this instance.
|
53 |
+
*/
|
54 |
+
public function addProperty($selector, $property, $value)
|
55 |
+
{
|
56 |
+
if (isset($this->selectors[$selector])) {
|
57 |
+
$selectorProps = $this->selectors[$selector];
|
58 |
+
} else {
|
59 |
+
$selectorProps = array();
|
60 |
+
}
|
61 |
+
|
62 |
+
$selectorProps[$property] = $value;
|
63 |
+
$this->selectors[$selector] = $selectorProps;
|
64 |
+
|
65 |
+
return $this;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Adds property and value to the $class. It creates the selector, apply prefix and builds up
|
70 |
+
* css selector class grouping the properties.
|
71 |
+
* @param string|array<string> $class The class to be applied to the selector.
|
72 |
+
* @param string $property The property name on CSS, free format accepted. Be cautious.
|
73 |
+
* @param string $value The property value on CSS, free format accepted. Be cautious.
|
74 |
+
* @return CSSBuilder $this instance.
|
75 |
+
*/
|
76 |
+
public function addToSelector($class, $property, $value)
|
77 |
+
{
|
78 |
+
return $this->addProperty($this->buildCssSelector($class), $property, $value);
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Adds dimension sized property value to the $class. It creates the selector, apply prefix and builds up
|
83 |
+
* css selector class grouping the properties. If value not informed, zero will be placed.
|
84 |
+
* @param string|array<string> $class The class to be applied to the selector.
|
85 |
+
* @param string $property The property name on CSS, free format accepted. Be cautious.
|
86 |
+
* @param string|float|int $dimension The property value on CSS.
|
87 |
+
* @param string $unit The unit to be applied. Default value: 'px'.
|
88 |
+
* @return CSSBuilder $this instance.
|
89 |
+
*/
|
90 |
+
public function addDimensionToSelector($class, $property, $dimension, $unit = 'px')
|
91 |
+
{
|
92 |
+
return $this->addProperty($this->buildCssSelector($class), $property, $dimension ? $dimension.$unit : '0');
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Adds condensed dimensions to property value selected by $class. If value not informed, zero will be placed.
|
97 |
+
* @param string|array<string> $class The class to be applied to the selector.
|
98 |
+
* @param string $property The property name on CSS, free format accepted. Be cautious.
|
99 |
+
* @param string|float|int $top The property value for top position on CSS.
|
100 |
+
* @param string|float|int $right The property value for right position on CSS.
|
101 |
+
* @param string|float|int $bottom The property value for bottom position on CSS.
|
102 |
+
* @param string|float|int $left The property value for left position on CSS.
|
103 |
+
* * @param string $unit The unit to be applied. Default value: 'px'.
|
104 |
+
* @return CSSBuilder $this instance.
|
105 |
+
*/
|
106 |
+
public function addTopRightBottomLeftToSelector($class, $property, $top, $right, $bottom, $left, $unit = 'px')
|
107 |
+
{
|
108 |
+
$dimension =
|
109 |
+
($top ? $top.$unit : '0').' '.
|
110 |
+
($right ? $right.$unit : '0').' '.
|
111 |
+
($bottom ? $bottom.$unit : '0').' '.
|
112 |
+
($left ? $left.$unit : '0');
|
113 |
+
return $this->addProperty($this->buildCssSelector($class), $property, $dimension);
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Adds spacing height value to the proper selected class.
|
118 |
+
* @param string|array<string> $class The class to be applied to the selector.
|
119 |
+
* @param string|float|int $height The spacing value for spacing.
|
120 |
+
* @param string $unit The unity to be applied. Default value: 'px'.
|
121 |
+
* @return CSSBuilder $this instance.
|
122 |
+
*/
|
123 |
+
public function addHeightSpacingToSelector($class, $height, $unit = 'px')
|
124 |
+
{
|
125 |
+
return $this->addProperty(
|
126 |
+
$this->buildCssSelector($class).' + '.$this->buildCssSelector($this->spacing),
|
127 |
+
'height',
|
128 |
+
$height ? $height.$unit : '0'
|
129 |
+
);
|
130 |
+
}
|
131 |
+
|
132 |
+
|
133 |
+
private function buildCssClass($cssClassName)
|
134 |
+
{
|
135 |
+
return $this->prefix.$cssClassName;
|
136 |
+
}
|
137 |
+
|
138 |
+
private function buildCssSelector($class)
|
139 |
+
{
|
140 |
+
if (is_array($class)) {
|
141 |
+
$selectors = array();
|
142 |
+
foreach ($class as $singleClass) {
|
143 |
+
$selectors[] = $this->buildCssSelector($singleClass);
|
144 |
+
}
|
145 |
+
return implode(', ', $selectors);
|
146 |
+
} else {
|
147 |
+
return '.'.$this->buildCssClass($class);
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Builds the css output representing the current status of the CSSBuilder structure.
|
154 |
+
* @param $formatOutput boolean Indicates if output will be formated.
|
155 |
+
* @return string The CSS generated based on current status.
|
156 |
+
*/
|
157 |
+
public function build($formatOutput = true)
|
158 |
+
{
|
159 |
+
$result = '';
|
160 |
+
$formatIdent = $formatOutput ? ' ' : '';
|
161 |
+
$formatNewLine = $formatOutput ? "\n" : '';
|
162 |
+
foreach ($this->selectors as $selector => $properties) {
|
163 |
+
if ($properties && !empty($properties)) {
|
164 |
+
if ($result !== '') {
|
165 |
+
$result = $result.$formatNewLine.$formatNewLine;
|
166 |
+
}
|
167 |
+
|
168 |
+
$result = $result.$selector.' {'.$formatNewLine;
|
169 |
+
foreach ($properties as $property => $value) {
|
170 |
+
$result = $result.$formatIdent.$property.': '.$value.';';
|
171 |
+
$result = $result.$formatNewLine;
|
172 |
+
}
|
173 |
+
$result = $result.'}';
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
return $result;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Auxiliary method to extract the full qualified class name.
|
182 |
+
*
|
183 |
+
* @return string The full qualified name of class.
|
184 |
+
*/
|
185 |
+
public static function getClassName()
|
186 |
+
{
|
187 |
+
return get_called_class();
|
188 |
+
}
|
189 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/CallbackHook.php
ADDED
@@ -0,0 +1,390 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* CallbackHook class. This is the helper class to get the hooks prioritized, called, removed and mantained.
|
13 |
+
*/
|
14 |
+
class CallbackHook implements \Iterator, \ArrayAccess
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var array Callback functions/instance->methods
|
19 |
+
*/
|
20 |
+
public $callbacks = array();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var array The priority keys of actively running iterations of a hook.
|
24 |
+
*/
|
25 |
+
private $iterations = array();
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var array The current priority of actively running iterations of a hook.
|
29 |
+
*/
|
30 |
+
private $currentPriority = array();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var int Number of levels this hook can be recursively called.
|
34 |
+
*/
|
35 |
+
private $nestingLevel = 0;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Hooks a function or method to a specific filter action.
|
39 |
+
*
|
40 |
+
* @param string $tag The name of the filter to hook the $functionToAdd callback to.
|
41 |
+
* @param callable $functionToAdd The callback to be run when the filter is applied.
|
42 |
+
* @param int $priority The order in which the functions associated with a
|
43 |
+
* particular action are executed. Lower numbers correspond with
|
44 |
+
* earlier execution, and functions with the same priority are executed
|
45 |
+
* in the order in which they were added to the action.
|
46 |
+
* @param int $acceptedArgs The number of arguments the function accepts.
|
47 |
+
*/
|
48 |
+
public function addFilter($idx, $tag, $functionToAdd, $priority, $acceptedArgs)
|
49 |
+
{
|
50 |
+
$priorityExisted = isset($this->callbacks[$priority]);
|
51 |
+
|
52 |
+
$this->callbacks[$priority][$idx] = array(
|
53 |
+
'function' => $functionToAdd,
|
54 |
+
'accepted_args' => $acceptedArgs
|
55 |
+
);
|
56 |
+
|
57 |
+
// if we're adding a new priority to the list, put them back in sorted order
|
58 |
+
if (!$priorityExisted && count($this->callbacks) > 1) {
|
59 |
+
ksort($this->callbacks, SORT_NUMERIC);
|
60 |
+
}
|
61 |
+
|
62 |
+
if ($this->nestingLevel > 0) {
|
63 |
+
$this->resortPerPriority($priority, $priorityExisted);
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Handles reseting callback priority keys mid-iteration.
|
69 |
+
*
|
70 |
+
* @param bool|int $newPriority Optional. The priority of the new filter being added. Default false,
|
71 |
+
* for no priority being added.
|
72 |
+
* @param bool $priorityExisted Optional. Flag for whether the priority already existed before the new
|
73 |
+
* filter was added. Default false.
|
74 |
+
*/
|
75 |
+
private function resortPerPriority($newPriority = false, $priorityExisted = false)
|
76 |
+
{
|
77 |
+
$newPriorities = array_keys($this->callbacks);
|
78 |
+
|
79 |
+
// If there are no remaining hooks, clear out all running iterations.
|
80 |
+
if (! $newPriorities) {
|
81 |
+
foreach ($this->iterations as $index => $iteration) {
|
82 |
+
$this->iterations[$index] = $newPriorities;
|
83 |
+
}
|
84 |
+
return;
|
85 |
+
}
|
86 |
+
|
87 |
+
$min = min($newPriorities);
|
88 |
+
foreach ($this->iterations as $index => &$iteration) {
|
89 |
+
$current = current($iteration);
|
90 |
+
// If we're already at the end of this iteration, just leave the array pointer where it is.
|
91 |
+
if (false === $current) {
|
92 |
+
continue;
|
93 |
+
}
|
94 |
+
|
95 |
+
$iteration = $newPriorities;
|
96 |
+
|
97 |
+
if ($current < $min) {
|
98 |
+
array_unshift($iteration, $current);
|
99 |
+
continue;
|
100 |
+
}
|
101 |
+
|
102 |
+
while (current($iteration) < $current) {
|
103 |
+
if (false === next($iteration)) {
|
104 |
+
break;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
// If we have a new priority that didn't exist, but ::applyFilters() thinks it's the current priority...
|
109 |
+
if ($newPriority === $this->currentPriority[$index] && ! $priorityExisted) {
|
110 |
+
/*
|
111 |
+
* ... and the new priority is the same as what $this->iterations thinks is the previous
|
112 |
+
* priority, we need to move back to it.
|
113 |
+
*/
|
114 |
+
|
115 |
+
if (false === current($iteration)) {
|
116 |
+
// If we've already moved off the end of the array, go back to the last element.
|
117 |
+
$prev = end($iteration);
|
118 |
+
} else {
|
119 |
+
// Otherwise, just go back to the previous element.
|
120 |
+
$prev = prev($iteration);
|
121 |
+
}
|
122 |
+
if (false === $prev) {
|
123 |
+
// Start of the array. Reset, and go about our day.
|
124 |
+
reset($iteration);
|
125 |
+
} elseif ($newPriority !== $prev) {
|
126 |
+
// Previous wasn't the same. Move forward again.
|
127 |
+
next($iteration);
|
128 |
+
}
|
129 |
+
}
|
130 |
+
}
|
131 |
+
unset($iteration);
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Unhooks a function or method from a specific filter action.
|
136 |
+
*
|
137 |
+
* @param string $tag The filter hook to which the function to be removed is hooked. Used
|
138 |
+
* for building the callback ID when SPL is not available.
|
139 |
+
* @param int $priority The exact priority used when adding the original filter callback.
|
140 |
+
* @return bool Whether the callback existed before it was removed.
|
141 |
+
*/
|
142 |
+
public function removeFilter($idx, $tag, $priority)
|
143 |
+
{
|
144 |
+
$exists = isset($this->callbacks[$priority][$idx]);
|
145 |
+
if ($exists) {
|
146 |
+
unset($this->callbacks[$priority][$idx]);
|
147 |
+
if (! $this->callbacks[$priority]) {
|
148 |
+
unset($this->callbacks[$priority]);
|
149 |
+
if ($this->nestingLevel > 0) {
|
150 |
+
$this->resortPerPriority();
|
151 |
+
}
|
152 |
+
}
|
153 |
+
}
|
154 |
+
return $exists;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Checks if a specific action has been registered for this hook.
|
159 |
+
*
|
160 |
+
* @param callable|bool $functionToCheck Optional. The callback to check for. Default false.
|
161 |
+
* @param string $tag Optional. The name of the filter hook. Used for building
|
162 |
+
* the callback ID when SPL is not available. Default empty.
|
163 |
+
* @return bool|int The priority of that hook is returned, or false if the function is not attached.
|
164 |
+
*/
|
165 |
+
public function hasFilter($idx, $tag = '', $functionToCheck = false)
|
166 |
+
{
|
167 |
+
if (false === $functionToCheck) {
|
168 |
+
return $this->hasFilters();
|
169 |
+
}
|
170 |
+
|
171 |
+
if (! $idx) {
|
172 |
+
return false;
|
173 |
+
}
|
174 |
+
|
175 |
+
foreach ($this->callbacks as $priority => $callbacks) {
|
176 |
+
if (isset($callbacks[$idx])) {
|
177 |
+
return $priority;
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
return false;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Checks if any callbacks have been registered for this hook.
|
186 |
+
*
|
187 |
+
* @return bool True if callbacks have been registered for the current hook, otherwise false.
|
188 |
+
*/
|
189 |
+
public function hasFilters()
|
190 |
+
{
|
191 |
+
foreach ($this->callbacks as $callbacks) {
|
192 |
+
if ($callbacks) {
|
193 |
+
return true;
|
194 |
+
}
|
195 |
+
}
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Removes all callbacks from the current filter.
|
201 |
+
*
|
202 |
+
* @param int|bool $priority Optional. The priority number to remove. Default false.
|
203 |
+
*/
|
204 |
+
public function removeAllFilters($priority = false)
|
205 |
+
{
|
206 |
+
if (! $this->callbacks) {
|
207 |
+
return;
|
208 |
+
}
|
209 |
+
|
210 |
+
if (false === $priority) {
|
211 |
+
$this->callbacks = array();
|
212 |
+
} else if (isset($this->callbacks[$priority])) {
|
213 |
+
unset($this->callbacks[$priority]);
|
214 |
+
}
|
215 |
+
|
216 |
+
if ($this->nestingLevel > 0) {
|
217 |
+
$this->resortPerPriority();
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Calls the callback functions added to a filter hook.
|
223 |
+
*
|
224 |
+
* @param mixed $value The value to filter.
|
225 |
+
* @param array $args Arguments to pass to callbacks.
|
226 |
+
* @return mixed The filtered value after all hooked functions are applied to it.
|
227 |
+
*/
|
228 |
+
public function applyFilters($value, $args)
|
229 |
+
{
|
230 |
+
if (!$this->callbacks) {
|
231 |
+
return $value;
|
232 |
+
}
|
233 |
+
|
234 |
+
$nestingLevel = $this->nestingLevel++;
|
235 |
+
|
236 |
+
$this->iterations[$nestingLevel] = array_keys($this->callbacks);
|
237 |
+
$num_args = count($args);
|
238 |
+
|
239 |
+
do {
|
240 |
+
$this->currentPriority[$nestingLevel] = $priority = current($this->iterations[$nestingLevel]);
|
241 |
+
|
242 |
+
foreach ($this->callbacks[$priority] as $callbackPriority) {
|
243 |
+
$args[0] = $value;
|
244 |
+
|
245 |
+
// Avoid the array_slice if possible.
|
246 |
+
if ($callbackPriority['accepted_args'] == 0) {
|
247 |
+
$value = call_user_func_array($callbackPriority['function'], array());
|
248 |
+
} elseif ($callbackPriority['accepted_args'] >= $num_args) {
|
249 |
+
$value = call_user_func_array($callbackPriority['function'], $args);
|
250 |
+
} else {
|
251 |
+
$value = call_user_func_array($callbackPriority['function'], array_slice($args, 0, (int)$callbackPriority['accepted_args']));
|
252 |
+
}
|
253 |
+
}
|
254 |
+
} while (false !== next($this->iterations[$nestingLevel]));
|
255 |
+
|
256 |
+
unset($this->iterations[$nestingLevel]);
|
257 |
+
unset($this->currentPriority[$nestingLevel]);
|
258 |
+
|
259 |
+
$this->nestingLevel--;
|
260 |
+
|
261 |
+
return $value;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Return the current priority level of the currently running iteration of the hook.
|
266 |
+
*
|
267 |
+
* @return int|false If the hook is running, return the current priority level. If it isn't running, return false.
|
268 |
+
*/
|
269 |
+
public function currentPriority()
|
270 |
+
{
|
271 |
+
if (false === current($this->iterations)) {
|
272 |
+
return false;
|
273 |
+
}
|
274 |
+
|
275 |
+
return current(current($this->iterations));
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Determines whether an offset value exists.
|
280 |
+
*
|
281 |
+
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
282 |
+
*
|
283 |
+
* @param mixed $offset An offset to check for.
|
284 |
+
* @return bool True if the offset exists, false otherwise.
|
285 |
+
*/
|
286 |
+
public function offsetExists($offset)
|
287 |
+
{
|
288 |
+
return isset($this->callbacks[$offset]);
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Retrieves a value at a specified offset.
|
293 |
+
*
|
294 |
+
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
295 |
+
*
|
296 |
+
* @param mixed $offset The offset to retrieve.
|
297 |
+
* @return mixed If set, the value at the specified offset, null otherwise.
|
298 |
+
*/
|
299 |
+
public function offsetGet($offset)
|
300 |
+
{
|
301 |
+
return isset($this->callbacks[$offset]) ? $this->callbacks[$offset] : null;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Sets a value at a specified offset.
|
306 |
+
*
|
307 |
+
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
308 |
+
*
|
309 |
+
* @param mixed $offset The offset to assign the value to.
|
310 |
+
* @param mixed $value The value to set.
|
311 |
+
*/
|
312 |
+
public function offsetSet($offset, $value)
|
313 |
+
{
|
314 |
+
if (is_null($offset)) {
|
315 |
+
$this->callbacks[] = $value;
|
316 |
+
} else {
|
317 |
+
$this->callbacks[$offset] = $value;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Unsets a specified offset.
|
323 |
+
*
|
324 |
+
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
325 |
+
*
|
326 |
+
* @param mixed $offset The offset to unset.
|
327 |
+
*/
|
328 |
+
public function offsetUnset($offset)
|
329 |
+
{
|
330 |
+
unset($this->callbacks[$offset]);
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Returns the current element.
|
335 |
+
*
|
336 |
+
* @link http://php.net/manual/en/iterator.current.php
|
337 |
+
*
|
338 |
+
* @return array Of callbacks at current priority.
|
339 |
+
*/
|
340 |
+
public function current()
|
341 |
+
{
|
342 |
+
return current($this->callbacks);
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Moves forward to the next element.
|
347 |
+
*
|
348 |
+
* @link http://php.net/manual/en/iterator.next.php
|
349 |
+
*
|
350 |
+
* @return array Of callbacks at next priority.
|
351 |
+
*/
|
352 |
+
public function next()
|
353 |
+
{
|
354 |
+
return next($this->callbacks);
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Returns the key of the current element.
|
359 |
+
*
|
360 |
+
* @link http://php.net/manual/en/iterator.key.php
|
361 |
+
*
|
362 |
+
* @return mixed Returns current priority on success, or NULL on failure
|
363 |
+
*/
|
364 |
+
public function key()
|
365 |
+
{
|
366 |
+
return key($this->callbacks);
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Checks if current position is valid.
|
371 |
+
*
|
372 |
+
* @link http://php.net/manual/en/iterator.valid.php
|
373 |
+
*
|
374 |
+
* @return boolean
|
375 |
+
*/
|
376 |
+
public function valid()
|
377 |
+
{
|
378 |
+
return key($this->callbacks) !== null;
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Rewinds the Iterator to the first element.
|
383 |
+
*
|
384 |
+
* @link http://php.net/manual/en/iterator.rewind.php
|
385 |
+
*/
|
386 |
+
public function rewind()
|
387 |
+
{
|
388 |
+
reset($this->callbacks);
|
389 |
+
}
|
390 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/Hook.php
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class to facilitate hooking callable statements.
|
13 |
+
* Usage example:
|
14 |
+
* <code>
|
15 |
+
* // Obtain the hook instance or create one
|
16 |
+
* Hook::create();
|
17 |
+
* // Name your hook with the string you want and set the default function to be called.
|
18 |
+
* $result = $hook->call('hook_name', array('Facebook\InstantArticles\hook\HookTest', 'staticMethodHookParams'), array('param1', 'param2'));
|
19 |
+
* // Anyone can override your callable by using this line:
|
20 |
+
* $hook->setHook('hook_name', array($this, 'methodHookReplacing'));
|
21 |
+
* </code>
|
22 |
+
*/
|
23 |
+
class Hook
|
24 |
+
{
|
25 |
+
/* Hooks to have overriden callable */
|
26 |
+
private $hooks = array();
|
27 |
+
private $params = array();
|
28 |
+
|
29 |
+
/* Hooks to have before callable */
|
30 |
+
private $beforeHooks = array();
|
31 |
+
private $beforeParams = array();
|
32 |
+
|
33 |
+
/* Hooks to have after callable */
|
34 |
+
private $afterHooks = array();
|
35 |
+
private $afterParams = array();
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Private constructor to force factory method: Hook::create();
|
39 |
+
*/
|
40 |
+
private function __construct()
|
41 |
+
{
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return Hook new instance of the Hook class.
|
46 |
+
*/
|
47 |
+
public static function create()
|
48 |
+
{
|
49 |
+
return new self();
|
50 |
+
}
|
51 |
+
|
52 |
+
public function clearHooks($hookName)
|
53 |
+
{
|
54 |
+
$this->removeHook($hookName);
|
55 |
+
$this->removeAfterHook($hookName);
|
56 |
+
$this->removeBeforeHook($hookName);
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Overrides a hook by name, by setting a new callable, with params.
|
61 |
+
* @param string $hookName The name for callable instruction to be intercepted/hooked. Use different names if you need different hooks.
|
62 |
+
* @param string/array $callable The string method to be called or array with array('Namespace.ClassName', 'methodName')
|
63 |
+
* @param array(mixed) The params to be used into your methodName from your callable.
|
64 |
+
*/
|
65 |
+
public function setHook($hookName, $callable, $params = null)
|
66 |
+
{
|
67 |
+
$this->hooks[$hookName] = $callable;
|
68 |
+
if (isset($params) && $params) {
|
69 |
+
$this->params[$hookName] = $params;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
public function removeHook($hookName)
|
74 |
+
{
|
75 |
+
unset($this->hooks[$hookName]);
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Overrides a before event hook by name, by setting a new callable, with params. The returned value from the beforeHook will be ignored. There is no blocking system.
|
80 |
+
* @param string $hookName The name for callable instruction to be intercepted/hooked. Use different names if you need different hooks.
|
81 |
+
* @param string/array $callable The string method to be called or array with array('Namespace.ClassName', 'methodName')
|
82 |
+
* @param array(mixed) The params to be used into your methodName from your callable.
|
83 |
+
*/
|
84 |
+
public function setBeforeHook($hookName, $callable, $params = null)
|
85 |
+
{
|
86 |
+
$this->beforeHooks[$hookName] = $callable;
|
87 |
+
if (isset($params) && $params) {
|
88 |
+
$this->beforeParams[$hookName] = $params;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
public function removeBeforeHook($hookName)
|
93 |
+
{
|
94 |
+
unset($this->beforeHooks[$hookName]);
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Overrides a after event hook by name, by setting a new callable, with params. The returned value from the after will be ignored.
|
99 |
+
* @param string $hookName The name for callable instruction to be intercepted/hooked. Use different names if you need different hooks.
|
100 |
+
* @param string/array $callable The string method to be called or array with array('Namespace.ClassName', 'methodName')
|
101 |
+
* @param array(mixed) The params to be used into your methodName from your callable.
|
102 |
+
*/
|
103 |
+
public function setAfterHook($hookName, $callable, $params = null)
|
104 |
+
{
|
105 |
+
$this->afterHooks[$hookName] = $callable;
|
106 |
+
if (isset($params) && $params) {
|
107 |
+
$this->afterParams[$hookName] = $params;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
public function removeAfterHook($hookName)
|
112 |
+
{
|
113 |
+
unset($this->afterHooks[$hookName]);
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Any callable method/call that you want to make it possible to have it
|
118 |
+
* possible to be overriden or a before/after hook, just call it by name
|
119 |
+
* using your hook instance. This make the callable to be intercepted/overriden.
|
120 |
+
* @param string $hookName The name for callable instruction to be intercepted/hooked. Use different names if you need different hooks.
|
121 |
+
* @param string/array $callable The string method to be called or array with array('Namespace.ClassName', 'methodName')
|
122 |
+
* @param array(mixed) The params to be used into your methodName from your callable.
|
123 |
+
*/
|
124 |
+
public function call($hookName, $callable, $params = array())
|
125 |
+
{
|
126 |
+
// Treats before hook is called. To set something to happen before any hook, just use setBeforeHook('hook_name', ...)
|
127 |
+
if (array_key_exists($hookName, $this->beforeHooks) && isset($this->beforeHooks[$hookName])) {
|
128 |
+
$beforeCallable = $this->beforeHooks[$hookName];
|
129 |
+
$beforeParams = array();
|
130 |
+
if (array_key_exists($hookName, $this->beforeParams) && isset($this->beforeParams[$hookName])) {
|
131 |
+
$beforeParams = $this->beforeParams[$hookName];
|
132 |
+
}
|
133 |
+
// Calls the "before" event $hookName, ignoring the return
|
134 |
+
call_user_func_array($beforeCallable, $beforeParams);
|
135 |
+
}
|
136 |
+
|
137 |
+
// Treats the Hook itself
|
138 |
+
if (array_key_exists($hookName, $this->hooks) && isset($this->hooks[$hookName])) {
|
139 |
+
$callable = $this->hooks[$hookName];
|
140 |
+
if (array_key_exists($hookName, $this->params) && isset($this->params[$hookName])) {
|
141 |
+
$params = $this->params[$hookName];
|
142 |
+
}
|
143 |
+
}
|
144 |
+
$return = call_user_func_array($callable, $params);
|
145 |
+
|
146 |
+
|
147 |
+
// Treats after hook is called. To set something to happen after any hook, just use setAfterHook('hook_name', ...)
|
148 |
+
if (array_key_exists($hookName, $this->afterHooks) && isset($this->afterHooks[$hookName])) {
|
149 |
+
$afterCallable = $this->afterHooks[$hookName];
|
150 |
+
$afterParams = array();
|
151 |
+
if (array_key_exists($hookName, $this->afterParams) && isset($this->afterParams[$hookName])) {
|
152 |
+
$afterParams = $this->afterParams[$hookName];
|
153 |
+
}
|
154 |
+
|
155 |
+
// Calls the "after" event $hookName ignoring the return
|
156 |
+
call_user_func_array($afterCallable, $afterParams);
|
157 |
+
}
|
158 |
+
|
159 |
+
return $return;
|
160 |
+
}
|
161 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/Observer.php
ADDED
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class Observer for managing filtering into the key and extensible points into
|
13 |
+
* your project architecture.
|
14 |
+
*
|
15 |
+
* Usage example:
|
16 |
+
* <code>
|
17 |
+
* // Obtain the observer instance or create one
|
18 |
+
* $observer = Observer::create();
|
19 |
+
* // Name your hook with the string you want and set the default function to be called.
|
20 |
+
* $result = $obs->applyFilters('filter name', SomeClass::statciMethodBeingCalled('param1', 'param2'));
|
21 |
+
* // Anyone can override your callable by using this line:
|
22 |
+
* $obs->addFilter('filter name', array($this, 'methodHookReplacing'));
|
23 |
+
* </code>
|
24 |
+
*/
|
25 |
+
class Observer
|
26 |
+
{
|
27 |
+
private static $filterCount = 0;
|
28 |
+
|
29 |
+
/* Filters configured. Mapped array: 'filter name' => CallbackHolder */
|
30 |
+
private $callbacks = array();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Private constructor to force factory method: Hook::create();
|
34 |
+
*/
|
35 |
+
private function __construct()
|
36 |
+
{
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @return Hook new instance of the Hook class.
|
41 |
+
*/
|
42 |
+
public static function create()
|
43 |
+
{
|
44 |
+
return new self();
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Hook functions/methods to change, replace or add info to the data you are filtering.
|
49 |
+
*
|
50 |
+
* Anyone can modify data by binding a callback to a filter hook. When the filter
|
51 |
+
* is later applied, each bound callback is run in order of priority, and given
|
52 |
+
* the opportunity to modify a value by returning a new value or modifying the
|
53 |
+
* value orinally returned.
|
54 |
+
*
|
55 |
+
* Check the following example on how we can bind callback to a filter:
|
56 |
+
*
|
57 |
+
* function myCallback( $value ) {
|
58 |
+
* // Maybe modify $value in some way.
|
59 |
+
* return $value;
|
60 |
+
* }
|
61 |
+
* $observer = Observer::create();
|
62 |
+
* $observer->addFilter('myFilterName', 'myCallback');
|
63 |
+
*
|
64 |
+
* Bound callbacks can receive zero to the total defined in addFilter method call.
|
65 |
+
*
|
66 |
+
* Here are few more examples about how to call the apply filters and how to set it up
|
67 |
+
* on the addFilter method. For example:
|
68 |
+
*
|
69 |
+
* // Call to be filtered
|
70 |
+
* $value = $observer->applyFilters('filterName', $value, $arg2, $arg3);
|
71 |
+
*
|
72 |
+
* // Accepting zero/one arguments.
|
73 |
+
* function callbackFunction() {
|
74 |
+
* ...
|
75 |
+
* return 'value overriden';
|
76 |
+
* }
|
77 |
+
* $observer = Observer::create();
|
78 |
+
* $observer->addFilter('filterName', 'callbackFunction'); // Where $priority is default 10, $acceptedArgs is default 1.
|
79 |
+
*
|
80 |
+
* // Accepting two arguments (three possible).
|
81 |
+
* function callbackFunction( $value, $arg2 ) {
|
82 |
+
* ...
|
83 |
+
* return $modifiedValue;
|
84 |
+
* }
|
85 |
+
* $observer = Observer::create();
|
86 |
+
* $observer->addFilter( 'filterName', 'callbackFunction', 5, 2 ); // Where $priority is 5, $acceptedArgs is 2.
|
87 |
+
*
|
88 |
+
* @param string $tag The name of the filter hook.
|
89 |
+
* @param callable $functionToAdd The callback to be called when the filter is applied.
|
90 |
+
* @param int $priority Optional. Priority order to run the multiple hooks appended to same $tag.
|
91 |
+
* As lower the number is, more priority it will have. Default 10.
|
92 |
+
* @param int $acceptedArgs Optional. The number of arguments the function accepts. Default 1.
|
93 |
+
*/
|
94 |
+
public function addFilter($tag, $functionToAdd, $priority = 10, $acceptedArgs = 1)
|
95 |
+
{
|
96 |
+
// This is a crude filter, needs to create the CallbackHook manager for that
|
97 |
+
if (!isset($this->callbacks[$tag])) {
|
98 |
+
$this->callbacks[$tag] = new CallbackHook();
|
99 |
+
}
|
100 |
+
// Builds unique identifier for this callback call. This is important due to
|
101 |
+
// same method calls from different instances.
|
102 |
+
$idx = $this->getUniqueIndexID($tag, $functionToAdd);
|
103 |
+
$this->callbacks[$tag]->addFilter($idx, $tag, $functionToAdd, $priority, $acceptedArgs);
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Call all the functions hooked to that filter name. If none are hooked the value will be returned back.
|
108 |
+
*
|
109 |
+
* A good strategy to use this function is to create hooking points into your code, by easily calling the
|
110 |
+
* applyFilters() method.
|
111 |
+
*
|
112 |
+
* Check this example:
|
113 |
+
* $observer = Observer::create();
|
114 |
+
* $url = $observer->applyFilters('GET_THE_URL', $a_url);
|
115 |
+
*
|
116 |
+
* You might not have initially a filter designed to this URL getter, but in
|
117 |
+
* the future you might have a URL redirect or even https enforcement, or anything
|
118 |
+
*
|
119 |
+
* When callback functions get attached to this 'GET_THE_URL' hook name, it will
|
120 |
+
* filter and can modify the final result.
|
121 |
+
*
|
122 |
+
* Full example:
|
123 |
+
*
|
124 |
+
* // The filter callback function
|
125 |
+
* function myCallback($value, $param1, $param2) {
|
126 |
+
* // do something with the value
|
127 |
+
* return $value;
|
128 |
+
* }
|
129 |
+
* $observer = Observer::create();
|
130 |
+
* $observer->addFilter('filter name', 'myCallback', 10, 3);
|
131 |
+
*
|
132 |
+
* /*
|
133 |
+
* * Apply the filters calling the 'myCallback' function we
|
134 |
+
* * "hooked" to $tag using the addFilter() method.
|
135 |
+
* * 'filter name' is the filter hook $tag
|
136 |
+
* * 'value to filter' is the value being filtered
|
137 |
+
* * $param1 and $param2 are the additional arguments passed to the callback.
|
138 |
+
* $value = $observer->applyFilters('filter name', 'value to filter', $param1, $param2);
|
139 |
+
*
|
140 |
+
* @param string $tag The name of the filter hook.
|
141 |
+
* @param mixed $value The value on which the filters hooked to `$tag` are applied on.
|
142 |
+
* @param mixed $var,... Additional variables passed to the functions hooked to `$tag`.
|
143 |
+
* @return mixed The filtered value after all hooked functions are applied to it.
|
144 |
+
*/
|
145 |
+
public function applyFilters($tag, $value/*, $var...*/)
|
146 |
+
{
|
147 |
+
$args = array();
|
148 |
+
|
149 |
+
// In case no filters configured for this hook, simply return informed value.
|
150 |
+
if (!isset($this->callbacks[$tag])) {
|
151 |
+
return $value;
|
152 |
+
}
|
153 |
+
|
154 |
+
// Uses this to be compatible with PHP < 5.6
|
155 |
+
$args = func_get_args();
|
156 |
+
|
157 |
+
// Removes the $tag, since this is not an expected parameter to callbacks.
|
158 |
+
array_shift($args);
|
159 |
+
|
160 |
+
$filtered = $this->callbacks[$tag]->applyFilters($value, $args);
|
161 |
+
|
162 |
+
return $filtered;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Removes a function from a specified filter hook.
|
167 |
+
*
|
168 |
+
* This function removes a specific function attached to a filter hook.
|
169 |
+
* To remove a hook, the $functionToRemove and $priority arguments must match
|
170 |
+
* when the hook was added by calling #addFilter() method.
|
171 |
+
*
|
172 |
+
* @param string $tag The filter hook name where function + priority will be removed from
|
173 |
+
* @param callable $functionToRemove The function/instance->method will be removed.
|
174 |
+
* @param int $priority Optional. The priority of the function to be removed. Default 10.
|
175 |
+
* @return bool True if found function to remove from filter list, false otherwise.
|
176 |
+
*/
|
177 |
+
public function removeFilter($tag, $functionToRemove, $priority = 10)
|
178 |
+
{
|
179 |
+
$return = false;
|
180 |
+
if (isset($this->callbacks[$tag])) {
|
181 |
+
$idx = $this->getUniqueIndexID($tag, $functionToRemove);
|
182 |
+
$return = $this->callbacks[$tag]->removeFilter($idx, $tag, $priority);
|
183 |
+
if (! $this->callbacks[$tag]->callbacks) {
|
184 |
+
unset($this->callbacks[$tag]);
|
185 |
+
}
|
186 |
+
}
|
187 |
+
return $return;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Remove all of the hooks from a filter.
|
192 |
+
*
|
193 |
+
* @param string $tag The filter to remove hooks from.
|
194 |
+
* @param int|bool $priority Optional. The priority number to remove. Default false.
|
195 |
+
*/
|
196 |
+
public function removeAllFilters($tag, $priority = false)
|
197 |
+
{
|
198 |
+
if (isset($this->callbacks[$tag])) {
|
199 |
+
$this->callbacks[$tag]->removeAllFilters($priority);
|
200 |
+
if (!$this->callbacks[$tag]->hasFilters()) {
|
201 |
+
unset($this->callbacks[$tag]);
|
202 |
+
}
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Serialize and generates an index for storage and retrival of method/functions as callbacks.
|
208 |
+
*
|
209 |
+
* This index will be used mostly for instance method callback hooks. Since those cam imply into
|
210 |
+
* having conflicting names.
|
211 |
+
*
|
212 |
+
* <code>
|
213 |
+
* $bar1 = new Bar();
|
214 |
+
* $bar2 = new Bar();
|
215 |
+
*
|
216 |
+
* // Check that the callbacks are registered under same method name, same class,
|
217 |
+
* // same priority, but using different instances.
|
218 |
+
* $observer->addFilter('FILTER_NAME', array($bar1, 'foo'), 10);
|
219 |
+
* $observer->addFilter('FILTER_NAME', array($bar2, 'foo'), 10);
|
220 |
+
* </code>
|
221 |
+
*
|
222 |
+
* @param string $tag Used in counting how many hooks were applied
|
223 |
+
* @param callable $function Used for creating unique id
|
224 |
+
* @param int|bool $priority Used in counting how many hooks were applied. If === false
|
225 |
+
* and $function is an object reference, we return the unique id only if it already has one,
|
226 |
+
* false otherwise.
|
227 |
+
* @return string|false Unique ID for usage as array key or false if $priority === false
|
228 |
+
* and $function is an object reference, and it does not already have a unique id.
|
229 |
+
*/
|
230 |
+
private function getUniqueIndexID($tag, $function)
|
231 |
+
{
|
232 |
+
if (is_string($function)) {
|
233 |
+
return $function;
|
234 |
+
}
|
235 |
+
if ($function instanceof \Closure) {
|
236 |
+
// If a Closure is used, it cannot be retrieved or removed
|
237 |
+
// individually later
|
238 |
+
return 'Closure' . self::$filterCount++;
|
239 |
+
}
|
240 |
+
if (is_object($function)) {
|
241 |
+
$function = array($function, '');
|
242 |
+
} else {
|
243 |
+
$function = (array) $function;
|
244 |
+
}
|
245 |
+
|
246 |
+
if (is_string($function[0])) {
|
247 |
+
// Static call
|
248 |
+
return $function[0] . '::' . $function[1];
|
249 |
+
} elseif (is_object($function[0])) {
|
250 |
+
// Instance call
|
251 |
+
if (function_exists('spl_object_hash')) {
|
252 |
+
return spl_object_hash($function[0]).'->' . $function[1];
|
253 |
+
} else {
|
254 |
+
$obj_idx = get_class($function[0]).'->'.$function[1];
|
255 |
+
if (!isset($function[0]->filterIdx)) {
|
256 |
+
$obj_idx = $obj_idx . self::$filterCount;
|
257 |
+
$function[0]->filterIdx = self::$filterCount;
|
258 |
+
self::$filterCount++;
|
259 |
+
} else {
|
260 |
+
$obj_idx = $obj_idx . $function[0]->filterIdx;
|
261 |
+
}
|
262 |
+
return $obj_idx;
|
263 |
+
}
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Check if any filter has been registered for a hook.
|
269 |
+
*
|
270 |
+
* @param string $tag The name of the filter.
|
271 |
+
* @param callable|bool $functionToCheck Optional. Callable that will be checked.
|
272 |
+
* @return false|int If $functionToCheck is omitted, returns boolean for whether the hook has
|
273 |
+
* anything registered. With a specific function, the priority of that
|
274 |
+
* hook is returned, false otherwise.
|
275 |
+
*/
|
276 |
+
public function hasFilter($tag, $functionToCheck = false)
|
277 |
+
{
|
278 |
+
// If hook name has nothing, then nothing is hooked there.
|
279 |
+
if (!isset($this->callbacks[$tag])) {
|
280 |
+
return false;
|
281 |
+
}
|
282 |
+
$idx = $this->getUniqueIndexID($tag, $functionToCheck);
|
283 |
+
return $this->callbacks[$tag]->hasFilter($idx, $tag, $functionToCheck);
|
284 |
+
}
|
285 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src/Facebook/InstantArticles/Utils/Warning.php
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Validators\Type;
|
12 |
+
|
13 |
+
class Warning
|
14 |
+
{
|
15 |
+
private $exception;
|
16 |
+
private $message;
|
17 |
+
private $context;
|
18 |
+
|
19 |
+
public function __construct($message, $context = null, $exception = null)
|
20 |
+
{
|
21 |
+
$this->message = $message;
|
22 |
+
$this->context = $context;
|
23 |
+
$this->exception = $exception;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function __toString()
|
27 |
+
{
|
28 |
+
$finalMessage = $this->message;
|
29 |
+
|
30 |
+
if ($this->context !== null) {
|
31 |
+
$finalMessage = $finalMessage."\nObject in the context: ".Type::stringify($this->context);
|
32 |
+
}
|
33 |
+
|
34 |
+
if ($this->exception) {
|
35 |
+
$finalMessage = $finalMessage."\nException cause: ".Type::stringify($this->exception);
|
36 |
+
}
|
37 |
+
|
38 |
+
return $finalMessage;
|
39 |
+
}
|
40 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPArticleTest.php
ADDED
@@ -0,0 +1,1092 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Elements\InstantArticle;
|
12 |
+
use Facebook\InstantArticles\Parser\Parser;
|
13 |
+
use Facebook\InstantArticles\Utils\FileUtilsPHPUnitTestCase;
|
14 |
+
|
15 |
+
class AMPArticleTest extends FileUtilsPHPUnitTestCase
|
16 |
+
{
|
17 |
+
public function testParseIA()
|
18 |
+
{
|
19 |
+
$html_file = $this->loadHTMLFile(__DIR__ . '/articles/test1-instant-article.html');
|
20 |
+
$document = $this->loadDOMDocument(__DIR__ . '/articles/test1-instant-article.html');
|
21 |
+
|
22 |
+
$parser = new Parser();
|
23 |
+
$instant_article = $parser->parse($document);
|
24 |
+
$instant_article->addMetaProperty('op:generator:version', '1.0.0');
|
25 |
+
$instant_article->addMetaProperty('op:generator:transformer:version', '1.0.0');
|
26 |
+
$result = $instant_article->render('', true)."\n";
|
27 |
+
|
28 |
+
$this->assertEquals($html_file, $result);
|
29 |
+
}
|
30 |
+
|
31 |
+
public function testTransformIAtoAMPTest1()
|
32 |
+
{
|
33 |
+
$customProperties = array_merge(
|
34 |
+
$this->getWodExpertCustomProperties(),
|
35 |
+
array(
|
36 |
+
'media-sizes' => array(
|
37 |
+
'http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg' => array(
|
38 |
+
800,
|
39 |
+
454,
|
40 |
+
),
|
41 |
+
),
|
42 |
+
)
|
43 |
+
);
|
44 |
+
$this->runIAtoAMPTest('test1', $customProperties);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function testTransformIAtoAMPTest2()
|
48 |
+
{
|
49 |
+
$customProperties = $this->getWodExpertCustomProperties();
|
50 |
+
$this->runIAtoAMPTest('test2', $customProperties);
|
51 |
+
}
|
52 |
+
|
53 |
+
public function testTransformIAtoAMPTest3()
|
54 |
+
{
|
55 |
+
$customProperties = $this->getWodExpertCustomProperties();
|
56 |
+
$this->runIAtoAMPTest('test3', $customProperties);
|
57 |
+
}
|
58 |
+
|
59 |
+
public function testTransformIAtoAMPTest4()
|
60 |
+
{
|
61 |
+
$customProperties = $this->getWodExpertCustomProperties();
|
62 |
+
$this->runIAtoAMPTest('test4', $customProperties);
|
63 |
+
}
|
64 |
+
|
65 |
+
public function testTransformIAtoAMPTest5()
|
66 |
+
{
|
67 |
+
$customProperties = $this->getWodExpertCustomProperties();
|
68 |
+
$this->runIAtoAMPTest('test5', $customProperties);
|
69 |
+
}
|
70 |
+
|
71 |
+
private function getWodExpertCustomProperties()
|
72 |
+
{
|
73 |
+
return array(
|
74 |
+
AMPArticle::PUBLISHER_KEY => array(
|
75 |
+
'@type' => 'Organization',
|
76 |
+
'name' => 'WOD Expert',
|
77 |
+
'logo' => array(
|
78 |
+
'@type' => 'ImageObject',
|
79 |
+
'url' => 'http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png',
|
80 |
+
'width' => 600,
|
81 |
+
'height' => 60,
|
82 |
+
),
|
83 |
+
)
|
84 |
+
);
|
85 |
+
}
|
86 |
+
|
87 |
+
public function testTransformIAtoAMPTestTutorial()
|
88 |
+
{
|
89 |
+
$this->runIAtoAMPTest('tutorial', array('google_maps_key'=>'123'));
|
90 |
+
}
|
91 |
+
|
92 |
+
private function getRenderer($test, $customProperties = null)
|
93 |
+
{
|
94 |
+
$instantArticle = $this->loadInstantArticle(__DIR__ . '/articles/'.$test.'-instant-article.html');
|
95 |
+
|
96 |
+
$properties = array(
|
97 |
+
'lang' => 'en-US',
|
98 |
+
AMPArticle::STYLES_FOLDER_KEY => __DIR__,
|
99 |
+
AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
100 |
+
);
|
101 |
+
if (!is_null($customProperties)) {
|
102 |
+
$properties = array_merge($properties, $customProperties);
|
103 |
+
}
|
104 |
+
|
105 |
+
return AMPArticle::create($instantArticle, $properties);
|
106 |
+
}
|
107 |
+
|
108 |
+
private function getRenderedAMP($test, $customProperties = null)
|
109 |
+
{
|
110 |
+
$renderer = $this->getRenderer($test, $customProperties);
|
111 |
+
|
112 |
+
return $renderer->render(null, true)."\n";
|
113 |
+
}
|
114 |
+
|
115 |
+
private function getMarkupWithoutStyles($markup)
|
116 |
+
{
|
117 |
+
libxml_use_internal_errors(true);
|
118 |
+
$markupDocument = new \DOMDocument();
|
119 |
+
$markupDocument->loadHTML($markup);
|
120 |
+
libxml_use_internal_errors(false);
|
121 |
+
|
122 |
+
$xPath = new \DOMXPath($markupDocument);
|
123 |
+
if ($customStyle = $xPath->query('//style[@amp-custom]')->item(0)) {
|
124 |
+
$customStyle->parentNode->removeChild($customStyle);
|
125 |
+
}
|
126 |
+
return $markupDocument->saveHTML();
|
127 |
+
}
|
128 |
+
|
129 |
+
private function compareIgnoringStyles($ampExpected, $ampRendered)
|
130 |
+
{
|
131 |
+
$ampExpectedNoStyles = $this->getMarkupWithoutStyles($ampExpected);
|
132 |
+
$ampRenderedNoStyles = $this->getMarkupWithoutStyles($ampRendered);
|
133 |
+
|
134 |
+
$this->assertEquals($ampExpectedNoStyles, $ampRenderedNoStyles);
|
135 |
+
}
|
136 |
+
|
137 |
+
public function runIAtoAMPTest($test, $customProperties = null)
|
138 |
+
{
|
139 |
+
$ampRendered = $this->getRenderedAMP($test, $customProperties);
|
140 |
+
|
141 |
+
$ampExpected = $this->loadHTMLFile(__DIR__.'/articles/'.$test.'-amp-converted.html');
|
142 |
+
$this->compareIgnoringStyles($ampExpected, $ampRendered);
|
143 |
+
|
144 |
+
// Sets content into the file for double checking testing
|
145 |
+
// file_put_contents(__DIR__.'/articles/'.$test.'-amp-converted.html', $ampRendered);
|
146 |
+
}
|
147 |
+
|
148 |
+
private function getRenderedMarkupXPathQuery($test, $xPathExpression, $customProperties = null)
|
149 |
+
{
|
150 |
+
$amp_rendered = $this->getRenderedAMP($test, $customProperties);
|
151 |
+
|
152 |
+
$renderedDocument = $this->loadDOMDocumentFromString($amp_rendered);
|
153 |
+
$xPath = new \DOMXPath($renderedDocument);
|
154 |
+
|
155 |
+
return $xPath->query($xPathExpression);
|
156 |
+
}
|
157 |
+
|
158 |
+
public function testArticleHasSingleLdJsonScript()
|
159 |
+
{
|
160 |
+
$xPathQuery = $this->getRenderedMarkupXPathQuery('test1', '//script[@type="application/ld+json"]');
|
161 |
+
$this->assertEquals(1, $xPathQuery->length);
|
162 |
+
}
|
163 |
+
|
164 |
+
private function getDiscoveryMetadata($test, $customProperties = null)
|
165 |
+
{
|
166 |
+
$renderer = $this->getRenderer($test, $customProperties);
|
167 |
+
$context = AMPContext::create(new \DOMDocument(), $renderer->getInstantArticle(), 'ia2amp-');
|
168 |
+
|
169 |
+
$discoveryMetadataContent = $renderer->buildSchemaOrgMetadata($context);
|
170 |
+
return json_decode($discoveryMetadataContent, true);
|
171 |
+
}
|
172 |
+
|
173 |
+
private function verifySchemaOrgHasExpectedValue($key, $expectedValue, $test = 'test1', $customProperties = null)
|
174 |
+
{
|
175 |
+
$discoveryMetadata = $this->getDiscoveryMetadata($test, $customProperties);
|
176 |
+
|
177 |
+
$this->assertArrayHasKey($key, $discoveryMetadata, "Could not find $key key in Schema.org metadata");
|
178 |
+
$this->assertEquals($expectedValue, $discoveryMetadata[$key], "Unexpected value found for $key");
|
179 |
+
}
|
180 |
+
|
181 |
+
private function verifySchemaOrgDoesNotHaveKey($key, $test = 'test1')
|
182 |
+
{
|
183 |
+
$discoveryMetadata = $this->getDiscoveryMetadata($test);
|
184 |
+
|
185 |
+
$this->assertFalse(array_key_exists($key, $discoveryMetadata), "Found unexpected '$key' key in Schema.org metadata");
|
186 |
+
}
|
187 |
+
|
188 |
+
public function testSchemaOrgContext()
|
189 |
+
{
|
190 |
+
$this->verifySchemaOrgHasExpectedValue('@context', 'http://schema.org');
|
191 |
+
}
|
192 |
+
|
193 |
+
public function testSchemaOrgType()
|
194 |
+
{
|
195 |
+
$this->verifySchemaOrgHasExpectedValue('@type', 'NewsArticle');
|
196 |
+
}
|
197 |
+
|
198 |
+
public function testSchemaOrgMainEntityOfPage()
|
199 |
+
{
|
200 |
+
$this->verifySchemaOrgHasExpectedValue('mainEntityOfPage', 'http://blog.wod.expert/very-first-wod/');
|
201 |
+
}
|
202 |
+
|
203 |
+
public function testSchemaOrgHeadline()
|
204 |
+
{
|
205 |
+
$this->verifySchemaOrgHasExpectedValue('headline', 'Very First WOD!');
|
206 |
+
}
|
207 |
+
|
208 |
+
public function testSchemaOrgDatePublished()
|
209 |
+
{
|
210 |
+
$this->verifySchemaOrgHasExpectedValue('datePublished', '2016-05-10T18:05:36+00:00');
|
211 |
+
}
|
212 |
+
|
213 |
+
public function testSchemaOrgDateModified()
|
214 |
+
{
|
215 |
+
$this->verifySchemaOrgHasExpectedValue('dateModified', '2017-03-17T16:46:07+00:00');
|
216 |
+
}
|
217 |
+
|
218 |
+
public function testSchemaOrgHasDateModified()
|
219 |
+
{
|
220 |
+
$key = 'dateModified';
|
221 |
+
$discoveryMetadata = $this->getDiscoveryMetadata('tutorial');
|
222 |
+
$this->assertTrue(array_key_exists($key, $discoveryMetadata), "Did not found expected '$key' key in Schema.org metadata");
|
223 |
+
}
|
224 |
+
|
225 |
+
public function testSchemaOrgAuthor()
|
226 |
+
{
|
227 |
+
$expectedAuthor = array(
|
228 |
+
'@type' => 'Person',
|
229 |
+
'name' => 'Éverton Rosário',
|
230 |
+
);
|
231 |
+
|
232 |
+
$this->verifySchemaOrgHasExpectedValue('author', $expectedAuthor);
|
233 |
+
}
|
234 |
+
|
235 |
+
public function testSchemaOrgImageNoCache()
|
236 |
+
{
|
237 |
+
$expectedImage = array(
|
238 |
+
'@type' => 'ImageObject',
|
239 |
+
'url' => 'http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg',
|
240 |
+
'width' => 380,
|
241 |
+
'height' => 240,
|
242 |
+
);
|
243 |
+
|
244 |
+
$this->verifySchemaOrgHasExpectedValue('image', $expectedImage);
|
245 |
+
}
|
246 |
+
|
247 |
+
public function testSchemaOrgImageWithCache()
|
248 |
+
{
|
249 |
+
$expectedImage = array(
|
250 |
+
'@type' => 'ImageObject',
|
251 |
+
'url' => 'http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg',
|
252 |
+
'width' => 400,
|
253 |
+
'height' => 227,
|
254 |
+
);
|
255 |
+
$customProperties = array(
|
256 |
+
AMPArticle::MEDIA_CACHE_FOLDER_KEY => __DIR__ . '/articles/media-cache',
|
257 |
+
);
|
258 |
+
|
259 |
+
$this->verifySchemaOrgHasExpectedValue('image', $expectedImage, 'test1', $customProperties);
|
260 |
+
}
|
261 |
+
|
262 |
+
public function testSchemaOrgDescription()
|
263 |
+
{
|
264 |
+
$this->verifySchemaOrgHasExpectedValue('description', 'The first WOD we never forget! Just to be sure we are talking about same thing, WOD stands for “Workout of the Day”. You feel you’re already gone on the warm up session.');
|
265 |
+
}
|
266 |
+
|
267 |
+
public function testSchemaOrgPublisherName()
|
268 |
+
{
|
269 |
+
$publisherName = 'The Publisher';
|
270 |
+
$customProperties = array(AMPArticle::PUBLISHER_KEY => $publisherName);
|
271 |
+
|
272 |
+
$expectedPublisher = array(
|
273 |
+
'@type' => 'Organization',
|
274 |
+
'name' => $publisherName,
|
275 |
+
);
|
276 |
+
|
277 |
+
$this->verifySchemaOrgHasExpectedValue('publisher', $expectedPublisher, 'test1', $customProperties);
|
278 |
+
}
|
279 |
+
|
280 |
+
public function testSchemaOrgPublisherArray()
|
281 |
+
{
|
282 |
+
$publisher = array(
|
283 |
+
'@type' => 'Robot',
|
284 |
+
'name' => 'The Robot',
|
285 |
+
);
|
286 |
+
$customProperties = array(AMPArticle::PUBLISHER_KEY => $publisher);
|
287 |
+
|
288 |
+
$this->verifySchemaOrgHasExpectedValue('publisher', $publisher, 'test1', $customProperties);
|
289 |
+
}
|
290 |
+
|
291 |
+
public function testSchemaOrgNoPublisher()
|
292 |
+
{
|
293 |
+
$this->verifySchemaOrgDoesNotHaveKey('publisher');
|
294 |
+
}
|
295 |
+
|
296 |
+
private function getRenderedLogoElement($test = 'test1')
|
297 |
+
{
|
298 |
+
$xPathQuery = $this->getRenderedMarkupXPathQuery(
|
299 |
+
$test,
|
300 |
+
'//div[@class=\'ia2amp-header-bar-img-container\']/amp-img'
|
301 |
+
);
|
302 |
+
|
303 |
+
return $xPathQuery->item(0);
|
304 |
+
}
|
305 |
+
|
306 |
+
public function testLogoURL()
|
307 |
+
{
|
308 |
+
$logoElement = $this->getRenderedLogoElement();
|
309 |
+
$this->assertNotNull($logoElement);
|
310 |
+
$src = $logoElement->getAttribute('src');
|
311 |
+
|
312 |
+
$this->assertEquals(
|
313 |
+
'https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8',
|
314 |
+
$src
|
315 |
+
);
|
316 |
+
}
|
317 |
+
|
318 |
+
public function testLogoWidth()
|
319 |
+
{
|
320 |
+
$logoElement = $this->getRenderedLogoElement();
|
321 |
+
$this->assertNotNull($logoElement);
|
322 |
+
$width = $logoElement->getAttribute('width');
|
323 |
+
|
324 |
+
$this->assertEquals(223, $width);
|
325 |
+
}
|
326 |
+
|
327 |
+
public function testLogoHeight()
|
328 |
+
{
|
329 |
+
$logoElement = $this->getRenderedLogoElement();
|
330 |
+
$this->assertNotNull($logoElement);
|
331 |
+
$height = $logoElement->getAttribute('height');
|
332 |
+
|
333 |
+
$this->assertEquals(44, $height);
|
334 |
+
}
|
335 |
+
|
336 |
+
public function testCachedImageHeight()
|
337 |
+
{
|
338 |
+
$expectedHeight = 181;
|
339 |
+
$customProperties = array(
|
340 |
+
AMPArticle::MEDIA_CACHE_FOLDER_KEY => __DIR__ . '/articles/media-cache',
|
341 |
+
);
|
342 |
+
|
343 |
+
$coverImageXPathQuery = $this->getRenderedMarkupXPathQuery(
|
344 |
+
'test2',
|
345 |
+
'//article//amp-img',
|
346 |
+
$customProperties
|
347 |
+
);
|
348 |
+
$coverImageElement = $coverImageXPathQuery->item(0);
|
349 |
+
|
350 |
+
$this->assertEquals($expectedHeight, $coverImageElement->getAttribute('height'));
|
351 |
+
}
|
352 |
+
|
353 |
+
public function testImageHeightDownloadDisabled()
|
354 |
+
{
|
355 |
+
$expectedHeight = 240;
|
356 |
+
$customProperties = array(
|
357 |
+
AMPArticle::MEDIA_CACHE_FOLDER_KEY => __DIR__ . '/articles/media-cache',
|
358 |
+
AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
359 |
+
);
|
360 |
+
|
361 |
+
$imageXPathQuery = $this->getRenderedMarkupXPathQuery(
|
362 |
+
'test1',
|
363 |
+
'//div[@class=\'ia2amp-slideshow-image\']//amp-img',
|
364 |
+
$customProperties
|
365 |
+
);
|
366 |
+
$firstArticleImageElement = $imageXPathQuery->item(0);
|
367 |
+
|
368 |
+
$this->assertEquals($expectedHeight, $firstArticleImageElement->getAttribute('height'));
|
369 |
+
}
|
370 |
+
|
371 |
+
public function testImageHeightDefaultProperty()
|
372 |
+
{
|
373 |
+
$expectedHeight = 120;
|
374 |
+
$customProperties = array(
|
375 |
+
AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
376 |
+
AMPArticle::DEFAULT_MEDIA_HEIGHT_KEY => $expectedHeight,
|
377 |
+
);
|
378 |
+
|
379 |
+
$imageXPathQuery = $this->getRenderedMarkupXPathQuery(
|
380 |
+
'test1',
|
381 |
+
'//div[@class=\'ia2amp-slideshow-image\']//amp-img',
|
382 |
+
$customProperties
|
383 |
+
);
|
384 |
+
$firstArticleImageElement = $imageXPathQuery->item(0);
|
385 |
+
|
386 |
+
$this->assertEquals($expectedHeight, $firstArticleImageElement->getAttribute('height'));
|
387 |
+
}
|
388 |
+
|
389 |
+
public function testImageHeightFromMediaSizes()
|
390 |
+
{
|
391 |
+
$expectedHeight = 253;
|
392 |
+
$customProperties = array(
|
393 |
+
AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
394 |
+
AMPArticle::MEDIA_SIZES_KEY => array(
|
395 |
+
"http://blog.wod.expert/wp-content/uploads/2017/03/fail2.jpg" => array(90, 60),
|
396 |
+
),
|
397 |
+
);
|
398 |
+
|
399 |
+
$imageXPathQuery = $this->getRenderedMarkupXPathQuery(
|
400 |
+
'test1',
|
401 |
+
'//div[@class=\'ia2amp-slideshow-image\']//amp-img',
|
402 |
+
$customProperties
|
403 |
+
);
|
404 |
+
$firstArticleImageElement = $imageXPathQuery->item(0);
|
405 |
+
|
406 |
+
$this->assertEquals($expectedHeight, $firstArticleImageElement->getAttribute('height'));
|
407 |
+
}
|
408 |
+
|
409 |
+
public function testVideoHeightDefaultProperty()
|
410 |
+
{
|
411 |
+
$expectedHeight = 120;
|
412 |
+
$customProperties = array(
|
413 |
+
AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
414 |
+
AMPArticle::DEFAULT_MEDIA_HEIGHT_KEY => $expectedHeight,
|
415 |
+
);
|
416 |
+
|
417 |
+
$videoXPathQuery = $this->getRenderedMarkupXPathQuery(
|
418 |
+
'tutorial',
|
419 |
+
'//amp-video',
|
420 |
+
$customProperties
|
421 |
+
);
|
422 |
+
$firstArticleVideoElement = $videoXPathQuery->item(0);
|
423 |
+
|
424 |
+
$this->assertEquals($expectedHeight, $firstArticleVideoElement->getAttribute('height'));
|
425 |
+
}
|
426 |
+
|
427 |
+
public function testVideoWidthFromMediaSizes()
|
428 |
+
{
|
429 |
+
$expectedWidth = 380;
|
430 |
+
$videoXPathQuery = $this->getRenderedMarkupXPathQuery(
|
431 |
+
'tutorial',
|
432 |
+
'//amp-video',
|
433 |
+
null
|
434 |
+
);
|
435 |
+
$firstArticleVideoElement = $videoXPathQuery->item(0);
|
436 |
+
|
437 |
+
$this->assertEquals($expectedWidth, $firstArticleVideoElement->getAttribute('width'));
|
438 |
+
}
|
439 |
+
|
440 |
+
public function testVideoHeightFromMediaSizes()
|
441 |
+
{
|
442 |
+
$expectedHeight = 240;
|
443 |
+
$videoXPathQuery = $this->getRenderedMarkupXPathQuery(
|
444 |
+
'tutorial',
|
445 |
+
'//amp-video',
|
446 |
+
null
|
447 |
+
);
|
448 |
+
$firstArticleVideoElement = $videoXPathQuery->item(0);
|
449 |
+
|
450 |
+
$this->assertEquals($expectedHeight, $firstArticleVideoElement->getAttribute('height'));
|
451 |
+
}
|
452 |
+
|
453 |
+
public function testFooterCredits()
|
454 |
+
{
|
455 |
+
$creditsXPathQuery = $this->getRenderedMarkupXPathQuery(
|
456 |
+
'test1',
|
457 |
+
'//article/footer/aside'
|
458 |
+
);
|
459 |
+
|
460 |
+
$creditsElement = $creditsXPathQuery->item(0);
|
461 |
+
|
462 |
+
$this->assertEquals('WOD Expert', trim($creditsElement->textContent));
|
463 |
+
}
|
464 |
+
|
465 |
+
public function testFooterCopyright()
|
466 |
+
{
|
467 |
+
$copyrightXPathQuery = $this->getRenderedMarkupXPathQuery(
|
468 |
+
'test1',
|
469 |
+
'//article/footer/small'
|
470 |
+
);
|
471 |
+
|
472 |
+
$copyrightElement = $copyrightXPathQuery->item(0);
|
473 |
+
|
474 |
+
$this->assertEquals('© 2017 WOD Expert', trim($copyrightElement->textContent));
|
475 |
+
}
|
476 |
+
|
477 |
+
public function testCoverImageWidth()
|
478 |
+
{
|
479 |
+
$expectedWidth = 422;
|
480 |
+
$coverImageXPathQuery = $this->getRenderedMarkupXPathQuery(
|
481 |
+
'test1',
|
482 |
+
'//amp-img[@class=\'ia2amp-header-cover-img\']',
|
483 |
+
array(
|
484 |
+
'media-sizes' => array(
|
485 |
+
'http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg' => array(
|
486 |
+
800,
|
487 |
+
454,
|
488 |
+
),
|
489 |
+
),
|
490 |
+
)
|
491 |
+
);
|
492 |
+
|
493 |
+
$coverImageElement = $coverImageXPathQuery->item(0);
|
494 |
+
|
495 |
+
$this->assertEquals($expectedWidth, $coverImageElement->getAttribute('width'));
|
496 |
+
}
|
497 |
+
|
498 |
+
public function testCoverImageHeight()
|
499 |
+
{
|
500 |
+
$expectedHeight = 240;
|
501 |
+
$coverImageXPathQuery = $this->getRenderedMarkupXPathQuery(
|
502 |
+
'test1',
|
503 |
+
'//amp-img[@class=\'ia2amp-header-cover-img\']',
|
504 |
+
array(
|
505 |
+
'media-sizes' => array(
|
506 |
+
'http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg' => array(
|
507 |
+
800,
|
508 |
+
454,
|
509 |
+
),
|
510 |
+
),
|
511 |
+
)
|
512 |
+
);
|
513 |
+
|
514 |
+
$coverImageElement = $coverImageXPathQuery->item(0);
|
515 |
+
|
516 |
+
$this->assertEquals($expectedHeight, $coverImageElement->getAttribute('height'));
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* @dataProvider testToRGBDataProvider
|
521 |
+
*/
|
522 |
+
public function testToRG($hexColor, $expected)
|
523 |
+
{
|
524 |
+
$rgb = AMPArticle::toRGB($hexColor);
|
525 |
+
$this->assertEquals($expected, $rgb);
|
526 |
+
}
|
527 |
+
|
528 |
+
public function testToRGBDataProvider()
|
529 |
+
{
|
530 |
+
return array(
|
531 |
+
array('FFAABB', 'rgb(255,170,187)'),
|
532 |
+
array('#FFAABB', 'rgb(255,170,187)'),
|
533 |
+
array('#FFFFAABB', 'rgb(255,170,187)'),
|
534 |
+
array('EEFFAABB', 'rgba(255,170,187,0.93)'),
|
535 |
+
array('#EEFFAABB', 'rgba(255,170,187,0.93)'),
|
536 |
+
array('#00FFFFFF', 'rgba(255,255,255,0)'),
|
537 |
+
);
|
538 |
+
}
|
539 |
+
|
540 |
+
private function getDefaultStyles()
|
541 |
+
{
|
542 |
+
$jsonStyles = file_get_contents(__DIR__ . '/default.style.json');
|
543 |
+
return json_decode($jsonStyles, true);
|
544 |
+
}
|
545 |
+
|
546 |
+
public function testBackgroundColorStyle()
|
547 |
+
{
|
548 |
+
$hexColor = AMPArticleTest::getRandomHexColor();
|
549 |
+
|
550 |
+
$defaultStyles = $this->getDefaultStyles();
|
551 |
+
$defaultStyles['background_color'] = $hexColor;
|
552 |
+
|
553 |
+
$customProperties = array(
|
554 |
+
AMPArticle::OVERRIDE_STYLES_KEY => $defaultStyles,
|
555 |
+
);
|
556 |
+
|
557 |
+
$renderer = $this->getRenderer('test1', $customProperties);
|
558 |
+
$context = AMPContext::create(new \DOMDocument(), $renderer->getInstantArticle(), 'ia2amp-');
|
559 |
+
$css = $renderer->getCustomCSS($context);
|
560 |
+
|
561 |
+
// Escape parenthesis before using regex
|
562 |
+
$expectedValue = str_replace(')', '\)', str_replace('(', '\(', AMPArticle::toRGB($hexColor)));
|
563 |
+
$this->validateCSSRule($css, 'html', 'background-color', $expectedValue);
|
564 |
+
}
|
565 |
+
|
566 |
+
public function textStylesDataProvider()
|
567 |
+
{
|
568 |
+
return array_merge(
|
569 |
+
// Head
|
570 |
+
$this->getTextStylesTestData('kicker', '.ia2amp-header-category'),
|
571 |
+
$this->getTextStylesTestData('title', '.ia2amp-header-h1'),
|
572 |
+
$this->getTextStylesTestData('subtitle', '.ia2amp-header-h2'),
|
573 |
+
$this->getTextStylesTestData('byline', '.ia2amp-header h3'),
|
574 |
+
// Body
|
575 |
+
$this->getTextStylesTestData('primary_heading', '.ia2amp-h1'),
|
576 |
+
$this->getTextStylesTestData('secondary_heading', '.ia2amp-h2'),
|
577 |
+
$this->getTextStylesTestData('body_text', '.ia2amp-p'),
|
578 |
+
$this->getTextStylesTestData('inline_link', '.ia2amp-article a'),
|
579 |
+
// Quotes
|
580 |
+
$this->getTextStylesTestData('block_quote', '.ia2amp-blockquote'),
|
581 |
+
$this->getTextStylesTestData('pull_quote', '.ia2amp-pullquote'),
|
582 |
+
$this->getTextStylesTestData('pull_quote_attribution', '.ia2amp-pullquote cite'),
|
583 |
+
// Captions
|
584 |
+
$this->getTextStylesTestData('caption_title_small', '.ia2amp-op-small h1'),
|
585 |
+
$this->getTextStylesTestData('caption_description_small', '.ia2amp-op-small h2'),
|
586 |
+
$this->getTextStylesTestData('caption_title', '.ia2amp-op-medium h1'),
|
587 |
+
$this->getTextStylesTestData('caption_description', '.ia2amp-op-medium h2'),
|
588 |
+
$this->getTextStylesTestData('caption_title_large', '.ia2amp-op-large h1'),
|
589 |
+
$this->getTextStylesTestData('caption_description_large', '.ia2amp-op-large h2'),
|
590 |
+
$this->getTextStylesTestData('caption_title_extra_large', '.ia2amp-op-extra-large h1'),
|
591 |
+
$this->getTextStylesTestData('caption_description_extra_large', '.ia2amp-op-extra-large h2'),
|
592 |
+
$this->getTextStylesTestData('caption_credit', '.ia2amp-figcaption cite'),
|
593 |
+
// Footer
|
594 |
+
$this->getTextStylesTestData('footer', '.ia2amp-footer')
|
595 |
+
);
|
596 |
+
}
|
597 |
+
|
598 |
+
/**
|
599 |
+
* @dataProvider textStylesDataProvider
|
600 |
+
*/
|
601 |
+
public function testTextStyles($styleName, $secondLevelProperty, $cssSelector, $cssProperty, $styleValue, $expectedCSSValue)
|
602 |
+
{
|
603 |
+
$this->validateSecondLevelProperty($styleName, $secondLevelProperty, $cssSelector, $cssProperty, $styleValue, $expectedCSSValue);
|
604 |
+
}
|
605 |
+
|
606 |
+
/**
|
607 |
+
* @dataProvider testTextStylesDataProvider
|
608 |
+
*/
|
609 |
+
private function getTextStylesTestData($styleName, $cssSelector)
|
610 |
+
{
|
611 |
+
$testData = array();
|
612 |
+
|
613 |
+
// Font Family
|
614 |
+
$testData = array_merge(
|
615 |
+
$testData,
|
616 |
+
$this->getSecondLevelPropertyTestData(
|
617 |
+
'randomDataProvider',
|
618 |
+
'passThroughValuesProvider',
|
619 |
+
$styleName,
|
620 |
+
'font',
|
621 |
+
$cssSelector,
|
622 |
+
'font-family'
|
623 |
+
)
|
624 |
+
);
|
625 |
+
|
626 |
+
// Color
|
627 |
+
$testData = array_merge(
|
628 |
+
$testData,
|
629 |
+
$this->getSecondLevelPropertyTestData(
|
630 |
+
'colorDataProvider',
|
631 |
+
'passThroughValuesProvider',
|
632 |
+
$styleName,
|
633 |
+
'color',
|
634 |
+
$cssSelector,
|
635 |
+
'color'
|
636 |
+
)
|
637 |
+
);
|
638 |
+
|
639 |
+
// Background Color
|
640 |
+
$testData = array_merge(
|
641 |
+
$testData,
|
642 |
+
$this->getSecondLevelPropertyTestData(
|
643 |
+
'colorDataProvider',
|
644 |
+
'passThroughValuesProvider',
|
645 |
+
$styleName,
|
646 |
+
'background_color',
|
647 |
+
$cssSelector,
|
648 |
+
'background-color'
|
649 |
+
)
|
650 |
+
);
|
651 |
+
|
652 |
+
// Text Transform
|
653 |
+
$testData = array_merge(
|
654 |
+
$testData,
|
655 |
+
$this->getSecondLevelPropertyTestData(
|
656 |
+
'textTransformDataProvider',
|
657 |
+
'passThroughValuesProvider',
|
658 |
+
$styleName,
|
659 |
+
'capitalization',
|
660 |
+
$cssSelector,
|
661 |
+
'text-transform'
|
662 |
+
)
|
663 |
+
);
|
664 |
+
|
665 |
+
// Text Alignment
|
666 |
+
$testData = array_merge(
|
667 |
+
$testData,
|
668 |
+
$this->getSecondLevelPropertyTestData(
|
669 |
+
'textAlignmentDataProvider',
|
670 |
+
'passThroughValuesProvider',
|
671 |
+
$styleName,
|
672 |
+
'text_alignment',
|
673 |
+
$cssSelector,
|
674 |
+
'text-align'
|
675 |
+
)
|
676 |
+
);
|
677 |
+
|
678 |
+
// Display
|
679 |
+
$testData = array_merge(
|
680 |
+
$testData,
|
681 |
+
$this->getSecondLevelPropertyTestData(
|
682 |
+
'displayDataProvider',
|
683 |
+
'passThroughValuesProvider',
|
684 |
+
$styleName,
|
685 |
+
'display',
|
686 |
+
$cssSelector,
|
687 |
+
'display'
|
688 |
+
)
|
689 |
+
);
|
690 |
+
|
691 |
+
// Margin
|
692 |
+
$testData = array_merge(
|
693 |
+
$testData,
|
694 |
+
$this->getSecondLevelPropertyTestData(
|
695 |
+
'marginDataProvider',
|
696 |
+
'spacingValuesProvider',
|
697 |
+
$styleName,
|
698 |
+
'margin',
|
699 |
+
$cssSelector,
|
700 |
+
'margin'
|
701 |
+
)
|
702 |
+
);
|
703 |
+
|
704 |
+
// Padding
|
705 |
+
$testData = array_merge(
|
706 |
+
$testData,
|
707 |
+
$this->getSecondLevelPropertyTestData(
|
708 |
+
'paddingDataProvider',
|
709 |
+
'spacingValuesProvider',
|
710 |
+
$styleName,
|
711 |
+
'padding',
|
712 |
+
$cssSelector,
|
713 |
+
'padding'
|
714 |
+
)
|
715 |
+
);
|
716 |
+
|
717 |
+
// Border Width
|
718 |
+
$testData = array_merge(
|
719 |
+
$testData,
|
720 |
+
$this->getSecondLevelPropertyTestData(
|
721 |
+
'borderWidthDataProvider',
|
722 |
+
'borderWidthValuesProvider',
|
723 |
+
$styleName,
|
724 |
+
'border',
|
725 |
+
$cssSelector,
|
726 |
+
'border-width'
|
727 |
+
)
|
728 |
+
);
|
729 |
+
|
730 |
+
return $testData;
|
731 |
+
}
|
732 |
+
|
733 |
+
/**
|
734 |
+
* Builds the arguments that will be pased to function validateSecondLevelProperty
|
735 |
+
*
|
736 |
+
* @param string $dataProviderFunctionName The name of the parameterless function that serves as Data Provider
|
737 |
+
* @param string $validationArgumentsProviderFunctionName The name of the function that receives the Data Provider rows and converts them to pairs of style
|
738 |
+
* @param string $styleName The style name that will be used for validateSecondLevelProperty
|
739 |
+
* @param object $secondLevelProperty The name of the property that will be transformed in the styles for the unit test
|
740 |
+
* @param string $cssSelector The CSS selector that will be used to verify the unit test result
|
741 |
+
* @param string $cssProperty The CSS property that will be used to verify the unit test result
|
742 |
+
* @return array An array with the style value that will be set, and the expected CSS value that will be generated
|
743 |
+
*/
|
744 |
+
private function getSecondLevelPropertyTestData(
|
745 |
+
$dataProviderFunctionName,
|
746 |
+
$validationArgumentsProviderFunctionName,
|
747 |
+
$styleName,
|
748 |
+
$secondLevelProperty,
|
749 |
+
$cssSelector,
|
750 |
+
$cssProperty
|
751 |
+
) {
|
752 |
+
|
753 |
+
$testData = array();
|
754 |
+
|
755 |
+
// Get all test cases for the given Data Provider function
|
756 |
+
$dataProviderTestData = call_user_func_array(array($this, $dataProviderFunctionName), array());
|
757 |
+
|
758 |
+
foreach ($dataProviderTestData as $dataProviderTestItem) {
|
759 |
+
// Call the Validation Arguments Provider function using the values from the Data Provider
|
760 |
+
$styleAndCssValues = call_user_func_array(array($this, $validationArgumentsProviderFunctionName), $dataProviderTestItem);
|
761 |
+
// Merge the known values with the mappings of style value to expected CSS value
|
762 |
+
$testDataItem = array_merge(
|
763 |
+
array(
|
764 |
+
$styleName,
|
765 |
+
$secondLevelProperty,
|
766 |
+
$cssSelector,
|
767 |
+
$cssProperty,
|
768 |
+
),
|
769 |
+
$styleAndCssValues
|
770 |
+
);
|
771 |
+
// Add the merged values to the list of test items
|
772 |
+
$testData[] = $testDataItem;
|
773 |
+
}
|
774 |
+
|
775 |
+
return $testData;
|
776 |
+
}
|
777 |
+
|
778 |
+
/**
|
779 |
+
* Takes an Instant Article style property name and an expected value and returns both in an array
|
780 |
+
*
|
781 |
+
* @param string $stylePropertyName
|
782 |
+
* @param string $expectedCSSValue
|
783 |
+
* @return array
|
784 |
+
*/
|
785 |
+
private function passThroughValuesProvider($stylePropertyName, $expectedCSSValue)
|
786 |
+
{
|
787 |
+
return array($stylePropertyName, $expectedCSSValue);
|
788 |
+
}
|
789 |
+
|
790 |
+
/**
|
791 |
+
* Generates random values for function passThroughValuesProvider
|
792 |
+
*
|
793 |
+
* @return array
|
794 |
+
*/
|
795 |
+
private function randomDataProvider()
|
796 |
+
{
|
797 |
+
$randomValue = rand();
|
798 |
+
return array(
|
799 |
+
array($randomValue, $randomValue),
|
800 |
+
);
|
801 |
+
}
|
802 |
+
|
803 |
+
/**
|
804 |
+
* Generates color values for function passThroughValuesProvider
|
805 |
+
*
|
806 |
+
* @return array
|
807 |
+
*/
|
808 |
+
private function colorDataProvider()
|
809 |
+
{
|
810 |
+
$hexColor = AMPArticleTest::getRandomHexColor();
|
811 |
+
// Escape parenthesis before using regex
|
812 |
+
$expectedValue = str_replace(')', '\)', str_replace('(', '\(', AMPArticle::toRGB($hexColor)));
|
813 |
+
return array(
|
814 |
+
array($hexColor, $expectedValue),
|
815 |
+
);
|
816 |
+
}
|
817 |
+
|
818 |
+
/**
|
819 |
+
* Generates text transform values for function passThroughValuesProvider
|
820 |
+
*
|
821 |
+
* @return array
|
822 |
+
*/
|
823 |
+
private function textTransformDataProvider()
|
824 |
+
{
|
825 |
+
return array(
|
826 |
+
array('ALL_CAPS', 'uppercase'),
|
827 |
+
array('NONE', 'none'),
|
828 |
+
array('ALL_LOWER_CASE', 'lowercase'),
|
829 |
+
);
|
830 |
+
}
|
831 |
+
|
832 |
+
/**
|
833 |
+
* Generates text alignment values for function passThroughValuesProvider
|
834 |
+
*
|
835 |
+
* @return array
|
836 |
+
*/
|
837 |
+
public function textAlignmentDataProvider()
|
838 |
+
{
|
839 |
+
return array(
|
840 |
+
array('LEFT', 'LEFT'),
|
841 |
+
array('CENTER', 'CENTER'),
|
842 |
+
array('RIGHT', 'RIGHT'),
|
843 |
+
);
|
844 |
+
}
|
845 |
+
|
846 |
+
/**
|
847 |
+
* Generates display values for function passThroughValuesProvider
|
848 |
+
*
|
849 |
+
* @return array
|
850 |
+
*/
|
851 |
+
public function displayDataProvider()
|
852 |
+
{
|
853 |
+
return array(
|
854 |
+
array('INLINE', 'INLINE'),
|
855 |
+
array('BLOCK', 'BLOCK'),
|
856 |
+
);
|
857 |
+
}
|
858 |
+
|
859 |
+
/**
|
860 |
+
* Generates spacing (margin or padding) Instant Article style values and expected CSS values
|
861 |
+
*
|
862 |
+
* @param int $size The Instant Article style size value
|
863 |
+
* @param int $baseSpacingValue The value that will be multiplied by the scaling factor
|
864 |
+
* @param string $direction A valid direction for a border style e.g. 'top'
|
865 |
+
* @param string $spacingFormat The expected spacing format e.g. '0 0 0 %spx'
|
866 |
+
* @return array
|
867 |
+
*/
|
868 |
+
public function spacingValuesProvider($size, $baseSpacingValue, $direction, $spacingFormat)
|
869 |
+
{
|
870 |
+
$scalingFactor = rand(0, 1000) / 1000 + 0.5;
|
871 |
+
$directionSpacing = array(
|
872 |
+
'scaling_factor' => $scalingFactor,
|
873 |
+
'size' => $size,
|
874 |
+
);
|
875 |
+
$spacingStyle = array(
|
876 |
+
$direction => $directionSpacing,
|
877 |
+
);
|
878 |
+
|
879 |
+
$expectedSpacing = $baseSpacingValue * $scalingFactor;
|
880 |
+
$expectedValue = sprintf($spacingFormat, $expectedSpacing);
|
881 |
+
|
882 |
+
return array($spacingStyle, $expectedValue);
|
883 |
+
}
|
884 |
+
|
885 |
+
/**
|
886 |
+
* Generates margin values for function spacingValuesProvider
|
887 |
+
*
|
888 |
+
* @return array
|
889 |
+
*/
|
890 |
+
private function marginDataProvider()
|
891 |
+
{
|
892 |
+
return array(
|
893 |
+
// size, baseSpacingValue, direction, spacingFormat
|
894 |
+
array('DOCUMENT_MARGIN', AMPArticle::DEFAULT_MARGIN, 'right', '0 %spx 0 0'),
|
895 |
+
array('DOCUMENT_MARGIN', AMPArticle::DEFAULT_MARGIN, 'left', '0 0 0 %spx'),
|
896 |
+
|
897 |
+
array('NONE', 0, 'right', '0 0 0 0'),
|
898 |
+
array('NONE', 0, 'left', '0 0 0 0'),
|
899 |
+
);
|
900 |
+
}
|
901 |
+
|
902 |
+
/**
|
903 |
+
* Generates padding values for function spacingValuesProvider
|
904 |
+
*
|
905 |
+
* @return array
|
906 |
+
*/
|
907 |
+
private function paddingDataProvider()
|
908 |
+
{
|
909 |
+
return array(
|
910 |
+
// size, baseSpacingValue, direction, spacingFormat
|
911 |
+
array('NONE', 0, 'top', '0 0 0 0'),
|
912 |
+
array('NONE', 0, 'right', '0 0 0 0'),
|
913 |
+
array('NONE', 0, 'bottom', '0 0 0 0'),
|
914 |
+
array('NONE', 0, 'left', '0 0 0 0'),
|
915 |
+
|
916 |
+
array('MEDIUM', 46, 'top', '%spx 0 0 0'),
|
917 |
+
array('MEDIUM', 46, 'right', '0 %spx 0 0'),
|
918 |
+
array('MEDIUM', 46, 'bottom', '0 0 %spx 0'),
|
919 |
+
array('MEDIUM', 46, 'left', '0 0 0 %spx'),
|
920 |
+
);
|
921 |
+
}
|
922 |
+
|
923 |
+
/**
|
924 |
+
* Generates Border Color Instant Article style values and expected CSS values
|
925 |
+
*
|
926 |
+
* @param string $direction A valid direction for a border style e.g. 'top'
|
927 |
+
* @return array
|
928 |
+
*/
|
929 |
+
public function borderColorValuesProvider($direction)
|
930 |
+
{
|
931 |
+
$width = rand(0, 100);
|
932 |
+
$hexColor = AMPArticleTest::getRandomHexColor();
|
933 |
+
$directionBorder = array(
|
934 |
+
'color' => $hexColor,
|
935 |
+
'width' => $width,
|
936 |
+
);
|
937 |
+
$borderStyle = array(
|
938 |
+
$direction => $directionBorder,
|
939 |
+
);
|
940 |
+
|
941 |
+
// Escape parenthesis before using regex
|
942 |
+
$expectedValue = str_replace(')', '\)', str_replace('(', '\(', AMPArticle::toRGB($hexColor)));
|
943 |
+
|
944 |
+
return array($borderStyle, $expectedValue);
|
945 |
+
}
|
946 |
+
|
947 |
+
/**
|
948 |
+
* Generates values for function borderColorValuesProvider
|
949 |
+
*
|
950 |
+
* @return array
|
951 |
+
*/
|
952 |
+
private function directionsDataProvider()
|
953 |
+
{
|
954 |
+
return array(
|
955 |
+
array('top'),
|
956 |
+
array('right'),
|
957 |
+
array('bottom'),
|
958 |
+
array('left'),
|
959 |
+
);
|
960 |
+
}
|
961 |
+
|
962 |
+
/**
|
963 |
+
* Generates Border Width Instant Article style values and expected CSS values
|
964 |
+
*
|
965 |
+
* @param string $direction A valid direction for a border style e.g. 'top'
|
966 |
+
* @param string $borderFormat The expected format of the border width for the given direction e.g. '%s 0 0 0'
|
967 |
+
* @return array
|
968 |
+
*/
|
969 |
+
public function borderWidthValuesProvider($direction, $borderFormat)
|
970 |
+
{
|
971 |
+
$width = rand(0, 100);
|
972 |
+
$directionBorder = array(
|
973 |
+
'color' => '#000000',
|
974 |
+
'width' => $width,
|
975 |
+
);
|
976 |
+
$borderStyle = array(
|
977 |
+
$direction => $directionBorder,
|
978 |
+
);
|
979 |
+
|
980 |
+
$expectedValue = sprintf($borderFormat, $width !== 0 ? $width . 'px' : 0);
|
981 |
+
return array($borderStyle, $expectedValue);
|
982 |
+
}
|
983 |
+
|
984 |
+
/**
|
985 |
+
* Generates arguments for function borderWidthValuesProvider
|
986 |
+
*
|
987 |
+
* @return array
|
988 |
+
*/
|
989 |
+
private function borderWidthDataProvider()
|
990 |
+
{
|
991 |
+
return array(
|
992 |
+
array('top', '%s 0 0 0'),
|
993 |
+
array('right', '0 %s 0 0'),
|
994 |
+
array('bottom', '0 0 %s 0'),
|
995 |
+
array('left', '0 0 0 %s'),
|
996 |
+
);
|
997 |
+
}
|
998 |
+
|
999 |
+
/**
|
1000 |
+
* Validates the transformation of Instant Article Styles to CSS by updating a second level JSON property and looking for an expected CSS value
|
1001 |
+
*
|
1002 |
+
* @param string $firstLevelKey The name of the Instant Article styles object that is the parent of the property that will be tested
|
1003 |
+
* @param string $secondLevelKey The name of the Instant Article styles object that will be tested
|
1004 |
+
* @param string $cssSelector The CSS selector that will be used to verify the genarted CSS
|
1005 |
+
* @param string $cssProperty The name of CSS property that will be used to test the transformation
|
1006 |
+
* @param string $styleValue The style value that will be assigned to test the generation of an expected CSS value
|
1007 |
+
* @param object $expectedCSSValue The value of CSS property that will be used to test the transformation
|
1008 |
+
* @return void
|
1009 |
+
*/
|
1010 |
+
private function validateSecondLevelProperty($firstLevelKey, $secondLevelKey, $cssSelector, $cssProperty, $styleValue, $expectedCSSValue)
|
1011 |
+
{
|
1012 |
+
// Load the default values
|
1013 |
+
$testStyles = $this->getDefaultStyles();
|
1014 |
+
// Set the style property value that will be used to generate the expected CSS
|
1015 |
+
$testStyles[$firstLevelKey][$secondLevelKey] = $styleValue;
|
1016 |
+
|
1017 |
+
$customProperties = array(
|
1018 |
+
// Use the updated styles instead of the ones defined in the Instant Article document
|
1019 |
+
AMPArticle::OVERRIDE_STYLES_KEY => $testStyles,
|
1020 |
+
);
|
1021 |
+
|
1022 |
+
$renderer = $this->getRenderer('test1', $customProperties);
|
1023 |
+
$context = AMPContext::create(new \DOMDocument(), $renderer->getInstantArticle(), 'ia2amp-');
|
1024 |
+
$css = $renderer->getCustomCSS($context);
|
1025 |
+
|
1026 |
+
// Look for the expected CSS
|
1027 |
+
$this->validateCSSRule($css, $cssSelector, $cssProperty, $expectedCSSValue);
|
1028 |
+
}
|
1029 |
+
|
1030 |
+
/**
|
1031 |
+
* Inspects CSS rules looking for expected values using regular expressions
|
1032 |
+
*
|
1033 |
+
* @param string $css The CSS rules that will be inspected
|
1034 |
+
* @param string $selector The CSS selector whose rules will be inspected
|
1035 |
+
* @param string $property The CSS property that will be verified
|
1036 |
+
* @param string $value The CSS property value that will be verified
|
1037 |
+
* @return void
|
1038 |
+
*/
|
1039 |
+
private function validateCSSRule($css, $selector, $property, $value)
|
1040 |
+
{
|
1041 |
+
// Escape the dot (used on class name selectors) so it is not interpreted as any character
|
1042 |
+
$selector = str_replace('.', '\.', $selector);
|
1043 |
+
|
1044 |
+
$cssRulePattern = '/' . $selector. '\s*{[^}]*'. $property . ':\s*' . $value . ';/';
|
1045 |
+
$this->assertEquals(1, preg_match($cssRulePattern, $css), "Could not find CSS rule '$property' for selector '$selector'");
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
/**
|
1049 |
+
* Generates a random color expressed as three hexadecimal values
|
1050 |
+
*
|
1051 |
+
* @return string E.g. '#237A90'
|
1052 |
+
*/
|
1053 |
+
private static function getRandomHexColor()
|
1054 |
+
{
|
1055 |
+
$red = rand(0, 255);
|
1056 |
+
$green = rand(0, 255);
|
1057 |
+
$blue = rand(0, 255);
|
1058 |
+
|
1059 |
+
return '#' . str_pad(dechex($red), 2, '0', STR_PAD_LEFT) .
|
1060 |
+
str_pad(dechex($green), 2, '0', STR_PAD_LEFT) .
|
1061 |
+
str_pad(dechex($blue), 2, '0', STR_PAD_LEFT);
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
public function testBuildAnalytics()
|
1065 |
+
{
|
1066 |
+
$properties = array();
|
1067 |
+
$properties['analytics'] = [
|
1068 |
+
'<amp-pixel src="https://foo.com/pixel?RANDOM"></amp-pixel>',
|
1069 |
+
'<amp-analytics><script type="application/json">{}</script></amp-analytics>'
|
1070 |
+
];
|
1071 |
+
|
1072 |
+
$context = AMPContext::create(new \DOMDocument(), InstantArticle::create());
|
1073 |
+
|
1074 |
+
$article = AMPArticle::create('<html></html>', $properties);
|
1075 |
+
$fragment = $article->buildAnalytics($context);
|
1076 |
+
|
1077 |
+
$this->assertEquals(2, $fragment->childNodes->length);
|
1078 |
+
|
1079 |
+
$pixel = $fragment->firstChild;
|
1080 |
+
$this->assertEquals('amp-pixel', $pixel->tagName);
|
1081 |
+
$this->assertEquals('https://foo.com/pixel?RANDOM', $pixel->getAttribute('src'));
|
1082 |
+
|
1083 |
+
$analytics = $fragment->childNodes->item(1);
|
1084 |
+
$this->assertEquals('amp-analytics', $analytics->tagName);
|
1085 |
+
$this->assertEquals(1, $analytics->childNodes->length);
|
1086 |
+
|
1087 |
+
$analyticsScript = $analytics->firstChild;
|
1088 |
+
$this->assertEquals('script', $analyticsScript->tagName);
|
1089 |
+
$this->assertEquals('application/json', $analyticsScript->getAttribute('type'));
|
1090 |
+
$this->assertEquals('{}', $analyticsScript->textContent);
|
1091 |
+
}
|
1092 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPCaptionTest.php
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
|
12 |
+
use Facebook\InstantArticles\Elements\InstantArticle;
|
13 |
+
use Facebook\InstantArticles\Elements\Header;
|
14 |
+
use Facebook\InstantArticles\Elements\Image;
|
15 |
+
use Facebook\InstantArticles\Elements\Time;
|
16 |
+
use Facebook\InstantArticles\Elements\Author;
|
17 |
+
use Facebook\InstantArticles\Elements\Caption;
|
18 |
+
use PHPUnit\Framework;
|
19 |
+
|
20 |
+
class AMPCaptionTest extends Framework\TestCase
|
21 |
+
{
|
22 |
+
|
23 |
+
protected function setUp()
|
24 |
+
{
|
25 |
+
\Logger::configure(
|
26 |
+
[
|
27 |
+
'rootLogger' => [
|
28 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
29 |
+
],
|
30 |
+
'appenders' => [
|
31 |
+
'facebook-instantarticles-traverser' => [
|
32 |
+
'class' => 'LoggerAppenderConsole',
|
33 |
+
'threshold' => 'INFO',
|
34 |
+
'layout' => [
|
35 |
+
'class' => 'LoggerLayoutSimple'
|
36 |
+
]
|
37 |
+
]
|
38 |
+
]
|
39 |
+
]
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
private function genInstantArticle()
|
44 |
+
{
|
45 |
+
return InstantArticle::create()
|
46 |
+
->withHeader(
|
47 |
+
Header::create()
|
48 |
+
->withTitle('Big Top Title')
|
49 |
+
->withSubTitle('Smaller SubTitle')
|
50 |
+
->withPublishTime(
|
51 |
+
Time::create(Time::PUBLISHED)
|
52 |
+
->withDatetime(
|
53 |
+
\DateTime::createFromFormat(
|
54 |
+
'j-M-Y G:i:s',
|
55 |
+
'14-Aug-1984 19:30:00'
|
56 |
+
)
|
57 |
+
)
|
58 |
+
)
|
59 |
+
->addAuthor(
|
60 |
+
Author::create()
|
61 |
+
->withName('Author One')
|
62 |
+
->withDescription('Passionate coder and mountain biker')
|
63 |
+
)
|
64 |
+
->addAuthor(
|
65 |
+
Author::create()
|
66 |
+
->withName('Author Two')
|
67 |
+
->withDescription('Weend surfer with heavy weight coding skils')
|
68 |
+
->withURL('http://facebook.com/author')
|
69 |
+
)
|
70 |
+
->withKicker('Some kicker of this article')
|
71 |
+
->withCover(
|
72 |
+
Image::create()
|
73 |
+
->withURL('http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg')
|
74 |
+
->withCaption(
|
75 |
+
Caption::create()
|
76 |
+
->appendText('Some caption to the image')
|
77 |
+
)
|
78 |
+
)
|
79 |
+
);
|
80 |
+
}
|
81 |
+
|
82 |
+
private function genContext($document, $instantArticle)
|
83 |
+
{
|
84 |
+
$context = AMPContext::create($document, $instantArticle);
|
85 |
+
|
86 |
+
$mediaSizes = array();
|
87 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
88 |
+
$enableDownloadForMediaSizing = false;
|
89 |
+
$defaultWidth = 1000;
|
90 |
+
$defaultHeight = 900;
|
91 |
+
|
92 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
93 |
+
|
94 |
+
return $context;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function testCaptionOnElementBottomByDefault()
|
98 |
+
{
|
99 |
+
$expected =
|
100 |
+
'<figure class="ia2amp-figure">'.
|
101 |
+
'<amp-img/>'.
|
102 |
+
'<figcaption class="ia2amp-figcaption ia2amp-op-small">Some caption to the image</figcaption>'.
|
103 |
+
'</figure>';
|
104 |
+
$instantArticle = $this->genInstantArticle();
|
105 |
+
|
106 |
+
$document = new \DOMDocument();
|
107 |
+
$context = $this->genContext($document, $instantArticle);
|
108 |
+
|
109 |
+
$ampImg = $document->createElement('amp-img');
|
110 |
+
$result = AMPCaption::create($instantArticle->getHeader()->getCover()->getCaption(), $context, $ampImg)->build();
|
111 |
+
$this->assertEquals($expected, $result->ownerDocument->saveXML($result));
|
112 |
+
}
|
113 |
+
|
114 |
+
public function testCaptionOnTopOfElement()
|
115 |
+
{
|
116 |
+
$expected =
|
117 |
+
'<figure class="ia2amp-figure">'.
|
118 |
+
'<figcaption class="ia2amp-figcaption ia2amp-op-small ia2amp-op-vertical-above">Some caption to the image</figcaption>'.
|
119 |
+
'<amp-img/>'.
|
120 |
+
'</figure>';
|
121 |
+
$instantArticle = $this->genInstantArticle();
|
122 |
+
$instantArticle->getHeader()->getCover()->getCaption()->withPosition(Caption::POSITION_ABOVE);
|
123 |
+
|
124 |
+
$document = new \DOMDocument();
|
125 |
+
$context = $this->genContext($document, $instantArticle);
|
126 |
+
|
127 |
+
$ampImg = $document->createElement('amp-img');
|
128 |
+
$result = AMPCaption::create($instantArticle->getHeader()->getCover()->getCaption(), $context, $ampImg)->build();
|
129 |
+
$this->assertEquals($expected, $result->ownerDocument->saveXML($result));
|
130 |
+
}
|
131 |
+
|
132 |
+
public function testCaptionOnTopOfElementBiggerSize()
|
133 |
+
{
|
134 |
+
$expected =
|
135 |
+
'<figure class="ia2amp-figure">'.
|
136 |
+
'<figcaption class="ia2amp-figcaption ia2amp-op-extra-large ia2amp-op-vertical-above">Some caption to the image</figcaption>'.
|
137 |
+
'<amp-img/>'.
|
138 |
+
'</figure>';
|
139 |
+
$instantArticle = $this->genInstantArticle();
|
140 |
+
$instantArticle->getHeader()->getCover()->getCaption()->withPosition(Caption::POSITION_ABOVE)->withFontsize(Caption::SIZE_XLARGE);
|
141 |
+
|
142 |
+
$document = new \DOMDocument();
|
143 |
+
$context = $this->genContext($document, $instantArticle);
|
144 |
+
|
145 |
+
$ampImg = $document->createElement('amp-img');
|
146 |
+
$result = AMPCaption::create($instantArticle->getHeader()->getCover()->getCaption(), $context, $ampImg)->build();
|
147 |
+
$this->assertEquals($expected, $result->ownerDocument->saveXML($result));
|
148 |
+
}
|
149 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPContextTest.php
ADDED
@@ -0,0 +1,563 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Elements\InstantArticle;
|
12 |
+
use Facebook\InstantArticles\Elements\Paragraph;
|
13 |
+
use PHPUnit\Framework;
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
class AMPContextTest extends Framework\TestCase
|
18 |
+
{
|
19 |
+
protected function setUp()
|
20 |
+
{
|
21 |
+
\Logger::configure(
|
22 |
+
[
|
23 |
+
'rootLogger' => [
|
24 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
25 |
+
],
|
26 |
+
'appenders' => [
|
27 |
+
'facebook-instantarticles-traverser' => [
|
28 |
+
'class' => 'LoggerAppenderConsole',
|
29 |
+
'threshold' => 'INFO',
|
30 |
+
'layout' => [
|
31 |
+
'class' => 'LoggerLayoutSimple'
|
32 |
+
]
|
33 |
+
]
|
34 |
+
]
|
35 |
+
]
|
36 |
+
);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function testContextCreation()
|
40 |
+
{
|
41 |
+
$context = AMPContext::create(new \DOMDocument(), InstantArticle::create());
|
42 |
+
$this->assertNotNull($context);
|
43 |
+
}
|
44 |
+
|
45 |
+
public function testContextCreationErrorDocument()
|
46 |
+
{
|
47 |
+
$this->setExpectedException('InvalidArgumentException');
|
48 |
+
$context = AMPContext::create("new \DOMDocument()", InstantArticle::create());
|
49 |
+
}
|
50 |
+
|
51 |
+
public function testContextCreationErrorIA()
|
52 |
+
{
|
53 |
+
$this->setExpectedException('InvalidArgumentException');
|
54 |
+
$context = AMPContext::create(new \DOMDocument(), Paragraph::create());
|
55 |
+
}
|
56 |
+
|
57 |
+
public function testCreatingHtml()
|
58 |
+
{
|
59 |
+
$document = new \DOMDocument();
|
60 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
61 |
+
$context->withHtml($document->createElement('html'));
|
62 |
+
$this->assertTrue($context->hasHtml());
|
63 |
+
}
|
64 |
+
|
65 |
+
public function testCreatingHtmlEmpty()
|
66 |
+
{
|
67 |
+
$document = new \DOMDocument();
|
68 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
69 |
+
$this->assertFalse($context->hasHtml());
|
70 |
+
}
|
71 |
+
|
72 |
+
public function testCreatingHtmlInvalid()
|
73 |
+
{
|
74 |
+
$document = new \DOMDocument();
|
75 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
76 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <html> expected, <script> informed.');
|
77 |
+
$context->withHtml($document->createElement('script'));
|
78 |
+
}
|
79 |
+
|
80 |
+
public function testCreatingHead()
|
81 |
+
{
|
82 |
+
$document = new \DOMDocument();
|
83 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
84 |
+
$context->withHead($document->createElement('head'));
|
85 |
+
$this->assertTrue($context->hasHead());
|
86 |
+
}
|
87 |
+
|
88 |
+
public function testCreatingHeadEmpty()
|
89 |
+
{
|
90 |
+
$document = new \DOMDocument();
|
91 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
92 |
+
$this->assertFalse($context->hasHead());
|
93 |
+
}
|
94 |
+
|
95 |
+
public function testCreatingHeadInvalid()
|
96 |
+
{
|
97 |
+
$document = new \DOMDocument();
|
98 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
99 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <head> expected, <script> informed.');
|
100 |
+
$context->withHead($document->createElement('script'));
|
101 |
+
}
|
102 |
+
|
103 |
+
public function testCreatingBody()
|
104 |
+
{
|
105 |
+
$document = new \DOMDocument();
|
106 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
107 |
+
$context->withBody($document->createElement('body'));
|
108 |
+
$this->assertTrue($context->hasBody());
|
109 |
+
}
|
110 |
+
|
111 |
+
public function testCreatingBodyEmpty()
|
112 |
+
{
|
113 |
+
$document = new \DOMDocument();
|
114 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
115 |
+
$this->assertFalse($context->hasBody());
|
116 |
+
}
|
117 |
+
|
118 |
+
public function testCreatingBodyInvalid()
|
119 |
+
{
|
120 |
+
$document = new \DOMDocument();
|
121 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
122 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <body> expected, <script> informed.');
|
123 |
+
$context->withBody($document->createElement('script'));
|
124 |
+
}
|
125 |
+
|
126 |
+
public function testCreatingArticle()
|
127 |
+
{
|
128 |
+
$document = new \DOMDocument();
|
129 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
130 |
+
$context->withArticle($document->createElement('article'));
|
131 |
+
$this->assertTrue($context->hasArticle());
|
132 |
+
}
|
133 |
+
|
134 |
+
public function testCreatingArticleEmpty()
|
135 |
+
{
|
136 |
+
$document = new \DOMDocument();
|
137 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
138 |
+
$this->assertFalse($context->hasArticle());
|
139 |
+
}
|
140 |
+
|
141 |
+
public function testCreatingArticleInvalid()
|
142 |
+
{
|
143 |
+
$document = new \DOMDocument();
|
144 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
145 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <article> expected, <script> informed.');
|
146 |
+
$context->withArticle($document->createElement('script'));
|
147 |
+
}
|
148 |
+
|
149 |
+
public function testCreatingHeader()
|
150 |
+
{
|
151 |
+
$document = new \DOMDocument();
|
152 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
153 |
+
$context->withHeader($document->createElement('header'));
|
154 |
+
$this->assertTrue($context->hasHeader());
|
155 |
+
}
|
156 |
+
|
157 |
+
public function testCreatingHeaderEmpty()
|
158 |
+
{
|
159 |
+
$document = new \DOMDocument();
|
160 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
161 |
+
$this->assertFalse($context->hasHeader());
|
162 |
+
}
|
163 |
+
|
164 |
+
public function testCreatingHeaderInvalid()
|
165 |
+
{
|
166 |
+
$document = new \DOMDocument();
|
167 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
168 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <header> expected, <script> informed.');
|
169 |
+
$context->withHeader($document->createElement('script'));
|
170 |
+
}
|
171 |
+
|
172 |
+
public function testCreatingHeaderBar()
|
173 |
+
{
|
174 |
+
$document = new \DOMDocument();
|
175 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
176 |
+
$context->withHeaderBar($document->createElement('div'));
|
177 |
+
$this->assertTrue($context->hasHeaderBar());
|
178 |
+
}
|
179 |
+
|
180 |
+
public function testCreatingHeaderBarEmpty()
|
181 |
+
{
|
182 |
+
$document = new \DOMDocument();
|
183 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
184 |
+
$this->assertFalse($context->hasHeaderBar());
|
185 |
+
}
|
186 |
+
|
187 |
+
public function testCreatingHeaderBarInvalid()
|
188 |
+
{
|
189 |
+
$document = new \DOMDocument();
|
190 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
191 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <div> expected, <script> informed.');
|
192 |
+
$context->withHeaderBar($document->createElement('script'));
|
193 |
+
}
|
194 |
+
|
195 |
+
public function testCreatingHeaderBarLogo()
|
196 |
+
{
|
197 |
+
$document = new \DOMDocument();
|
198 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
199 |
+
$context->withHeaderBarLogo($document->createElement('div'));
|
200 |
+
$this->assertTrue($context->hasHeaderBarLogo());
|
201 |
+
}
|
202 |
+
|
203 |
+
public function testCreatingHeaderBarLogoEmpty()
|
204 |
+
{
|
205 |
+
$document = new \DOMDocument();
|
206 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
207 |
+
$this->assertFalse($context->hasHeaderBarLogo());
|
208 |
+
}
|
209 |
+
|
210 |
+
public function testCreatingHeaderBarLogoInvalid()
|
211 |
+
{
|
212 |
+
$document = new \DOMDocument();
|
213 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
214 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <div> expected, <script> informed.');
|
215 |
+
$context->withHeaderBarLogo($document->createElement('script'));
|
216 |
+
}
|
217 |
+
|
218 |
+
public function testCreatingHeaderTitle()
|
219 |
+
{
|
220 |
+
$document = new \DOMDocument();
|
221 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
222 |
+
$context->withHeaderTitle($document->createElement('h1'));
|
223 |
+
$this->assertTrue($context->hasHeaderTitle());
|
224 |
+
}
|
225 |
+
|
226 |
+
public function testCreatingHeaderTitleEmpty()
|
227 |
+
{
|
228 |
+
$document = new \DOMDocument();
|
229 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
230 |
+
$this->assertFalse($context->hasHeaderTitle());
|
231 |
+
}
|
232 |
+
|
233 |
+
public function testCreatingHeaderTitleInvalid()
|
234 |
+
{
|
235 |
+
$document = new \DOMDocument();
|
236 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
237 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <h1> expected, <script> informed.');
|
238 |
+
$context->withHeaderTitle($document->createElement('script'));
|
239 |
+
}
|
240 |
+
|
241 |
+
public function testCreatingHeaderAuthor()
|
242 |
+
{
|
243 |
+
$document = new \DOMDocument();
|
244 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
245 |
+
$context->withHeaderAuthor($document->createElement('h3'));
|
246 |
+
$this->assertTrue($context->hasHeaderAuthor());
|
247 |
+
}
|
248 |
+
|
249 |
+
public function testCreatingHeaderAuthorEmpty()
|
250 |
+
{
|
251 |
+
$document = new \DOMDocument();
|
252 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
253 |
+
$this->assertFalse($context->hasHeaderAuthor());
|
254 |
+
}
|
255 |
+
|
256 |
+
public function testCreatingHeaderAuthorInvalid()
|
257 |
+
{
|
258 |
+
$document = new \DOMDocument();
|
259 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
260 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <h3> expected, <script> informed.');
|
261 |
+
$context->withHeaderAuthor($document->createElement('script'));
|
262 |
+
}
|
263 |
+
|
264 |
+
public function testCreatingHeaderKicker()
|
265 |
+
{
|
266 |
+
$document = new \DOMDocument();
|
267 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
268 |
+
$context->withHeaderKicker($document->createElement('h2'));
|
269 |
+
$this->assertTrue($context->hasHeaderKicker());
|
270 |
+
}
|
271 |
+
|
272 |
+
public function testCreatingHeaderKickerEmpty()
|
273 |
+
{
|
274 |
+
$document = new \DOMDocument();
|
275 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
276 |
+
$this->assertFalse($context->hasHeaderKicker());
|
277 |
+
}
|
278 |
+
|
279 |
+
public function testCreatingHeaderKickerInvalid()
|
280 |
+
{
|
281 |
+
$document = new \DOMDocument();
|
282 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
283 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <h2> expected, <script> informed.');
|
284 |
+
$context->withHeaderKicker($document->createElement('script'));
|
285 |
+
}
|
286 |
+
|
287 |
+
public function testCreatingHeaderDate()
|
288 |
+
{
|
289 |
+
$document = new \DOMDocument();
|
290 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
291 |
+
$context->withHeaderDate($document->createElement('h3'));
|
292 |
+
$this->assertTrue($context->hasHeaderDate());
|
293 |
+
}
|
294 |
+
|
295 |
+
public function testCreatingHeaderDateEmpty()
|
296 |
+
{
|
297 |
+
$document = new \DOMDocument();
|
298 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
299 |
+
$this->assertFalse($context->hasHeaderDate());
|
300 |
+
}
|
301 |
+
|
302 |
+
public function testCreatingHeaderDateInvalid()
|
303 |
+
{
|
304 |
+
$document = new \DOMDocument();
|
305 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
306 |
+
$this->setExpectedException('InvalidArgumentException', 'Tag <h3> expected, <script> informed.');
|
307 |
+
$context->withHeaderDate($document->createElement('script'));
|
308 |
+
}
|
309 |
+
|
310 |
+
public function testInformedImageDimensions()
|
311 |
+
{
|
312 |
+
$expectedWidth = 800;
|
313 |
+
$expectedHeight = 500;
|
314 |
+
|
315 |
+
$document = new \DOMDocument();
|
316 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
317 |
+
|
318 |
+
$mediaSizes = array('https://www.facebook.com/images/fb_icon_325x325.png' => array($expectedWidth, $expectedHeight));
|
319 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
320 |
+
$enableDownloadForMediaSizing = true;
|
321 |
+
$defaultWidth = 1000;
|
322 |
+
$defaultHeight = 900;
|
323 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
324 |
+
|
325 |
+
$dimensions = $context->getMediaDimensions('https://www.facebook.com/images/fb_icon_325x325.png');
|
326 |
+
|
327 |
+
$this->assertEquals($expectedWidth, $dimensions[0]);
|
328 |
+
$this->assertEquals($expectedHeight, $dimensions[1]);
|
329 |
+
}
|
330 |
+
|
331 |
+
public function testCachedImageDimensions()
|
332 |
+
{
|
333 |
+
$expectedWidth = 325;
|
334 |
+
$expectedHeight = 325;
|
335 |
+
|
336 |
+
$document = new \DOMDocument();
|
337 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
338 |
+
|
339 |
+
$mediaSizes = array();
|
340 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
341 |
+
$enableDownloadForMediaSizing = true;
|
342 |
+
$defaultWidth = 1000;
|
343 |
+
$defaultHeight = 900;
|
344 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
345 |
+
|
346 |
+
$dimensions = $context->getMediaDimensions('https://www.facebook.com/images/fb_icon_325x325.png');
|
347 |
+
|
348 |
+
$this->assertEquals($expectedWidth, $dimensions[0]);
|
349 |
+
$this->assertEquals($expectedHeight, $dimensions[1]);
|
350 |
+
}
|
351 |
+
|
352 |
+
public function testImageDimensionsDownloadDisabled()
|
353 |
+
{
|
354 |
+
$expectedWidth = 325;
|
355 |
+
$expectedHeight = 325;
|
356 |
+
|
357 |
+
$document = new \DOMDocument();
|
358 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
359 |
+
|
360 |
+
$mediaSizes = array();
|
361 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
362 |
+
$enableDownloadForMediaSizing = false;
|
363 |
+
$defaultWidth = 1000;
|
364 |
+
$defaultHeight = 900;
|
365 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
366 |
+
|
367 |
+
$dimensions = $context->getMediaDimensions('https://www.facebook.com/images/fb_icon_325x325.png');
|
368 |
+
|
369 |
+
$this->assertEquals($expectedWidth, $dimensions[0]);
|
370 |
+
$this->assertEquals($expectedHeight, $dimensions[1]);
|
371 |
+
}
|
372 |
+
|
373 |
+
public function testImageDimensionsDownloadEnabled()
|
374 |
+
{
|
375 |
+
$expectedWidth = 325;
|
376 |
+
$expectedHeight = 325;
|
377 |
+
|
378 |
+
$document = new \DOMDocument();
|
379 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
380 |
+
|
381 |
+
$mediaSizes = array();
|
382 |
+
$mediaCacheFolder = null;
|
383 |
+
$enableDownloadForMediaSizing = true;
|
384 |
+
$defaultWidth = 1000;
|
385 |
+
$defaultHeight = 900;
|
386 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
387 |
+
|
388 |
+
$dimensions = $context->getMediaDimensions('https://www.facebook.com/images/fb_icon_325x325.png', AMPContext::MEDIA_TYPE_IMAGE);
|
389 |
+
|
390 |
+
$this->assertEquals($expectedWidth, $dimensions[0]);
|
391 |
+
$this->assertEquals($expectedHeight, $dimensions[1]);
|
392 |
+
}
|
393 |
+
|
394 |
+
public function testImageDimensionsDefault()
|
395 |
+
{
|
396 |
+
$document = new \DOMDocument();
|
397 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
398 |
+
|
399 |
+
$mediaSizes = array();
|
400 |
+
$mediaCacheFolder = null;
|
401 |
+
$enableDownloadForMediaSizing = false;
|
402 |
+
$defaultWidth = 1000;
|
403 |
+
$defaultHeight = 900;
|
404 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
405 |
+
|
406 |
+
$dimensions = $context->getMediaDimensions('https://www.facebook.com/images/fb_icon_325x325.png', AMPContext::MEDIA_TYPE_IMAGE);
|
407 |
+
|
408 |
+
$this->assertEquals($defaultWidth, $dimensions[0]);
|
409 |
+
$this->assertEquals($defaultHeight, $dimensions[1]);
|
410 |
+
}
|
411 |
+
|
412 |
+
public function testInformedVideoDimensions()
|
413 |
+
{
|
414 |
+
$expectedWidth = 800;
|
415 |
+
$expectedHeight = 500;
|
416 |
+
|
417 |
+
$document = new \DOMDocument();
|
418 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
419 |
+
|
420 |
+
$mediaSizes = array('http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4' => array($expectedWidth, $expectedHeight));
|
421 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
422 |
+
$enableDownloadForMediaSizing = true;
|
423 |
+
$defaultWidth = 1000;
|
424 |
+
$defaultHeight = 900;
|
425 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
426 |
+
|
427 |
+
$dimensions = $context->getMediaDimensions('http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4', AMPContext::MEDIA_TYPE_VIDEO);
|
428 |
+
|
429 |
+
$this->assertEquals($expectedWidth, $dimensions[0]);
|
430 |
+
$this->assertEquals($expectedHeight, $dimensions[1]);
|
431 |
+
}
|
432 |
+
|
433 |
+
public function testCachedVideoDimensions()
|
434 |
+
{
|
435 |
+
$document = new \DOMDocument();
|
436 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
437 |
+
|
438 |
+
$mediaSizes = array();
|
439 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
440 |
+
$enableDownloadForMediaSizing = true;
|
441 |
+
$defaultWidth = 1000;
|
442 |
+
$defaultHeight = 900;
|
443 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
444 |
+
|
445 |
+
$dimensions = $context->getMediaDimensions('http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4', AMPContext::MEDIA_TYPE_VIDEO);
|
446 |
+
|
447 |
+
$this->assertEquals($defaultWidth, $dimensions[0]);
|
448 |
+
$this->assertEquals($defaultHeight, $dimensions[1]);
|
449 |
+
}
|
450 |
+
|
451 |
+
public function testVideoDimensionsDownloadDisabled()
|
452 |
+
{
|
453 |
+
$document = new \DOMDocument();
|
454 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
455 |
+
|
456 |
+
$mediaSizes = array();
|
457 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
458 |
+
$enableDownloadForMediaSizing = false;
|
459 |
+
$defaultWidth = 1000;
|
460 |
+
$defaultHeight = 900;
|
461 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
462 |
+
|
463 |
+
$dimensions = $context->getMediaDimensions('http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4', AMPContext::MEDIA_TYPE_VIDEO);
|
464 |
+
|
465 |
+
$this->assertEquals($defaultWidth, $dimensions[0]);
|
466 |
+
$this->assertEquals($defaultHeight, $dimensions[1]);
|
467 |
+
}
|
468 |
+
|
469 |
+
public function testVideoDimensionsDownloadEnabled()
|
470 |
+
{
|
471 |
+
$document = new \DOMDocument();
|
472 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
473 |
+
|
474 |
+
$mediaSizes = array();
|
475 |
+
$mediaCacheFolder = null;
|
476 |
+
$enableDownloadForMediaSizing = true;
|
477 |
+
$defaultWidth = 1000;
|
478 |
+
$defaultHeight = 900;
|
479 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
480 |
+
|
481 |
+
$dimensions = $context->getMediaDimensions('http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4', AMPContext::MEDIA_TYPE_VIDEO);
|
482 |
+
|
483 |
+
$this->assertEquals($defaultWidth, $dimensions[0]);
|
484 |
+
$this->assertEquals($defaultHeight, $dimensions[1]);
|
485 |
+
}
|
486 |
+
|
487 |
+
public function testVideoDimensionsDefault()
|
488 |
+
{
|
489 |
+
$document = new \DOMDocument();
|
490 |
+
$context = AMPContext::create($document, InstantArticle::create());
|
491 |
+
|
492 |
+
$mediaSizes = array();
|
493 |
+
$mediaCacheFolder = null;
|
494 |
+
$enableDownloadForMediaSizing = false;
|
495 |
+
$defaultWidth = 1000;
|
496 |
+
$defaultHeight = 900;
|
497 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
498 |
+
|
499 |
+
$dimensions = $context->getMediaDimensions('http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4', AMPContext::MEDIA_TYPE_VIDEO);
|
500 |
+
|
501 |
+
$this->assertEquals($defaultWidth, $dimensions[0]);
|
502 |
+
$this->assertEquals($defaultHeight, $dimensions[1]);
|
503 |
+
}
|
504 |
+
|
505 |
+
//
|
506 |
+
// public function testVideoHeightDefaultProperty()
|
507 |
+
// {
|
508 |
+
// $expectedHeight = 120;
|
509 |
+
// $customProperties = array(
|
510 |
+
// AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
511 |
+
// AMPArticle::DEFAULT_MEDIA_HEIGHT_KEY => $expectedHeight,
|
512 |
+
// );
|
513 |
+
//
|
514 |
+
// $videoXPathQuery = $this->getRenderedMarkupXPathQuery(
|
515 |
+
// 'natgeo',
|
516 |
+
// '//amp-video',
|
517 |
+
// $customProperties
|
518 |
+
// );
|
519 |
+
// $firstArticleVideoElement = $videoXPathQuery->item(0);
|
520 |
+
//
|
521 |
+
// $this->assertEquals($expectedHeight, $firstArticleVideoElement->getAttribute('height'));
|
522 |
+
// }
|
523 |
+
//
|
524 |
+
// public function testVideoWidthFromMediaSizes()
|
525 |
+
// {
|
526 |
+
// $expectedWidth = 90;
|
527 |
+
// $customProperties = array(
|
528 |
+
// AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
529 |
+
// AMPArticle::MEDIA_SIZES_KEY => array(
|
530 |
+
// "http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4" => array($expectedWidth, 60),
|
531 |
+
// ),
|
532 |
+
// );
|
533 |
+
//
|
534 |
+
// $videoXPathQuery = $this->getRenderedMarkupXPathQuery(
|
535 |
+
// 'natgeo',
|
536 |
+
// '//amp-video',
|
537 |
+
// $customProperties
|
538 |
+
// );
|
539 |
+
// $firstArticleVideoElement = $videoXPathQuery->item(0);
|
540 |
+
//
|
541 |
+
// $this->assertEquals($expectedWidth, $firstArticleVideoElement->getAttribute('width'));
|
542 |
+
// }
|
543 |
+
//
|
544 |
+
// public function testVideoHeightFromMediaSizes()
|
545 |
+
// {
|
546 |
+
// $expectedHeight = 60;
|
547 |
+
// $customProperties = array(
|
548 |
+
// AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
549 |
+
// AMPArticle::MEDIA_SIZES_KEY => array(
|
550 |
+
// "http://ngm.nationalgeographic.com/2015/05/building-bees/v/timelapse-final-4x3.mp4" => array(90, $expectedHeight),
|
551 |
+
// ),
|
552 |
+
// );
|
553 |
+
//
|
554 |
+
// $videoXPathQuery = $this->getRenderedMarkupXPathQuery(
|
555 |
+
// 'natgeo',
|
556 |
+
// '//amp-video',
|
557 |
+
// $customProperties
|
558 |
+
// );
|
559 |
+
// $firstArticleVideoElement = $videoXPathQuery->item(0);
|
560 |
+
//
|
561 |
+
// $this->assertEquals($expectedHeight, $firstArticleVideoElement->getAttribute('height'));
|
562 |
+
// }
|
563 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPCoverImageTest.php
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
|
12 |
+
use Facebook\InstantArticles\Elements\InstantArticle;
|
13 |
+
use Facebook\InstantArticles\Elements\Header;
|
14 |
+
use Facebook\InstantArticles\Elements\Image;
|
15 |
+
use Facebook\InstantArticles\Elements\Time;
|
16 |
+
use Facebook\InstantArticles\Elements\Author;
|
17 |
+
use Facebook\InstantArticles\Elements\Caption;
|
18 |
+
use PHPUnit\Framework;
|
19 |
+
|
20 |
+
class AMPCoverImageTest extends Framework\TestCase
|
21 |
+
{
|
22 |
+
|
23 |
+
protected function setUp()
|
24 |
+
{
|
25 |
+
\Logger::configure(
|
26 |
+
[
|
27 |
+
'rootLogger' => [
|
28 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
29 |
+
],
|
30 |
+
'appenders' => [
|
31 |
+
'facebook-instantarticles-traverser' => [
|
32 |
+
'class' => 'LoggerAppenderConsole',
|
33 |
+
'threshold' => 'INFO',
|
34 |
+
'layout' => [
|
35 |
+
'class' => 'LoggerLayoutSimple'
|
36 |
+
]
|
37 |
+
]
|
38 |
+
]
|
39 |
+
]
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
private function genInstantArticle()
|
44 |
+
{
|
45 |
+
return InstantArticle::create()
|
46 |
+
->withHeader(
|
47 |
+
Header::create()
|
48 |
+
->withTitle('Big Top Title')
|
49 |
+
->withSubTitle('Smaller SubTitle')
|
50 |
+
->withPublishTime(
|
51 |
+
Time::create(Time::PUBLISHED)
|
52 |
+
->withDatetime(
|
53 |
+
\DateTime::createFromFormat(
|
54 |
+
'j-M-Y G:i:s',
|
55 |
+
'14-Aug-1984 19:30:00'
|
56 |
+
)
|
57 |
+
)
|
58 |
+
)
|
59 |
+
->addAuthor(
|
60 |
+
Author::create()
|
61 |
+
->withName('Author One')
|
62 |
+
->withDescription('Passionate coder and mountain biker')
|
63 |
+
)
|
64 |
+
->addAuthor(
|
65 |
+
Author::create()
|
66 |
+
->withName('Author Two')
|
67 |
+
->withDescription('Weend surfer with heavy weight coding skils')
|
68 |
+
->withURL('http://facebook.com/author')
|
69 |
+
)
|
70 |
+
->withKicker('Some kicker of this article')
|
71 |
+
->withCover(
|
72 |
+
Image::create()
|
73 |
+
->withURL('http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg')
|
74 |
+
)
|
75 |
+
);
|
76 |
+
}
|
77 |
+
|
78 |
+
private function genContext($document, $instantArticle)
|
79 |
+
{
|
80 |
+
$context = AMPContext::create($document, $instantArticle);
|
81 |
+
|
82 |
+
$mediaSizes = array();
|
83 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
84 |
+
$enableDownloadForMediaSizing = false;
|
85 |
+
$defaultWidth = 1000;
|
86 |
+
$defaultHeight = 900;
|
87 |
+
|
88 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
89 |
+
|
90 |
+
return $context;
|
91 |
+
}
|
92 |
+
|
93 |
+
public function testBuildCoverWithCaption()
|
94 |
+
{
|
95 |
+
$expected =
|
96 |
+
'<div class="ia2amp-cover-image">'.
|
97 |
+
'<figure class="ia2amp-figure">'.
|
98 |
+
'<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg" width="422" height="240"/>'.
|
99 |
+
'<figcaption class="ia2amp-figcaption ia2amp-op-small">Some caption to the image</figcaption>'.
|
100 |
+
'</figure>'.
|
101 |
+
'</div>';
|
102 |
+
$instantArticle = $this->genInstantArticle();
|
103 |
+
$instantArticle->getHeader()->getCover()->withCaption(
|
104 |
+
Caption::create()
|
105 |
+
->appendText('Some caption to the image')
|
106 |
+
);
|
107 |
+
|
108 |
+
$document = new \DOMDocument();
|
109 |
+
$context = $this->genContext($document, $instantArticle);
|
110 |
+
|
111 |
+
$result = AMPCoverImage::create($instantArticle->getHeader()->getCover(), $context, 'cover-image')->build();
|
112 |
+
$this->assertEquals($expected, $result->ownerDocument->saveXML($result));
|
113 |
+
}
|
114 |
+
|
115 |
+
public function testBuildCoverWithoutCaption()
|
116 |
+
{
|
117 |
+
$expected =
|
118 |
+
'<div class="ia2amp-cover-image">'.
|
119 |
+
'<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg" width="422" height="240"/>'.
|
120 |
+
'</div>';
|
121 |
+
$instantArticle = $this->genInstantArticle();
|
122 |
+
|
123 |
+
$document = new \DOMDocument();
|
124 |
+
$context = $this->genContext($document, $instantArticle);
|
125 |
+
|
126 |
+
$result = AMPCoverImage::create($instantArticle->getHeader()->getCover(), $context, 'cover-image')->build();
|
127 |
+
$this->assertEquals($expected, $result->ownerDocument->saveXML($result));
|
128 |
+
}
|
129 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/AMPHeaderTest.php
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\AMP;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Utils\FileUtilsPHPUnitTestCase;
|
12 |
+
|
13 |
+
class AMPHeaderTest extends FileUtilsPHPUnitTestCase
|
14 |
+
{
|
15 |
+
private $logo;
|
16 |
+
private $testHeader;
|
17 |
+
|
18 |
+
protected function setUp()
|
19 |
+
{
|
20 |
+
$url = 'http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png';
|
21 |
+
$width = 600;
|
22 |
+
$height = 60;
|
23 |
+
$this->logo = new AMPImage($url, $width, $height);
|
24 |
+
}
|
25 |
+
|
26 |
+
private function getRenderer($test, $customProperties = null)
|
27 |
+
{
|
28 |
+
$instantArticle = $this->loadInstantArticle(__DIR__ . '/articles/'.$test.'-instant-article.html');
|
29 |
+
$properties = array(
|
30 |
+
'lang' => 'en-US',
|
31 |
+
AMPArticle::STYLES_FOLDER_KEY => __DIR__,
|
32 |
+
AMPArticle::ENABLE_DOWNLOAD_FOR_MEDIA_SIZING_KEY => false,
|
33 |
+
);
|
34 |
+
if (!is_null($customProperties)) {
|
35 |
+
$properties = array_merge($properties, $customProperties);
|
36 |
+
}
|
37 |
+
|
38 |
+
return AMPArticle::create($instantArticle, $properties);
|
39 |
+
}
|
40 |
+
|
41 |
+
private function genContext()
|
42 |
+
{
|
43 |
+
$renderer = $this->getRenderer('test1', null);
|
44 |
+
$context = AMPContext::create(new \DOMDocument('1.0'), $renderer->getInstantArticle());
|
45 |
+
|
46 |
+
$mediaSizes = array();
|
47 |
+
$mediaCacheFolder = __DIR__ . '/articles/media-cache';
|
48 |
+
$enableDownloadForMediaSizing = false;
|
49 |
+
$defaultWidth = 1000;
|
50 |
+
$defaultHeight = 900;
|
51 |
+
|
52 |
+
$context->withMediaSizingSetup($mediaSizes, $mediaCacheFolder, $enableDownloadForMediaSizing, $defaultWidth, $defaultHeight);
|
53 |
+
|
54 |
+
return $context;
|
55 |
+
}
|
56 |
+
|
57 |
+
private function genTestingHeader()
|
58 |
+
{
|
59 |
+
$context = $this->genContext();
|
60 |
+
|
61 |
+
$this->testHeader = new AMPHeader($context);
|
62 |
+
$target = $this->testHeader->build();
|
63 |
+
$this->testHeader->genHeaderLogo($this->logo);
|
64 |
+
|
65 |
+
$document = new \DOMDocument;
|
66 |
+
$document->appendChild($document->importNode($target, true));
|
67 |
+
|
68 |
+
return new \DOMXPath($document);
|
69 |
+
}
|
70 |
+
|
71 |
+
public function testBuild()
|
72 |
+
{
|
73 |
+
$testingHeader = $this->genTestingHeader();
|
74 |
+
|
75 |
+
$publicationDateFetch = $testingHeader->query('//h3[@class="ia2amp-header-date"][1]')->item(0);
|
76 |
+
$titleFetch = $testingHeader->query('//h1[@class="ia2amp-header-h1"][1]')->item(0);
|
77 |
+
$byLineFetch = $testingHeader->query('//h3[@class="ia2amp-header-author"][1]')->item(0);
|
78 |
+
$kickerFetch = $testingHeader->query('//h2[@class="ia2amp-header-category"][1]')->item(0);
|
79 |
+
$logo = $testingHeader->query('//div[@class="ia2amp-header-bar-img-container"]/amp-img[1]')->item(0);
|
80 |
+
|
81 |
+
$publicationDate = $publicationDateFetch->textContent;
|
82 |
+
$title = $titleFetch->textContent;
|
83 |
+
$byLine = $byLineFetch->textContent;
|
84 |
+
$kicker = $kickerFetch->textContent;
|
85 |
+
|
86 |
+
$this->assertEquals("http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png", $logo->getAttribute("src"));
|
87 |
+
$this->assertEquals(600, $logo->getAttribute("width"));
|
88 |
+
$this->assertEquals(60, $logo->getAttribute("height"));
|
89 |
+
$this->assertEquals("motivational", $kicker);
|
90 |
+
$this->assertEquals("Very First WOD!", $title);
|
91 |
+
//$this->assertEquals("May 10, 2016", $publicationDate);
|
92 |
+
$this->assertEquals("By Éverton Rosário", $byLine);
|
93 |
+
|
94 |
+
$spaceNodes = array(
|
95 |
+
'//div[@class="ia2amp-header-bar"][1]',
|
96 |
+
'//h2[@class="ia2amp-spacing after-header-date"][1]',
|
97 |
+
'//h2[@class="ia2amp-spacing after-header-author before-header-date"][1]',
|
98 |
+
'//div[@class="ia2amp-spacing after-header-category before-header-h1"][1]',
|
99 |
+
'//div[@class="ia2amp-spacing after-header-h1 before-header-author"]',
|
100 |
+
'//div[@class="ia2amp-spacing after-header-bar before-header-category"]',
|
101 |
+
);
|
102 |
+
|
103 |
+
foreach ($spaceNodes as $currentNode) {
|
104 |
+
$this->assertNotEmpty($testingHeader->query($currentNode));
|
105 |
+
}
|
106 |
+
}
|
107 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/amp-converted.html
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<style amp-custom>html {background-color: rgb(238,238,238);}.ia2amp-header-category {font-family: Helvetica Neue; color: #000000; text-align: LEFT; display: INLINE; text-transform: uppercase; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-header-h1 {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-header-h2 {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue; color: #000000; text-align: LEFT; display: INLINE; text-transform: uppercase; margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-header-bar {background-color: #666666;}.ia2amp-h1 {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-h2 {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-p {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-article a {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; text-decoration: underline; margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-blockquote {font-family: Georgia; color: #000000; text-align: LEFT; display: BLOCK; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 32px 0 46px; border-top-color: rgb(0,0,0); border-right-color: rgb(0,0,0); border-bottom-color: rgb(0,0,0); border-left-color: rgb(0,0,0); border-width: 0 0 0 2px; border-style: solid;}.ia2amp-pullquote {font-family: Georgia; color: #000000; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue; color: #000000; text-align: LEFT; display: INLINE; text-transform: uppercase; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}figcaption h1 {font-family: Helvetica Neue Bold; color: #808080; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}figcaption h2 {font-family: Helvetica Neue; color: #808080; text-align: LEFT; display: INLINE; text-transform: none; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}figcaption cite {font-family: Helvetica Neue; color: #BFBFBF; text-align: LEFT; display: INLINE; text-transform: uppercase; background-color: rgba(255,255,255,0); margin: 0 15px 0 15px; padding: 0 0 0 0; border-width: 0 0 0 0; border-style: solid;}/*Global Styles*/ .ia2amp-header { margin-bottom: 26.4px; } .ia2amp-header-bar { margin: -5px 0 12px 0; height: 55px; font: 0/0 a; } .ia2amp-header-bar:before { content: ' '; display: inline-block; vertical-align: middle; height: 100%; width: 15px; } .ia2amp-header-bar-img-container { display: inline-block; vertical-align: middle; } .ia2amp-header-category { font-size: 10px; line-height: 12px; display: block; font-weight: normal; margin: 18.8px 16.4px 0 16.4px; } .ia2amp-header-h1 { font-size: 30px; line-height: 30px; display: block; font-weight: normal; margin: 13.2px 16.4px 13.2px 16.4px; } .ia2amp-header-h2 { font-size: 16px; line-height: 20px; display: block; font-weight: normal; margin: 0 16.4px 18.8px 16.4px; } .ia2amp-header h3 { font-size: 8px; line-height: 12px; display: block; font-weight: normal; margin: 0 16.4px 0 16.4px; } .ia2amp-p { font-size: 14px; line-height: 20px; display: inline-block; } .ia2amp-blockquote { font-size: 14px; line-height: 20px; padding: 0px 13.2px 0px 18.8px; margin: 18.8px 16.4px 18.8px 16.4px; } /* Custom CSS for wod-gray style goes here */ /* p { background-color: rgb(255,00,00); } */ </style>
|
11 |
+
<link rel="canonical" href="http://blog.wod.expert/very-first-wod/"/>
|
12 |
+
<title>Very First WOD!</title>
|
13 |
+
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
|
14 |
+
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
|
15 |
+
</head>
|
16 |
+
<body class="ia2amp-body">
|
17 |
+
<header class="ia2amp-header">
|
18 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg" width="380" height="215"></amp-img>
|
19 |
+
<div class="ia2amp-header-bar">
|
20 |
+
<div class="ia2amp-header-bar-img-container">
|
21 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/wod-expert-horizontal@033x.png" width="200" height="40"></amp-img>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
<h2 class="ia2amp-header-category">motivational</h2>
|
25 |
+
<div class"ia2amp-separator ia2amp-sep-category ia2amp-sep-h1"></div>
|
26 |
+
<h1 class="ia2amp-header-h1">Very First WOD!</h1>
|
27 |
+
<h3 class="ia2amp-header-author">BY Éverton Rosário</h3>
|
28 |
+
<h3 class="ia2amp-header-date">May 10, 2016</h3>
|
29 |
+
</header>
|
30 |
+
<div class"ia2amp-separator ia2amp-sep-category ia2amp-sep-h1"></div>
|
31 |
+
<article class="ia2amp-article">
|
32 |
+
<p class="ia2amp-p">The first WOD we never forget! Just to be sure we are talking about same thing, WOD stands for “Workout of the Day”. You feel you’re already gone on the warm up session.</p>
|
33 |
+
<blockquote class="ia2amp-blockquote">“WOD stands for Workout of the Day”</blockquote>
|
34 |
+
<p class="ia2amp-p">Most likely you won’t be the only one in that training session, so it might be your first, but you will feel that others on your side are lightyears above and in front of you. You look at those faces, and they seem to be feeling nothing, but you are dying to run 100 meters sprint, unable to do 10 air squats and completely unable to perform 10 pushups. One thing I gotta say to you: you’re not alone!</p>
|
35 |
+
<div class="ia2amp-slideshow">
|
36 |
+
<amp-carousel width="380" height="240">
|
37 |
+
<div class="ia2amp-slideshow-image">
|
38 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail2.jpg" width="380" height="243"></amp-img>
|
39 |
+
</div>
|
40 |
+
<div class="ia2amp-slideshow-image">
|
41 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail3.jpg" width="380" height="252"></amp-img>
|
42 |
+
</div>
|
43 |
+
</amp-carousel>
|
44 |
+
</div>
|
45 |
+
<p class="ia2amp-p">No matter which will be your very first workout. It can be one of the benchmark’s fancy named workouts or any unnamed workout, it doesn’t matter: you will “complete”, or better to say: you will suffer on it even just doing with the lightest weight on the box, using rubber, doing half of the repetitions, but still you will suck on performing it! Don’t feel ashamed of that!</p>
|
46 |
+
<div class="ia2amp-interactive">
|
47 |
+
<amp-iframe src="https://www.youtube.com/embed/P_uDhI-5FqE?start=258&feature=oembed" width="600" height="480" sandbox="allow-scripts allow-same-origin" layout="responsive" frameborder="0"></amp-iframe>
|
48 |
+
</div>
|
49 |
+
<p class="ia2amp-p">Have you made thru it? What was your feeling by the end, even not finishing, or doing half of workout? You will pick one side here: Either you will get addicted and return every day, or you will just drop out. Which one you took?</p>
|
50 |
+
<p class="ia2amp-p">I guess I already know your answer, once you are coming here!</p>
|
51 |
+
<p class="ia2amp-p">Welcome, crossfitter!</p>
|
52 |
+
</article>
|
53 |
+
</body>
|
54 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/amp-example.html
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async=""></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<style amp-custom>h1 { color: #000; }</style>
|
11 |
+
<link rel="canonical" href="http://blog.wod.expert/very-first-wod/"/>
|
12 |
+
<title>Very First WOD!</title>
|
13 |
+
<script custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js" async></script>
|
14 |
+
<script custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js" async></script>
|
15 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Merriweather:400,400italic,700,700italic">
|
16 |
+
<script type="application/ld+json">{"@context":"http:\/\/schema.org","@type":"BlogPosting","mainEntityOfPage":"http:\/\/blog.wod.expert\/very-first-wod\/","publisher":{"@type":"Organization","name":"Wod Expert"},"headline":"Very First WOD!","datePublished":"2016-05-10T18:05:36+00:00","dateModified":"2017-03-17T16:46:07+00:00","author":{"@type":"Person","name":"\u00c9verton Ros\u00e1rio"},"image":{"@type":"ImageObject","url":"http:\/\/blog.wod.expert\/wp-content\/uploads\/2017\/03\/fail1.jpg","width":800,"height":454}}</script>
|
17 |
+
<style amp-custom>.alignright{float:right}.alignleft{float:left}.aligncenter{display:block;margin-left:auto;margin-right:auto}.amp-wp-enforced-sizes{max-width:100%;margin:0 auto}.amp-wp-unknown-size img{object-fit:contain}.amp-wp-content,.amp-wp-title-bar div{margin:0 auto;max-width:525px}html{background:#0a89c0}body{background:#fff;color:#353535;font-family:'Merriweather','Times New Roman',Times,serif;font-weight:300;line-height:1.75em}p,ol,ul,figure{margin:0 0 1em;padding:0}a,a:visited{color:#0a89c0}a:hover,a:active,a:focus{color:#353535}blockquote{color:#353535;background:rgba(127,127,127,.125);border-left:2px solid #0a89c0;margin:8px 0 24px 0;padding:16px}blockquote p:last-child{margin-bottom:0}.amp-wp-meta,.amp-wp-header div,.amp-wp-title,.wp-caption-text,.amp-wp-tax-category,.amp-wp-tax-tag,.amp-wp-comments-link,.amp-wp-footer p,.back-to-top{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen-Sans","Ubuntu","Cantarell","Helvetica Neue",sans-serif}.amp-wp-header{background-color:#0a89c0}.amp-wp-header div{color:#fff;font-size:1em;font-weight:400;margin:0 auto;max-width:calc(840px - 32px);padding:.875em 16px;position:relative}.amp-wp-header a{color:#fff;text-decoration:none}.amp-wp-header .amp-wp-site-icon{background-color:#fff;border:1px solid #fff;border-radius:50%;position:absolute;right:18px;top:10px}.amp-wp-article{color:#353535;font-weight:400;margin:1.5em auto;max-width:840px;overflow-wrap:break-word;word-wrap:break-word}.amp-wp-article-header{align-items:center;align-content:stretch;display:flex;flex-wrap:wrap;justify-content:space-between;margin:1.5em 16px 1.5em}.amp-wp-title{color:#353535;display:block;flex:1 0 100%;font-weight:900;margin:0 0 .625em;width:100%}.amp-wp-meta{color:#696969;display:inline-block;flex:2 1 50%;font-size:.875em;line-height:1.5em;margin:0;padding:0}.amp-wp-article-header .amp-wp-meta:last-of-type{text-align:right}.amp-wp-article-header .amp-wp-meta:first-of-type{text-align:left}.amp-wp-byline amp-img,.amp-wp-byline .amp-wp-author{display:inline-block;vertical-align:middle}.amp-wp-byline amp-img{border:1px solid #0a89c0;border-radius:50%;position:relative;margin-right:6px}.amp-wp-posted-on{text-align:right}.amp-wp-article-featured-image{margin:0 0 1em}.amp-wp-article-featured-image amp-img{margin:0 auto}.amp-wp-article-featured-image.wp-caption .wp-caption-text{margin:0 18px}.amp-wp-article-content{margin:0 16px}.amp-wp-article-content ul,.amp-wp-article-content ol{margin-left:1em}.amp-wp-article-content amp-img{margin:0 auto}.amp-wp-article-content amp-img.alignright{margin:0 0 1em 16px}.amp-wp-article-content amp-img.alignleft{margin:0 16px 1em 0}.wp-caption{padding:0}.wp-caption.alignleft{margin-right:16px}.wp-caption.alignright{margin-left:16px}.wp-caption .wp-caption-text{border-bottom:1px solid #c2c2c2;color:#696969;font-size:.875em;line-height:1.5em;margin:0;padding:.66em 10px .75em}amp-carousel{background:#c2c2c2;margin:0 -16px 1.5em}amp-iframe,amp-youtube,amp-instagram,amp-vine{background:#c2c2c2;margin:0 -16px 1.5em}.amp-wp-article-content amp-carousel amp-img{border:none}amp-carousel>amp-img>img{object-fit:contain}.amp-wp-iframe-placeholder{background:#c2c2c2 url(http://blog.wod.expert/wp-content/plugins/amp/assets/images/placeholder-icon.png) no-repeat center 40%;background-size:48px 48px;min-height:48px}.amp-wp-article-footer .amp-wp-meta{display:block}.amp-wp-tax-category,.amp-wp-tax-tag{color:#696969;font-size:.875em;line-height:1.5em;margin:1.5em 16px}.amp-wp-comments-link{color:#696969;font-size:.875em;line-height:1.5em;text-align:center;margin:2.25em 0 1.5em}.amp-wp-comments-link a{border-style:solid;border-color:#c2c2c2;border-width:1px 1px 2px;border-radius:4px;background-color:transparent;color:#0a89c0;cursor:pointer;display:block;font-size:14px;font-weight:600;line-height:18px;margin:0 auto;max-width:200px;padding:11px 16px;text-decoration:none;width:50%;-webkit-transition:background-color .2s ease;transition:background-color .2s ease}.amp-wp-footer{border-top:1px solid #c2c2c2;margin:calc(1.5em - 1px) 0 0}.amp-wp-footer div{margin:0 auto;max-width:calc(840px - 32px);padding:1.25em 16px 1.25em;position:relative}.amp-wp-footer h2{font-size:1em;line-height:1.375em;margin:0 0 .5em}.amp-wp-footer p{color:#696969;font-size:.8em;line-height:1.5em;margin:0 85px 0 0}.amp-wp-footer a{text-decoration:none}.back-to-top{bottom:1.275em;font-size:.8em;font-weight:600;line-height:2em;position:absolute;right:16px}</style>
|
18 |
+
</head>
|
19 |
+
|
20 |
+
<body class="">
|
21 |
+
|
22 |
+
<header id="#top" class="amp-wp-header">
|
23 |
+
<div>
|
24 |
+
<a href="http://blog.wod.expert">
|
25 |
+
Wod Expert </a>
|
26 |
+
</div>
|
27 |
+
</header>
|
28 |
+
|
29 |
+
<article class="amp-wp-article">
|
30 |
+
|
31 |
+
<header class="amp-wp-article-header">
|
32 |
+
<h1 class="amp-wp-title">Very First WOD!</h1>
|
33 |
+
<div class="amp-wp-meta amp-wp-byline">
|
34 |
+
<amp-img src="http://2.gravatar.com/avatar/ef460d8dfc54e64030b8230184b590b0?s=24&d=mm&r=g" width="24" height="24" layout="fixed"></amp-img>
|
35 |
+
<span class="amp-wp-author author vcard">Éverton Rosário</span>
|
36 |
+
</div>
|
37 |
+
<div class="amp-wp-meta amp-wp-posted-on">
|
38 |
+
<time datetime="2016-05-10T18:05:36+00:00">
|
39 |
+
11 months ago </time>
|
40 |
+
</div>
|
41 |
+
</header>
|
42 |
+
|
43 |
+
<figure class="amp-wp-article-featured-image wp-caption">
|
44 |
+
<amp-img width="525" height="298" src="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg" class="attachment-large size-large wp-post-image amp-wp-enforced-sizes" alt="" srcset="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg 800w, http://blog.wod.expert/wp-content/uploads/2017/03/fail1-300x170.jpg 300w, http://blog.wod.expert/wp-content/uploads/2017/03/fail1-768x436.jpg 768w" sizes="(min-width: 525px) 525px, 100vw"></amp-img> <p class="wp-caption-text">
|
45 |
+
Flickr/crossfitpaleodietfitnessclassess </p>
|
46 |
+
</figure>
|
47 |
+
|
48 |
+
<div class="amp-wp-article-content">
|
49 |
+
<p>The first WOD we never forget! Just to be sure we are talking about same thing, WOD stands for “Workout of the Day”. You feel you’re already gone on the warm up session.</p>
|
50 |
+
<blockquote><p>“WOD stands for Workout of the Day”</p></blockquote>
|
51 |
+
<p>Most likely you won’t be the only one in that training session, so it might be your first, but you will feel that others on your side are lightyears above and in front of you. You look at those faces, and they seem to be feeling nothing, but you are dying to run 100 meters sprint, unable to do 10 air squats and completely unable to perform 10 pushups. One thing I gotta say to you: you’re not alone!</p>
|
52 |
+
<amp-carousel width="600" height="480" type="slides" layout="responsive"><amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail2.jpg" width="507" height="325" layout="responsive"></amp-img><amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail3.jpg" width="600" height="399" layout="responsive"></amp-img></amp-carousel><p>No matter which will be your very first workout. It can be one of the benchmark’s fancy named workouts or any unnamed workout, it doesn’t matter: you will “complete”, or better to say: you will suffer on it even just doing with the lightest weight on the box, using rubber, doing half of the repetitions, but still you will suck on performing it! Don’t feel ashamed of that!</p>
|
53 |
+
<p><amp-youtube data-videoid="P_uDhI-5FqE" layout="responsive" width="525" height="295"></amp-youtube></p>
|
54 |
+
<p>Have you made thru it? What was your feeling by the end, even not finishing, or doing half of workout? You will pick one side here: Either you will get addicted and return every day, or you will just drop out. Which one you took?</p>
|
55 |
+
<p>I guess I already know your answer, once you are coming here!</p>
|
56 |
+
<p>Welcome, crossfitter!</p>
|
57 |
+
</div>
|
58 |
+
|
59 |
+
<footer class="amp-wp-article-footer">
|
60 |
+
<div class="amp-wp-meta amp-wp-tax-category">
|
61 |
+
Categories: <a href="http://blog.wod.expert/category/motivational/" rel="category tag">motivational</a> </div>
|
62 |
+
|
63 |
+
</footer>
|
64 |
+
|
65 |
+
</article>
|
66 |
+
|
67 |
+
<footer class="amp-wp-footer">
|
68 |
+
<div>
|
69 |
+
<h2>Wod Expert</h2>
|
70 |
+
<p>
|
71 |
+
<a href="https://wordpress.org/">Powered by WordPress</a>
|
72 |
+
</p>
|
73 |
+
<a href="#top" class="back-to-top">Back to top</a>
|
74 |
+
</div>
|
75 |
+
</footer>
|
76 |
+
|
77 |
+
|
78 |
+
</body>
|
79 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/fail1.jpg
ADDED
Binary file
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/fb_icon_325x325.png
ADDED
Binary file
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/heart-rate-age-300x182.gif
ADDED
Binary file
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/media-cache/timelapse-final-4x3.mp4
ADDED
Binary file
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test1-amp-converted.html
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<link rel="canonical" href="http://blog.wod.expert/very-first-wod/"/>
|
11 |
+
<style amp-custom>amp-img.ia2amp-header-cover-img {transform: translate(-21px, 0px);}div.ia2amp-cover-image {width: 380px;height: 240px;overflow: hidden;}html {background-color: rgb(238,238,238);}.ia2amp-header-category {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue;text-align: LEFT;text-transform: uppercase;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-header-bar {background-color: rgb(102,102,102);}.ia2amp-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-p {font-family: Georgia;text-align: LEFT;text-transform: none;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-article a {font-family: Georgia;text-decoration: underline;color: rgb(0,0,0);}.ia2amp-blockquote {font-family: Georgia;text-align: LEFT;display: BLOCK;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 32px 0 46px;border-top-color: rgb(0,0,0);border-right-color: rgb(0,0,0);border-bottom-color: rgb(0,0,0);border-left-color: rgb(0,0,0);border-width: 0 0 0 2px;border-style: solid;}.ia2amp-pullquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h1 {font-family: Helvetica Neue Bold;display: INLINE;text-transform: none;background-color: rgb(0,255,255);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h2 {font-family: Helvetica Neue;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-figcaption cite {font-family: Helvetica Neue;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(191,191,191);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-footer {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}/*Global Styles*/ .ia2amp-header-bar { margin: -5px 0 0 0; height: 55px; font: 0/0 a; } .ia2amp-header-bar:before { content: ' '; display: inline-block; vertical-align: middle; height: 100%; width: 16.4px; } .ia2amp-header-bar-img-container { display: inline-block; vertical-align: middle; } .ia2amp-header-category { font-size: 10px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-header-h1 { font-size: 24px; line-height: 30px; display: block; font-weight: normal; } .ia2amp-header-h2 { font-size: 16px; line-height: 20px; display: block; font-weight: normal; } .ia2amp-header h3 { font-size: 8px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-h1, .ia2amp-h2, .ia2amp-h3 { display: block; font-weight: normal; } .ia2amp-h1 { font-size: 19px; line-height: 23px; } .ia2amp-h2 { font-size: 16px; line-height: 20px; } .ia2amp-p { font-size: 14px; line-height: 20px; display: inline-block; } .ia2amp-p a { margin: 0; } .ia2amp-blockquote { font-size: 14px; line-height: 20px; padding: 0px 13.2px 0px 18.8px; } .ia2amp-spacing { display: block; height: 18.8px; margin: 0 16.4px 0 16.4px; } header figure figcaption { display: none; } .ia2amp-figure { margin: 0; } .ia2amp-op-small h1, .ia2amp-op-small h2 { font-size: 10px; display: block; } .ia2amp-op-medium h1, .ia2amp-op-medium h2 { font-size: 14px; display: block; } .ia2amp-op-large h1, .ia2amp-op-large h2 { font-size: 16px; display: block; } .ia2amp-op-extra-large h1, .ia2amp-op-extra-large h2 { font-size: 23px; display: block; } .ia2amp-figcaption cite { font-size: 8px; display: block; } .ia2amp-op-left { text-align: left; } .ia2amp-op-center { text-align: center; } .ia2amp-op-right { text-align: right; } .ia2amp-figure { position: relative; } figcaption.ia2amp-op-vertical-center { position: absolute; z-index: 1000; } .ia2amp-footer { display: block; font-size: 12px; line-height: 17px; } .ia2amp-footer aside p { margin: 0; } .ia2amp-spacing.after-header-bar.before-header-category { height: 18.8px; } .ia2amp-spacing.after-header-category.before-header-h1, .ia2amp-spacing.after-header-h1.before-header-h2 { height: 13.2px; } .ia2amp-spacing.after-h1.before-h2 { height: 13.2px; } .ia2amp-spacing.after-li.before-li { height: 13.2px; } .ia2amp-spacing.after-footer.before-footer { height: 18.8px; } .ia2amp-spacing.after-header-h1.before-header-author, .ia2amp-spacing.after-header-h2.before-header-author { height: 18.8px; } .ia2amp-spacing.after-header-author.before-header-date { height: 0; } .ia2amp-spacing.after-header-date.before-h1, .ia2amp-spacing.after-header-date.before-h2, .ia2amp-spacing.after-header-date.before-p { height: 26.4px; } .ia2amp-spacing.after-h1.before-p, .ia2amp-spacing.after-h2.before-p, .ia2amp-spacing.after-h3.before-p { height: 18.8px; } .ia2amp-spacing.after-blockquote.before-p { height: 18.8px; } .ia2amp-spacing.after-slideshow, .ia2amp-spacing.before-slideshow, .ia2amp-spacing.after-interactive, .ia2amp-spacing.before-interactive, .ia2amp-spacing.after-image, .ia2amp-spacing.before-image, .ia2amp-spacing.after-figcaption-small, .ia2amp-spacing.after-figcaption-medium, .ia2amp-spacing.after-figcaption-large, .ia2amp-spacing.after-figcaption-extra-large { height: 26.4px; } </style>
|
12 |
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"http://blog.wod.expert/very-first-wod/","headline":"Very First WOD!","datePublished":"2016-05-10T18:05:36+00:00","description":"The first WOD we never forget! Just to be sure we are talking about same thing, WOD stands for \u201cWorkout of the Day\u201d. \u00a0You feel you\u2019re already gone on the warm up session.","dateModified":"2017-03-17T16:46:07+00:00","author":{"@type":"Person","name":"\u00c9verton Ros\u00e1rio"},"image":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg","width":800,"height":454},"publisher":{"@type":"Organization","name":"WOD Expert","logo":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png","width":600,"height":60}}}</script>
|
13 |
+
<title>Very First WOD!</title>
|
14 |
+
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
|
15 |
+
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
|
16 |
+
</head>
|
17 |
+
<body class="ia2amp-body">
|
18 |
+
<header class="ia2amp-header">
|
19 |
+
<div class="ia2amp-cover-image">
|
20 |
+
<figure class="ia2amp-figure">
|
21 |
+
<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg" width="422" height="240"></amp-img>
|
22 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">Flickr/crossfitpaleodietfitnessclassess</figcaption>
|
23 |
+
</figure>
|
24 |
+
</div>
|
25 |
+
<div class="ia2amp-header-bar">
|
26 |
+
<div class="ia2amp-header-bar-img-container">
|
27 |
+
<amp-img src="https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8" width="223" height="44"></amp-img>
|
28 |
+
</div>
|
29 |
+
</div>
|
30 |
+
<div class="ia2amp-spacing after-header-bar before-header-category"></div>
|
31 |
+
<h2 class="ia2amp-header-category">motivational</h2>
|
32 |
+
<div class="ia2amp-spacing after-header-category before-header-h1"></div>
|
33 |
+
<h1 class="ia2amp-header-h1">Very First WOD!</h1>
|
34 |
+
<div class="ia2amp-spacing after-header-h1 before-header-h2"></div>
|
35 |
+
<h2 class="ia2amp-header-h2">It's great to see you here</h2>
|
36 |
+
<div class="ia2amp-spacing after-header-h2 before-header-author"></div>
|
37 |
+
<h3 class="ia2amp-header-author">By Éverton Rosário</h3>
|
38 |
+
<div class="ia2amp-spacing after-header-author before-header-date"></div>
|
39 |
+
<h3 class="ia2amp-header-date">May 10, 2016</h3>
|
40 |
+
<div class="ia2amp-spacing after-header-date before-p"></div>
|
41 |
+
</header>
|
42 |
+
<article class="ia2amp-article">
|
43 |
+
<p class="ia2amp-p">The first <em>WOD</em> we never forget! Just to be sure we are talking about same thing, WOD stands for “Workout of the Day”. You feel you’re already gone on the warm up session.</p>
|
44 |
+
<div class="ia2amp-spacing after-p before-blockquote"></div>
|
45 |
+
<blockquote class="ia2amp-blockquote">“WOD stands for Workout of the Day”</blockquote>
|
46 |
+
<div class="ia2amp-spacing after-blockquote before-p"></div>
|
47 |
+
<p class="ia2amp-p">Most likely you won’t be the only one in that training session, so it might be your first, but you will feel that others on your side are lightyears above and in front of you. You look at those faces, and they seem to be feeling nothing, but you are dying to run 100 meters sprint, unable to do 10 air squats and completely unable to perform 10 pushups. One thing I gotta say to you: you’re not alone!</p>
|
48 |
+
<div class="ia2amp-spacing after-p before-slideshow"></div>
|
49 |
+
<div class="ia2amp-slideshow">
|
50 |
+
<amp-carousel width="380" height="240">
|
51 |
+
<div class="ia2amp-slideshow-image">
|
52 |
+
<figure class="ia2amp-figure">
|
53 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail2.jpg" width="380" height="240"></amp-img>
|
54 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>
|
55 |
+
twopalswiththoughts
|
56 |
+
</h1></figcaption>
|
57 |
+
</figure>
|
58 |
+
</div>
|
59 |
+
<div class="ia2amp-slideshow-image">
|
60 |
+
<figure class="ia2amp-figure">
|
61 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail3.jpg" width="380" height="240"></amp-img>
|
62 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>
|
63 |
+
Flickr: crossfitpaleodietfitnessclasses
|
64 |
+
</h1></figcaption>
|
65 |
+
</figure>
|
66 |
+
</div>
|
67 |
+
</amp-carousel>
|
68 |
+
</div>
|
69 |
+
<div class="ia2amp-spacing after-slideshow before-p"></div>
|
70 |
+
<p class="ia2amp-p">No matter which will be your very first workout. It can be one of the benchmark’s fancy named workouts or any unnamed workout, it doesn’t matter: you will “complete”, or better to say: you will suffer on it even just doing with the lightest weight on the box, using rubber, doing half of the repetitions, but still you will suck on performing it! Don’t feel ashamed of that!</p>
|
71 |
+
<div class="ia2amp-spacing after-p before-interactive"></div>
|
72 |
+
<div class="ia2amp-interactive">
|
73 |
+
<amp-iframe src="https://www.youtube.com/embed/P_uDhI-5FqE?start=258&feature=oembed" width="380" height="240" sandbox="allow-scripts allow-same-origin" layout="responsive" frameborder="0"></amp-iframe>
|
74 |
+
</div>
|
75 |
+
<div class="ia2amp-spacing after-interactive before-p"></div>
|
76 |
+
<p class="ia2amp-p">Have you made thru it? What was your feeling by the end, even not finishing, or doing half of workout? You will pick one side here: Either you will get addicted and return every day, or you will just drop out. Which one you took?</p>
|
77 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
78 |
+
<p class="ia2amp-p">I guess I already know your answer, once you are coming here!</p>
|
79 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
80 |
+
<p class="ia2amp-p">Welcome, crossfitter!</p>
|
81 |
+
<div class="ia2amp-spacing after-p"></div>
|
82 |
+
<footer class="ia2amp-footer">
|
83 |
+
<aside>
|
84 |
+
<p>WOD Expert</p>
|
85 |
+
</aside>
|
86 |
+
<small>© 2017 WOD Expert</small>
|
87 |
+
</footer>
|
88 |
+
</article>
|
89 |
+
</body>
|
90 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test1-instant-article.html
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head>
|
3 |
+
<link rel="canonical" href="http://blog.wod.expert/very-first-wod/"/>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
6 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
7 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
8 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
9 |
+
<meta property="op:markup_version" content="v1.0"/>
|
10 |
+
<meta property="fb:article_style" content="wod-gray"/>
|
11 |
+
</head>
|
12 |
+
<body>
|
13 |
+
<article>
|
14 |
+
<header>
|
15 |
+
<figure>
|
16 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail1.jpg"/>
|
17 |
+
<figcaption>Flickr/crossfitpaleodietfitnessclassess</figcaption>
|
18 |
+
</figure>
|
19 |
+
<h1>Very First WOD!</h1>
|
20 |
+
<h2>It's great to see you here</h2>
|
21 |
+
<time class="op-published" datetime="2016-05-10T18:05:36+00:00">May 10th, 6:05pm</time>
|
22 |
+
<time class="op-modified" datetime="2017-03-17T16:46:07+00:00">March 17th, 4:46pm</time>
|
23 |
+
<address><a>Éverton Rosário</a></address>
|
24 |
+
<h3 class="op-kicker">motivational</h3>
|
25 |
+
</header>
|
26 |
+
<p>The first <em>WOD</em> we never forget! Just to be sure we are talking about same thing, WOD stands for “Workout of the Day”. You feel you’re already gone on the warm up session.</p>
|
27 |
+
<blockquote>“WOD stands for Workout of the Day”</blockquote>
|
28 |
+
<p>Most likely you won’t be the only one in that training session, so it might be your first, but you will feel that others on your side are lightyears above and in front of you. You look at those faces, and they seem to be feeling nothing, but you are dying to run 100 meters sprint, unable to do 10 air squats and completely unable to perform 10 pushups. One thing I gotta say to you: you’re not alone!</p>
|
29 |
+
<figure class="op-slideshow">
|
30 |
+
<figure>
|
31 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail2.jpg"/>
|
32 |
+
<figcaption>
|
33 |
+
twopalswiththoughts
|
34 |
+
</figcaption>
|
35 |
+
</figure>
|
36 |
+
<figure>
|
37 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/fail3.jpg"/>
|
38 |
+
<figcaption>
|
39 |
+
Flickr: crossfitpaleodietfitnessclasses
|
40 |
+
</figcaption>
|
41 |
+
</figure>
|
42 |
+
</figure>
|
43 |
+
<p>No matter which will be your very first workout. It can be one of the benchmark’s fancy named workouts or any unnamed workout, it doesn’t matter: you will “complete”, or better to say: you will suffer on it even just doing with the lightest weight on the box, using rubber, doing half of the repetitions, but still you will suck on performing it! Don’t feel ashamed of that!</p>
|
44 |
+
<figure class="op-interactive">
|
45 |
+
<iframe src="https://www.youtube.com/embed/P_uDhI-5FqE?start=258&feature=oembed" class="no-margin" width="525" height="295"></iframe>
|
46 |
+
</figure>
|
47 |
+
<p>Have you made thru it? What was your feeling by the end, even not finishing, or doing half of workout? You will pick one side here: Either you will get addicted and return every day, or you will just drop out. Which one you took?</p>
|
48 |
+
<p>I guess I already know your answer, once you are coming here!</p>
|
49 |
+
<p>Welcome, crossfitter!</p>
|
50 |
+
<footer>
|
51 |
+
<aside>
|
52 |
+
<p>WOD Expert</p>
|
53 |
+
</aside>
|
54 |
+
<small>© 2017 WOD Expert</small>
|
55 |
+
</footer>
|
56 |
+
</article>
|
57 |
+
</body>
|
58 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test2-amp-converted.html
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<link rel="canonical" href="http://blog.wod.expert/break-your-reps-before-you-die/"/>
|
11 |
+
<style amp-custom>amp-img.ia2amp-header-cover-img {transform: translate(0px, 0px);}div.ia2amp-cover-image {width: 380px;height: 240px;overflow: hidden;}html {background-color: rgb(238,238,238);}.ia2amp-header-category {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue;text-align: LEFT;text-transform: uppercase;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-header-bar {background-color: rgb(102,102,102);}.ia2amp-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-p {font-family: Georgia;text-align: LEFT;text-transform: none;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-article a {font-family: Georgia;text-decoration: underline;color: rgb(0,0,0);}.ia2amp-blockquote {font-family: Georgia;text-align: LEFT;display: BLOCK;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 32px 0 46px;border-top-color: rgb(0,0,0);border-right-color: rgb(0,0,0);border-bottom-color: rgb(0,0,0);border-left-color: rgb(0,0,0);border-width: 0 0 0 2px;border-style: solid;}.ia2amp-pullquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h1 {font-family: Helvetica Neue Bold;display: INLINE;text-transform: none;background-color: rgb(0,255,255);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h2 {font-family: Helvetica Neue;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-figcaption cite {font-family: Helvetica Neue;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(191,191,191);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-footer {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}/*Global Styles*/ .ia2amp-header-bar { margin: -5px 0 0 0; height: 55px; font: 0/0 a; } .ia2amp-header-bar:before { content: ' '; display: inline-block; vertical-align: middle; height: 100%; width: 16.4px; } .ia2amp-header-bar-img-container { display: inline-block; vertical-align: middle; } .ia2amp-header-category { font-size: 10px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-header-h1 { font-size: 24px; line-height: 30px; display: block; font-weight: normal; } .ia2amp-header-h2 { font-size: 16px; line-height: 20px; display: block; font-weight: normal; } .ia2amp-header h3 { font-size: 8px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-h1, .ia2amp-h2, .ia2amp-h3 { display: block; font-weight: normal; } .ia2amp-h1 { font-size: 19px; line-height: 23px; } .ia2amp-h2 { font-size: 16px; line-height: 20px; } .ia2amp-p { font-size: 14px; line-height: 20px; display: inline-block; } .ia2amp-p a { margin: 0; } .ia2amp-blockquote { font-size: 14px; line-height: 20px; padding: 0px 13.2px 0px 18.8px; } .ia2amp-spacing { display: block; height: 18.8px; margin: 0 16.4px 0 16.4px; } header figure figcaption { display: none; } .ia2amp-figure { margin: 0; } .ia2amp-op-small h1, .ia2amp-op-small h2 { font-size: 10px; display: block; } .ia2amp-op-medium h1, .ia2amp-op-medium h2 { font-size: 14px; display: block; } .ia2amp-op-large h1, .ia2amp-op-large h2 { font-size: 16px; display: block; } .ia2amp-op-extra-large h1, .ia2amp-op-extra-large h2 { font-size: 23px; display: block; } .ia2amp-figcaption cite { font-size: 8px; display: block; } .ia2amp-op-left { text-align: left; } .ia2amp-op-center { text-align: center; } .ia2amp-op-right { text-align: right; } .ia2amp-figure { position: relative; } figcaption.ia2amp-op-vertical-center { position: absolute; z-index: 1000; } .ia2amp-footer { display: block; font-size: 12px; line-height: 17px; } .ia2amp-footer aside p { margin: 0; } .ia2amp-spacing.after-header-bar.before-header-category { height: 18.8px; } .ia2amp-spacing.after-header-category.before-header-h1, .ia2amp-spacing.after-header-h1.before-header-h2 { height: 13.2px; } .ia2amp-spacing.after-h1.before-h2 { height: 13.2px; } .ia2amp-spacing.after-li.before-li { height: 13.2px; } .ia2amp-spacing.after-footer.before-footer { height: 18.8px; } .ia2amp-spacing.after-header-h1.before-header-author, .ia2amp-spacing.after-header-h2.before-header-author { height: 18.8px; } .ia2amp-spacing.after-header-author.before-header-date { height: 0; } .ia2amp-spacing.after-header-date.before-h1, .ia2amp-spacing.after-header-date.before-h2, .ia2amp-spacing.after-header-date.before-p { height: 26.4px; } .ia2amp-spacing.after-h1.before-p, .ia2amp-spacing.after-h2.before-p, .ia2amp-spacing.after-h3.before-p { height: 18.8px; } .ia2amp-spacing.after-blockquote.before-p { height: 18.8px; } .ia2amp-spacing.after-slideshow, .ia2amp-spacing.before-slideshow, .ia2amp-spacing.after-interactive, .ia2amp-spacing.before-interactive, .ia2amp-spacing.after-image, .ia2amp-spacing.before-image, .ia2amp-spacing.after-figcaption-small, .ia2amp-spacing.after-figcaption-medium, .ia2amp-spacing.after-figcaption-large, .ia2amp-spacing.after-figcaption-extra-large { height: 26.4px; } </style>
|
12 |
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"http://blog.wod.expert/break-your-reps-before-you-die/","headline":"Break your reps, before you die!","datePublished":"2016-05-17T12:47:46+00:00","description":"Having a good strategy to tackle the series in WODs are fundamental to achieve the best result given your particular physical condition. Comparing yourself to the top athletes, or trying to use their strategy probably won\u2019t work well, unless you are a top athlete! By good strategy I mean planing basically how fast you will perform your movements and how you will play your pauses. There is no better person in the world to know you better than yourself.","dateModified":"2017-03-17T16:45:18+00:00","author":{"@type":"Person","name":"\u00c9verton Ros\u00e1rio"},"image":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/03/wod-break.jpg","width":380,"height":240},"publisher":{"@type":"Organization","name":"WOD Expert","logo":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png","width":600,"height":60}}}</script>
|
13 |
+
<title>Break your reps, before you die!</title>
|
14 |
+
</head>
|
15 |
+
<body class="ia2amp-body">
|
16 |
+
<header class="ia2amp-header">
|
17 |
+
<div class="ia2amp-cover-image">
|
18 |
+
<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2017/03/wod-break.jpg" width="380" height="240"></amp-img>
|
19 |
+
</div>
|
20 |
+
<div class="ia2amp-header-bar">
|
21 |
+
<div class="ia2amp-header-bar-img-container">
|
22 |
+
<amp-img src="https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8" width="223" height="44"></amp-img>
|
23 |
+
</div>
|
24 |
+
</div>
|
25 |
+
<div class="ia2amp-spacing after-header-bar before-header-category"></div>
|
26 |
+
<h2 class="ia2amp-header-category">exercise</h2>
|
27 |
+
<div class="ia2amp-spacing after-header-category before-header-h1"></div>
|
28 |
+
<h1 class="ia2amp-header-h1">Break your reps, before you die!</h1>
|
29 |
+
<div class="ia2amp-spacing after-header-h1 before-header-author"></div>
|
30 |
+
<h3 class="ia2amp-header-author">By Éverton Rosário</h3>
|
31 |
+
<div class="ia2amp-spacing after-header-author before-header-date"></div>
|
32 |
+
<h3 class="ia2amp-header-date">May 17, 2016</h3>
|
33 |
+
<div class="ia2amp-spacing after-header-date before-p"></div>
|
34 |
+
</header>
|
35 |
+
<article class="ia2amp-article">
|
36 |
+
<p class="ia2amp-p">Having a good strategy to tackle the series in WODs are fundamental to achieve the best result given your particular physical condition. Comparing yourself to the top athletes, or trying to use their strategy probably won’t work well, unless you are a top athlete! By good strategy I mean planing basically how fast you will perform your movements and how you will play your pauses. There is no better person in the world to know you better than yourself.</p>
|
37 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
38 |
+
<p class="ia2amp-p">But firstly you gotta understand better how your body responds to exercise and how you gotta plan given your body symptoms.</p>
|
39 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
40 |
+
<p class="ia2amp-p">One of the three main areas to observe here are: heart rate, breathing and muscle energy.</p>
|
41 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
42 |
+
<h2 class="ia2amp-h2">Heart Rate</h2>
|
43 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
44 |
+
<p class="ia2amp-p">Heart rate is commonly measured in beats per minute and it measures how fast your heart is pumping blood to your body. When performing your exercises in the WOD your body is moving lots of muscles, so heart needs to keep oxygen level to your muscles, so it keeps working well.</p>
|
45 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
46 |
+
<p class="ia2amp-p">Few characteristics influence how efficient you heart works, as more prepared you are, more efficient you heart works. Good to mention that you heart is also a muscle that by exercising in your WODs will also improve your heart condition. The heart beat at rest is one of good indicators on how well you are prepared, as top athletes have rest heart rate slightly slower than regular people.</p>
|
47 |
+
<div class="ia2amp-spacing after-p before-figcaption-small"></div>
|
48 |
+
<div class="ia2amp-image">
|
49 |
+
<figure class="ia2amp-figure">
|
50 |
+
<amp-img layout="responsive" src="http://blog.wod.expert/wp-content/uploads/2017/03/heart-rate-age-300x182.gif" width="380" height="240"></amp-img>
|
51 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">The heart rate per age</figcaption>
|
52 |
+
</figure>
|
53 |
+
</div>
|
54 |
+
<div class="ia2amp-spacing after-figcaption-small before-p"></div>
|
55 |
+
<p class="ia2amp-p">Warning about heart rate is that, if in only few reps you get your heart rate close to maximum and this is going to be a long series. Example: your heart rate skyrocket getting close to the max at your age with only 5 reps, but the workout is about performing 50 reps, so you seriously need to review and lower the weights you will use.</p>
|
56 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
57 |
+
<p class="ia2amp-p">During training you gotta keep close attention to your heart rate, and if you are getting into your red zone, you definitely will need a pause. But pause before you get there, otherwise it will be slower to recover once you are close to the max.</p>
|
58 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
59 |
+
<p class="ia2amp-p">Using heart monitors will be a good aid by checking how your heart rating changes during your workout. As higher your heart goes, higher your breathing frequency goes</p>
|
60 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
61 |
+
<h2 class="ia2amp-h2">Breathing</h2>
|
62 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
63 |
+
<p class="ia2amp-p">During your series you will feel and observe yourself catching your breath in between the reps. This happens once you get closer to the max heart beat and you need to keep your oxygen levels in your body good enough so you keep contracting your muscles.</p>
|
64 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
65 |
+
<p class="ia2amp-p">When you reach that respiration frequency, where it is too fast inhaling and exhaling, you will waste too much time catching your breath. Plan to break your workout few reps before you reach that level. This will make your recovering faster.</p>
|
66 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
67 |
+
<p class="ia2amp-p">Once you reach this situation of inhale exhale to fast, and probably this will happen frequently, enforce yourself to exhale with more power, this will make your lungs go empty and inhaling more fresh air, thus, being more efficient about taking oxygen to your body, then your heart beat will slow down. Respiration frequency is really attached to your heart rate, and the influence occurs in both ways: heart beating influencing breathing frequency and vice-versa.</p>
|
68 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
69 |
+
<h2 class="ia2amp-h2">Muscle energy</h2>
|
70 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
71 |
+
<p class="ia2amp-p">By muscle energy I mean how ready your muscle is to perform one more contraction, with what power. To lift a weight or to perform the exercises during your WOD you will have lots of muscle contractions. Going deeper and understand what it takes for a muscle to contract, it will basically need to have your celular respiration and ATP working well. Just to remember it requires glucose, oxygen and strong muscle fibers. Once all requirements are met, you will successfully contract that muscle, thus executing the rep. Those three are fundamental.</p>
|
72 |
+
<div class="ia2amp-spacing after-p before-image"></div>
|
73 |
+
<div class="ia2amp-image">
|
74 |
+
<amp-img layout="responsive" src="http://blog.wod.expert/wp-content/uploads/2017/03/muscles-300x255.jpg" width="380" height="240"></amp-img>
|
75 |
+
</div>
|
76 |
+
<div class="ia2amp-spacing after-image before-p"></div>
|
77 |
+
<p class="ia2amp-p">Glucose -&gt; connected to your nutrition quality and how well you are eating before your workouts</p>
|
78 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
79 |
+
<p class="ia2amp-p">Oxygen -&gt; How efficiency your breathing is and how well your heart rate is pumping the oxygen thru your blood.</p>
|
80 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
81 |
+
<p class="ia2amp-p">Strong muscle fibers -&gt; That weight shouldn’t be heavier than your max for that movement.</p>
|
82 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
83 |
+
<p class="ia2amp-p">As you exercise during your workout, you will feel your breathing go faster, and this is something you should try to avoid while contracting your muscles, because once you are contracting your muscles without the proper oxygen levels, you start the glycolysis process, which generates lactic acid causing your muscle fatigue.</p>
|
84 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
85 |
+
<h2 class="ia2amp-h2">All connected</h2>
|
86 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
87 |
+
<p class="ia2amp-p">As we can see, the 3 are all deeply connected. Getting more fitness prepared includes being stronger, good VO2 max and faster heart rating recovering. Being stronger will play one of the key differences here, since you will need less effort to perform the same exercise, thus keeping lower heart rate and breathing frequency. Once maybe you are not really strong you gotta keep checking your heart beat and breathing so you can stop before you get to the dying zone near your maximum. Once you get to your max, it is slower to recover.</p>
|
88 |
+
<div class="ia2amp-spacing after-p before-image"></div>
|
89 |
+
<div class="ia2amp-image">
|
90 |
+
<amp-img layout="responsive" src="http://blog.wod.expert/wp-content/uploads/2017/03/running-fatigue-277x300.jpg" width="380" height="240"></amp-img>
|
91 |
+
</div>
|
92 |
+
<div class="ia2amp-spacing after-image"></div>
|
93 |
+
</article>
|
94 |
+
</body>
|
95 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test2-instant-article.html
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<link rel="canonical" href="http://blog.wod.expert/break-your-reps-before-you-die/" />
|
5 |
+
<meta charset="utf-8" />
|
6 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
7 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
8 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
9 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
10 |
+
<meta property="op:markup_version" content="v1.0"/>
|
11 |
+
<meta property="fb:article_style" content="wod-gray"/>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<article>
|
15 |
+
<header>
|
16 |
+
<figure>
|
17 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/wod-break.jpg" />
|
18 |
+
</figure>
|
19 |
+
<h1>Break your reps, before you die!</h1>
|
20 |
+
<time class="op-published" datetime="2016-05-17T12:47:46+00:00">May 17th, 12:47pm</time>
|
21 |
+
<time class="op-modified" datetime="2017-03-17T16:45:18+00:00">March 17th, 4:45pm</time>
|
22 |
+
<address>
|
23 |
+
<a>Éverton Rosário</a>
|
24 |
+
</address>
|
25 |
+
<h3 class="op-kicker">exercise</h3>
|
26 |
+
</header>
|
27 |
+
<p>Having a good strategy to tackle the series in WODs are fundamental to achieve the best result given your particular physical condition. Comparing yourself to the top athletes, or trying to use their strategy probably won’t work well, unless you are a top athlete! By good strategy I mean planing basically how fast you will perform your movements and how you will play your pauses. There is no better person in the world to know you better than yourself.</p>
|
28 |
+
<p>But firstly you gotta understand better how your body responds to exercise and how you gotta plan given your body symptoms.</p>
|
29 |
+
<p>One of the three main areas to observe here are: heart rate, breathing and muscle energy.</p>
|
30 |
+
<h2>Heart Rate</h2>
|
31 |
+
<p>Heart rate is commonly measured in beats per minute and it measures how fast your heart is pumping blood to your body. When performing your exercises in the WOD your body is moving lots of muscles, so heart needs to keep oxygen level to your muscles, so it keeps working well.</p>
|
32 |
+
<p>Few characteristics influence how efficient you heart works, as more prepared you are, more efficient you heart works. Good to mention that you heart is also a muscle that by exercising in your WODs will also improve your heart condition. The heart beat at rest is one of good indicators on how well you are prepared, as top athletes have rest heart rate slightly slower than regular people.</p>
|
33 |
+
<figure>
|
34 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/heart-rate-age-300x182.gif" />
|
35 |
+
<figcaption>The heart rate per age</figcaption>
|
36 |
+
</figure>
|
37 |
+
<p>Warning about heart rate is that, if in only few reps you get your heart rate close to maximum and this is going to be a long series. Example: your heart rate skyrocket getting close to the max at your age with only 5 reps, but the workout is about performing 50 reps, so you seriously need to review and lower the weights you will use.</p>
|
38 |
+
<p>During training you gotta keep close attention to your heart rate, and if you are getting into your red zone, you definitely will need a pause. But pause before you get there, otherwise it will be slower to recover once you are close to the max.</p>
|
39 |
+
<p>Using heart monitors will be a good aid by checking how your heart rating changes during your workout. As higher your heart goes, higher your breathing frequency goes</p>
|
40 |
+
<h2>Breathing</h2>
|
41 |
+
<p>During your series you will feel and observe yourself catching your breath in between the reps. This happens once you get closer to the max heart beat and you need to keep your oxygen levels in your body good enough so you keep contracting your muscles.</p>
|
42 |
+
<p>When you reach that respiration frequency, where it is too fast inhaling and exhaling, you will waste too much time catching your breath. Plan to break your workout few reps before you reach that level. This will make your recovering faster.</p>
|
43 |
+
<p>Once you reach this situation of inhale exhale to fast, and probably this will happen frequently, enforce yourself to exhale with more power, this will make your lungs go empty and inhaling more fresh air, thus, being more efficient about taking oxygen to your body, then your heart beat will slow down. Respiration frequency is really attached to your heart rate, and the influence occurs in both ways: heart beating influencing breathing frequency and vice-versa.</p>
|
44 |
+
<h2>Muscle energy</h2>
|
45 |
+
<p>By muscle energy I mean how ready your muscle is to perform one more contraction, with what power. To lift a weight or to perform the exercises during your WOD you will have lots of muscle contractions. Going deeper and understand what it takes for a muscle to contract, it will basically need to have your celular respiration and ATP working well. Just to remember it requires glucose, oxygen and strong muscle fibers. Once all requirements are met, you will successfully contract that muscle, thus executing the rep. Those three are fundamental.</p>
|
46 |
+
<figure>
|
47 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/muscles-300x255.jpg" />
|
48 |
+
</figure>
|
49 |
+
<p>Glucose -&gt; connected to your nutrition quality and how well you are eating before your workouts</p>
|
50 |
+
<p>Oxygen -&gt; How efficiency your breathing is and how well your heart rate is pumping the oxygen thru your blood.</p>
|
51 |
+
<p>Strong muscle fibers -&gt; That weight shouldn’t be heavier than your max for that movement.</p>
|
52 |
+
<p>As you exercise during your workout, you will feel your breathing go faster, and this is something you should try to avoid while contracting your muscles, because once you are contracting your muscles without the proper oxygen levels, you start the glycolysis process, which generates lactic acid causing your muscle fatigue.</p>
|
53 |
+
<h2>All connected</h2>
|
54 |
+
<p>As we can see, the 3 are all deeply connected. Getting more fitness prepared includes being stronger, good VO2 max and faster heart rating recovering. Being stronger will play one of the key differences here, since you will need less effort to perform the same exercise, thus keeping lower heart rate and breathing frequency. Once maybe you are not really strong you gotta keep checking your heart beat and breathing so you can stop before you get to the dying zone near your maximum. Once you get to your max, it is slower to recover.</p>
|
55 |
+
<figure>
|
56 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/running-fatigue-277x300.jpg" />
|
57 |
+
</figure>
|
58 |
+
</article>
|
59 |
+
</body>
|
60 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test3-amp-converted.html
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<link rel="canonical" href="http://blog.wod.expert/open-2017/"/>
|
11 |
+
<style amp-custom>amp-img.ia2amp-header-cover-img {transform: translate(0px, 0px);}div.ia2amp-cover-image {width: 380px;height: 240px;overflow: hidden;}html {background-color: rgb(238,238,238);}.ia2amp-header-category {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue;text-align: LEFT;text-transform: uppercase;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-header-bar {background-color: rgb(102,102,102);}.ia2amp-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-p {font-family: Georgia;text-align: LEFT;text-transform: none;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-article a {font-family: Georgia;text-decoration: underline;color: rgb(0,0,0);}.ia2amp-blockquote {font-family: Georgia;text-align: LEFT;display: BLOCK;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 32px 0 46px;border-top-color: rgb(0,0,0);border-right-color: rgb(0,0,0);border-bottom-color: rgb(0,0,0);border-left-color: rgb(0,0,0);border-width: 0 0 0 2px;border-style: solid;}.ia2amp-pullquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h1 {font-family: Helvetica Neue Bold;display: INLINE;text-transform: none;background-color: rgb(0,255,255);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h2 {font-family: Helvetica Neue;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-figcaption cite {font-family: Helvetica Neue;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(191,191,191);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-footer {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}/*Global Styles*/ .ia2amp-header-bar { margin: -5px 0 0 0; height: 55px; font: 0/0 a; } .ia2amp-header-bar:before { content: ' '; display: inline-block; vertical-align: middle; height: 100%; width: 16.4px; } .ia2amp-header-bar-img-container { display: inline-block; vertical-align: middle; } .ia2amp-header-category { font-size: 10px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-header-h1 { font-size: 24px; line-height: 30px; display: block; font-weight: normal; } .ia2amp-header-h2 { font-size: 16px; line-height: 20px; display: block; font-weight: normal; } .ia2amp-header h3 { font-size: 8px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-h1, .ia2amp-h2, .ia2amp-h3 { display: block; font-weight: normal; } .ia2amp-h1 { font-size: 19px; line-height: 23px; } .ia2amp-h2 { font-size: 16px; line-height: 20px; } .ia2amp-p { font-size: 14px; line-height: 20px; display: inline-block; } .ia2amp-p a { margin: 0; } .ia2amp-blockquote { font-size: 14px; line-height: 20px; padding: 0px 13.2px 0px 18.8px; } .ia2amp-spacing { display: block; height: 18.8px; margin: 0 16.4px 0 16.4px; } header figure figcaption { display: none; } .ia2amp-figure { margin: 0; } .ia2amp-op-small h1, .ia2amp-op-small h2 { font-size: 10px; display: block; } .ia2amp-op-medium h1, .ia2amp-op-medium h2 { font-size: 14px; display: block; } .ia2amp-op-large h1, .ia2amp-op-large h2 { font-size: 16px; display: block; } .ia2amp-op-extra-large h1, .ia2amp-op-extra-large h2 { font-size: 23px; display: block; } .ia2amp-figcaption cite { font-size: 8px; display: block; } .ia2amp-op-left { text-align: left; } .ia2amp-op-center { text-align: center; } .ia2amp-op-right { text-align: right; } .ia2amp-figure { position: relative; } figcaption.ia2amp-op-vertical-center { position: absolute; z-index: 1000; } .ia2amp-footer { display: block; font-size: 12px; line-height: 17px; } .ia2amp-footer aside p { margin: 0; } .ia2amp-spacing.after-header-bar.before-header-category { height: 18.8px; } .ia2amp-spacing.after-header-category.before-header-h1, .ia2amp-spacing.after-header-h1.before-header-h2 { height: 13.2px; } .ia2amp-spacing.after-h1.before-h2 { height: 13.2px; } .ia2amp-spacing.after-li.before-li { height: 13.2px; } .ia2amp-spacing.after-footer.before-footer { height: 18.8px; } .ia2amp-spacing.after-header-h1.before-header-author, .ia2amp-spacing.after-header-h2.before-header-author { height: 18.8px; } .ia2amp-spacing.after-header-author.before-header-date { height: 0; } .ia2amp-spacing.after-header-date.before-h1, .ia2amp-spacing.after-header-date.before-h2, .ia2amp-spacing.after-header-date.before-p { height: 26.4px; } .ia2amp-spacing.after-h1.before-p, .ia2amp-spacing.after-h2.before-p, .ia2amp-spacing.after-h3.before-p { height: 18.8px; } .ia2amp-spacing.after-blockquote.before-p { height: 18.8px; } .ia2amp-spacing.after-slideshow, .ia2amp-spacing.before-slideshow, .ia2amp-spacing.after-interactive, .ia2amp-spacing.before-interactive, .ia2amp-spacing.after-image, .ia2amp-spacing.before-image, .ia2amp-spacing.after-figcaption-small, .ia2amp-spacing.after-figcaption-medium, .ia2amp-spacing.after-figcaption-large, .ia2amp-spacing.after-figcaption-extra-large { height: 26.4px; } </style>
|
12 |
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"http://blog.wod.expert/open-2017/","headline":"Open 2017","datePublished":"2017-02-24T22:30:40+00:00","description":"\n The\n CrossFit Games\n are coming and the Open is the very first step for anyone try to fight for a spot on the regionals, then on the games! Pretty much almost all other sport modalities have a pre-selected group of athletes, teams or league affiliates. Sometimes the path is simply impossible: Try to get your football team to play on the NFL, it will be simply something near impossible, no matter how good that team is. Of course if your team is not part of the League you simply can\u2019t. Not going into the merits of having a team on NFL, since this is not the point here.\n ","dateModified":"2017-04-05T17:57:54+00:00","author":{"@type":"Person","name":"\u00c9verton Ros\u00e1rio"},"image":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/02/CrossFitGamesLogo-wide.png","width":380,"height":240},"publisher":{"@type":"Organization","name":"WOD Expert","logo":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png","width":600,"height":60}}}</script>
|
13 |
+
<title>Open 2017</title>
|
14 |
+
<script async custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.js"></script>
|
15 |
+
</head>
|
16 |
+
<body class="ia2amp-body">
|
17 |
+
<header class="ia2amp-header">
|
18 |
+
<div class="ia2amp-cover-image">
|
19 |
+
<figure class="ia2amp-figure">
|
20 |
+
<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2017/02/CrossFitGamesLogo-wide.png" width="380" height="240"></amp-img>
|
21 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">CrossFit Games 2017 Logo</figcaption>
|
22 |
+
</figure>
|
23 |
+
</div>
|
24 |
+
<div class="ia2amp-header-bar">
|
25 |
+
<div class="ia2amp-header-bar-img-container">
|
26 |
+
<amp-img src="https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8" width="223" height="44"></amp-img>
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
<div class="ia2amp-spacing after-header-bar before-header-h1"></div>
|
30 |
+
<h1 class="ia2amp-header-h1">Open 2017</h1>
|
31 |
+
<div class="ia2amp-spacing after-header-h1 before-header-author"></div>
|
32 |
+
<h3 class="ia2amp-header-author">By Éverton Rosário</h3>
|
33 |
+
<div class="ia2amp-spacing after-header-author before-header-date"></div>
|
34 |
+
<h3 class="ia2amp-header-date">February 24, 2017</h3>
|
35 |
+
<div class="ia2amp-spacing after-header-date before-p"></div>
|
36 |
+
</header>
|
37 |
+
<article class="ia2amp-article">
|
38 |
+
<p class="ia2amp-p">
|
39 |
+
The
|
40 |
+
<a href="http://games.crossfit.com">CrossFit Games</a>
|
41 |
+
are coming and the Open is the very first step for anyone try to fight for a spot on the regionals, then on the games! Pretty much almost all other sport modalities have a pre-selected group of athletes, teams or league affiliates. Sometimes the path is simply impossible: Try to get your football team to play on the NFL, it will be simply something near impossible, no matter how good that team is. Of course if your team is not part of the League you simply can’t. Not going into the merits of having a team on NFL, since this is not the point here.
|
42 |
+
</p>
|
43 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
44 |
+
<p class="ia2amp-p">What I’m claiming is that is really hard for most of the athletes, no matter the modality to get a spot on the highlight competition from that sport. This goes from olympic sports to any worldwide league.</p>
|
45 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
46 |
+
<p class="ia2amp-p">In the CrossFit Games, there is no such a thing. And the Open is the very first step in, to fight for your spot to shine. It relies only on you and your results. Once you get your spot on the regionals, you are one step closer to the Games.</p>
|
47 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
48 |
+
<p class="ia2amp-p">Let the Open begin! Here you will follow and have easy access to all content needed to follow up about the Open. Keep posted, since this is a dynamic post and will be regularly update once a week after each announcement and results pops out.</p>
|
49 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
50 |
+
<p class="ia2amp-p">Are you competing? Please make sure you will survive, and good luck! 😉</p>
|
51 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
52 |
+
<h2 class="ia2amp-h2">17.1</h2>
|
53 |
+
<div class="ia2amp-spacing after-h2 before-figcaption-small"></div>
|
54 |
+
<div class="ia2amp-video">
|
55 |
+
<figure class="ia2amp-figure">
|
56 |
+
<amp-video src="https://www.facebook.com/CrossFitGames/videos/1423437551031432/" width="380" height="240"></amp-video>
|
57 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">17.1 Announcement</figcaption>
|
58 |
+
</figure>
|
59 |
+
</div>
|
60 |
+
<div class="ia2amp-spacing after-figcaption-small before-h2"></div>
|
61 |
+
<h2 class="ia2amp-h2">17.2</h2>
|
62 |
+
<div class="ia2amp-spacing after-h2 before-figcaption-small"></div>
|
63 |
+
<div class="ia2amp-video">
|
64 |
+
<figure class="ia2amp-figure">
|
65 |
+
<amp-video src="https://www.facebook.com/CrossFitGames/videos/1431391013569419/" width="380" height="240"></amp-video>
|
66 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">17.2 Announcement</figcaption>
|
67 |
+
</figure>
|
68 |
+
</div>
|
69 |
+
<div class="ia2amp-spacing after-figcaption-small before-h2"></div>
|
70 |
+
<h2 class="ia2amp-h2">17.3</h2>
|
71 |
+
<div class="ia2amp-spacing after-h2 before-figcaption-small"></div>
|
72 |
+
<div class="ia2amp-video">
|
73 |
+
<figure class="ia2amp-figure">
|
74 |
+
<amp-video src="https://www.facebook.com/CrossFitGames/videos/1439636189411568/" width="380" height="240"></amp-video>
|
75 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">17.3 Announcement</figcaption>
|
76 |
+
</figure>
|
77 |
+
</div>
|
78 |
+
<div class="ia2amp-spacing after-figcaption-small before-h2"></div>
|
79 |
+
<h2 class="ia2amp-h2">17.4</h2>
|
80 |
+
<div class="ia2amp-spacing after-h2 before-figcaption-small"></div>
|
81 |
+
<div class="ia2amp-video">
|
82 |
+
<figure class="ia2amp-figure">
|
83 |
+
<amp-video src="https://www.facebook.com/CrossFitGames/videos/1447649318610255/" width="380" height="240"></amp-video>
|
84 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">17.4 Announcement</figcaption>
|
85 |
+
</figure>
|
86 |
+
</div>
|
87 |
+
<div class="ia2amp-spacing after-figcaption-small before-h2"></div>
|
88 |
+
<h2 class="ia2amp-h2">17.5</h2>
|
89 |
+
<div class="ia2amp-spacing after-h2 before-figcaption-small"></div>
|
90 |
+
<div class="ia2amp-video">
|
91 |
+
<figure class="ia2amp-figure">
|
92 |
+
<amp-video src="https://www.facebook.com/CrossFitGames/videos/1456025707772616/" width="380" height="240"></amp-video>
|
93 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">17.5 Announcement</figcaption>
|
94 |
+
</figure>
|
95 |
+
</div>
|
96 |
+
<div class="ia2amp-spacing after-figcaption-small"></div>
|
97 |
+
</article>
|
98 |
+
</body>
|
99 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test3-instant-article.html
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<link rel="canonical" href="http://blog.wod.expert/open-2017/" />
|
5 |
+
<meta charset="utf-8" />
|
6 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
7 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
8 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
9 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
10 |
+
<meta property="op:markup_version" content="v1.0"/>
|
11 |
+
<meta property="fb:article_style" content="wod-gray"/>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<article>
|
15 |
+
<header>
|
16 |
+
<figure>
|
17 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/02/CrossFitGamesLogo-wide.png" />
|
18 |
+
<figcaption>CrossFit Games 2017 Logo</figcaption>
|
19 |
+
</figure>
|
20 |
+
<h1>Open 2017</h1>
|
21 |
+
<time class="op-published" datetime="2017-02-24T22:30:40+00:00">February 24th, 10:30pm</time>
|
22 |
+
<time class="op-modified" datetime="2017-04-05T17:57:54+00:00">April 5th, 5:57pm</time>
|
23 |
+
<address>
|
24 |
+
<a>Éverton Rosário</a>
|
25 |
+
</address>
|
26 |
+
</header>
|
27 |
+
<p>
|
28 |
+
The
|
29 |
+
<a href="http://games.crossfit.com">CrossFit Games</a>
|
30 |
+
are coming and the Open is the very first step for anyone try to fight for a spot on the regionals, then on the games! Pretty much almost all other sport modalities have a pre-selected group of athletes, teams or league affiliates. Sometimes the path is simply impossible: Try to get your football team to play on the NFL, it will be simply something near impossible, no matter how good that team is. Of course if your team is not part of the League you simply can’t. Not going into the merits of having a team on NFL, since this is not the point here.
|
31 |
+
</p>
|
32 |
+
<p>What I’m claiming is that is really hard for most of the athletes, no matter the modality to get a spot on the highlight competition from that sport. This goes from olympic sports to any worldwide league.</p>
|
33 |
+
<p>In the CrossFit Games, there is no such a thing. And the Open is the very first step in, to fight for your spot to shine. It relies only on you and your results. Once you get your spot on the regionals, you are one step closer to the Games.</p>
|
34 |
+
<p>Let the Open begin! Here you will follow and have easy access to all content needed to follow up about the Open. Keep posted, since this is a dynamic post and will be regularly update once a week after each announcement and results pops out.</p>
|
35 |
+
<p>Are you competing? Please make sure you will survive, and good luck! 😉</p>
|
36 |
+
<h2>17.1</h2>
|
37 |
+
<figure>
|
38 |
+
<video>
|
39 |
+
<source src="https://www.facebook.com/CrossFitGames/videos/1423437551031432/" type="video/mp4" />
|
40 |
+
</video>
|
41 |
+
<figcaption>17.1 Announcement</figcaption>
|
42 |
+
</figure>
|
43 |
+
<h2>17.2</h2>
|
44 |
+
<figure>
|
45 |
+
<video>
|
46 |
+
<source src="https://www.facebook.com/CrossFitGames/videos/1431391013569419/" type="video/mp4" />
|
47 |
+
</video>
|
48 |
+
<figcaption>17.2 Announcement</figcaption>
|
49 |
+
</figure>
|
50 |
+
<h2>17.3</h2>
|
51 |
+
<figure>
|
52 |
+
<video>
|
53 |
+
<source src="https://www.facebook.com/CrossFitGames/videos/1439636189411568/" type="video/mp4" />
|
54 |
+
</video>
|
55 |
+
<figcaption>17.3 Announcement</figcaption>
|
56 |
+
</figure>
|
57 |
+
<h2>17.4</h2>
|
58 |
+
<figure>
|
59 |
+
<video>
|
60 |
+
<source src="https://www.facebook.com/CrossFitGames/videos/1447649318610255/" type="video/mp4" />
|
61 |
+
</video>
|
62 |
+
<figcaption>17.4 Announcement</figcaption>
|
63 |
+
</figure>
|
64 |
+
<h2>17.5</h2>
|
65 |
+
<figure>
|
66 |
+
<video>
|
67 |
+
<source src="https://www.facebook.com/CrossFitGames/videos/1456025707772616/" type="video/mp4" />
|
68 |
+
</video>
|
69 |
+
<figcaption>17.5 Announcement</figcaption>
|
70 |
+
</figure>
|
71 |
+
</article>
|
72 |
+
</body>
|
73 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test4-amp-converted.html
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<link rel="canonical" href="http://blog.wod.expert/du-damm-u-double-unders/"/>
|
11 |
+
<style amp-custom>amp-img.ia2amp-header-cover-img {transform: translate(0px, 0px);}div.ia2amp-cover-image {width: 380px;height: 240px;overflow: hidden;}html {background-color: rgb(238,238,238);}.ia2amp-header-category {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue;text-align: LEFT;text-transform: uppercase;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-header-bar {background-color: rgb(102,102,102);}.ia2amp-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-p {font-family: Georgia;text-align: LEFT;text-transform: none;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-article a {font-family: Georgia;text-decoration: underline;color: rgb(0,0,0);}.ia2amp-blockquote {font-family: Georgia;text-align: LEFT;display: BLOCK;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 32px 0 46px;border-top-color: rgb(0,0,0);border-right-color: rgb(0,0,0);border-bottom-color: rgb(0,0,0);border-left-color: rgb(0,0,0);border-width: 0 0 0 2px;border-style: solid;}.ia2amp-pullquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h1 {font-family: Helvetica Neue Bold;display: INLINE;text-transform: none;background-color: rgb(0,255,255);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h2 {font-family: Helvetica Neue;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-figcaption cite {font-family: Helvetica Neue;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(191,191,191);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-footer {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}/*Global Styles*/ .ia2amp-header-bar { margin: -5px 0 0 0; height: 55px; font: 0/0 a; } .ia2amp-header-bar:before { content: ' '; display: inline-block; vertical-align: middle; height: 100%; width: 16.4px; } .ia2amp-header-bar-img-container { display: inline-block; vertical-align: middle; } .ia2amp-header-category { font-size: 10px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-header-h1 { font-size: 24px; line-height: 30px; display: block; font-weight: normal; } .ia2amp-header-h2 { font-size: 16px; line-height: 20px; display: block; font-weight: normal; } .ia2amp-header h3 { font-size: 8px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-h1, .ia2amp-h2, .ia2amp-h3 { display: block; font-weight: normal; } .ia2amp-h1 { font-size: 19px; line-height: 23px; } .ia2amp-h2 { font-size: 16px; line-height: 20px; } .ia2amp-p { font-size: 14px; line-height: 20px; display: inline-block; } .ia2amp-p a { margin: 0; } .ia2amp-blockquote { font-size: 14px; line-height: 20px; padding: 0px 13.2px 0px 18.8px; } .ia2amp-spacing { display: block; height: 18.8px; margin: 0 16.4px 0 16.4px; } header figure figcaption { display: none; } .ia2amp-figure { margin: 0; } .ia2amp-op-small h1, .ia2amp-op-small h2 { font-size: 10px; display: block; } .ia2amp-op-medium h1, .ia2amp-op-medium h2 { font-size: 14px; display: block; } .ia2amp-op-large h1, .ia2amp-op-large h2 { font-size: 16px; display: block; } .ia2amp-op-extra-large h1, .ia2amp-op-extra-large h2 { font-size: 23px; display: block; } .ia2amp-figcaption cite { font-size: 8px; display: block; } .ia2amp-op-left { text-align: left; } .ia2amp-op-center { text-align: center; } .ia2amp-op-right { text-align: right; } .ia2amp-figure { position: relative; } figcaption.ia2amp-op-vertical-center { position: absolute; z-index: 1000; } .ia2amp-footer { display: block; font-size: 12px; line-height: 17px; } .ia2amp-footer aside p { margin: 0; } .ia2amp-spacing.after-header-bar.before-header-category { height: 18.8px; } .ia2amp-spacing.after-header-category.before-header-h1, .ia2amp-spacing.after-header-h1.before-header-h2 { height: 13.2px; } .ia2amp-spacing.after-h1.before-h2 { height: 13.2px; } .ia2amp-spacing.after-li.before-li { height: 13.2px; } .ia2amp-spacing.after-footer.before-footer { height: 18.8px; } .ia2amp-spacing.after-header-h1.before-header-author, .ia2amp-spacing.after-header-h2.before-header-author { height: 18.8px; } .ia2amp-spacing.after-header-author.before-header-date { height: 0; } .ia2amp-spacing.after-header-date.before-h1, .ia2amp-spacing.after-header-date.before-h2, .ia2amp-spacing.after-header-date.before-p { height: 26.4px; } .ia2amp-spacing.after-h1.before-p, .ia2amp-spacing.after-h2.before-p, .ia2amp-spacing.after-h3.before-p { height: 18.8px; } .ia2amp-spacing.after-blockquote.before-p { height: 18.8px; } .ia2amp-spacing.after-slideshow, .ia2amp-spacing.before-slideshow, .ia2amp-spacing.after-interactive, .ia2amp-spacing.before-interactive, .ia2amp-spacing.after-image, .ia2amp-spacing.before-image, .ia2amp-spacing.after-figcaption-small, .ia2amp-spacing.after-figcaption-medium, .ia2amp-spacing.after-figcaption-large, .ia2amp-spacing.after-figcaption-extra-large { height: 26.4px; } </style>
|
12 |
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"http://blog.wod.expert/du-damm-u-double-unders/","headline":"DU \u2013 Damm U (Double Unders)!","datePublished":"2016-05-15T20:57:00+00:00","description":"Damm you Double Unders (DU)! I guess lots of people will agree with the DAMM part\u2026 But why the Double Unders are so problematic since it is just a simple jumping rope? Well, maybe not that simple! \ud83d\ude09","dateModified":"2017-03-17T15:40:25+00:00","author":{"@type":"Person","name":"\u00c9verton Ros\u00e1rio"},"image":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2016/05/jumprope.jpg","width":380,"height":240},"publisher":{"@type":"Organization","name":"WOD Expert","logo":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png","width":600,"height":60}}}</script>
|
13 |
+
<title>DU – Damm U (Double Unders)!</title>
|
14 |
+
</head>
|
15 |
+
<body class="ia2amp-body">
|
16 |
+
<header class="ia2amp-header">
|
17 |
+
<div class="ia2amp-cover-image">
|
18 |
+
<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2016/05/jumprope.jpg" width="380" height="240"></amp-img>
|
19 |
+
</div>
|
20 |
+
<div class="ia2amp-header-bar">
|
21 |
+
<div class="ia2amp-header-bar-img-container">
|
22 |
+
<amp-img src="https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8" width="223" height="44"></amp-img>
|
23 |
+
</div>
|
24 |
+
</div>
|
25 |
+
<div class="ia2amp-spacing after-header-bar before-header-category"></div>
|
26 |
+
<h2 class="ia2amp-header-category">double under</h2>
|
27 |
+
<div class="ia2amp-spacing after-header-category before-header-h1"></div>
|
28 |
+
<h1 class="ia2amp-header-h1">DU – Damm U (Double Unders)!</h1>
|
29 |
+
<div class="ia2amp-spacing after-header-h1 before-header-author"></div>
|
30 |
+
<h3 class="ia2amp-header-author">By Éverton Rosário</h3>
|
31 |
+
<div class="ia2amp-spacing after-header-author before-header-date"></div>
|
32 |
+
<h3 class="ia2amp-header-date">May 15, 2016</h3>
|
33 |
+
<div class="ia2amp-spacing after-header-date before-p"></div>
|
34 |
+
</header>
|
35 |
+
<article class="ia2amp-article">
|
36 |
+
<p class="ia2amp-p">Damm you Double Unders (DU)! I guess lots of people will agree with the DAMM part… But why the Double Unders are so problematic since it is just a simple jumping rope? Well, maybe not that simple! 😉</p>
|
37 |
+
<div class="ia2amp-spacing after-p before-figcaption-small"></div>
|
38 |
+
<div class="ia2amp-image">
|
39 |
+
<figure class="ia2amp-figure">
|
40 |
+
<amp-img layout="responsive" src="http://blog.wod.expert/wp-content/uploads/2017/03/elephant-jump-rope-300x233.gif" width="380" height="240"></amp-img>
|
41 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">@MrWhaite</figcaption>
|
42 |
+
</figure>
|
43 |
+
</div>
|
44 |
+
<div class="ia2amp-spacing after-figcaption-small before-p"></div>
|
45 |
+
<p class="ia2amp-p">Jumping rope might be simple as most people were used to do it during school years. And by jumping rope I mean the single unders.</p>
|
46 |
+
<div class="ia2amp-spacing after-p before-blockquote"></div>
|
47 |
+
<blockquote class="ia2amp-blockquote">
|
48 |
+
“A
|
49 |
+
<b>double under</b>
|
50 |
+
is a popular exercise done on a
|
51 |
+
<a href="http://athletics.wikia.com/wiki/Jump_rope">jump rope</a>
|
52 |
+
in which the rope makes two passes per jump instead of just one.”
|
53 |
+
<a href="http://athletics.wikia.com/wiki/Double_Unders">Athlepedia</a>
|
54 |
+
</blockquote>
|
55 |
+
<div class="ia2amp-spacing after-blockquote before-p"></div>
|
56 |
+
<p class="ia2amp-p">One of the key characteristics comparing the double unders to the single unders are 2:</p>
|
57 |
+
<div class="ia2amp-spacing after-p before-list"></div>
|
58 |
+
<ul class="ia2amp-list">
|
59 |
+
<li>the speed you spin the rope; and</li>
|
60 |
+
<li>how high the jump is.</li>
|
61 |
+
</ul>
|
62 |
+
<div class="ia2amp-spacing after-list before-p"></div>
|
63 |
+
<p class="ia2amp-p">In simple math therms, if you jump twice as high from your single under would be enough to perfectly accomplish the double unders. Another possibility is spinning twice as fast the rope, thus not needing to change how high you jump. The actual answer here is that none of the situations will be the correct answer, otherwise you will burn your wrists and your handle power, or you will burn your legs more than necessary. Combining the DU into a more complex WOD will make these 2 initial extreme options even more useless, since probably you will have any other exercise that will demand your handle or your legs, or even worst: both.</p>
|
64 |
+
<div class="ia2amp-spacing after-p before-image"></div>
|
65 |
+
<div class="ia2amp-image">
|
66 |
+
<amp-img layout="responsive" src="http://blog.wod.expert/wp-content/uploads/2016/05/JumpROpe-copy-300x188.jpg" width="380" height="240"></amp-img>
|
67 |
+
</div>
|
68 |
+
<div class="ia2amp-spacing after-image before-h2"></div>
|
69 |
+
<h2 class="ia2amp-h2">Progression</h2>
|
70 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
71 |
+
<p class="ia2amp-p">A good progression to perform your double unders if you still didn’t make it is to start without any rope! “Are you crazy?” you might be wondering. But no, Im not crazy or out of my mind. The point to start here is to start jumping consistently on your toes, not on your hills, and bending minimally as possible your knees. Once you are jumping consistently high, and by high, try jumping twice as high of your single under, or maybe even higher if you can. Once you can perform at least 10 sequence jumps high enough with not much difference between the jumps. At this high you can perform the “double tap” on your hips using your free hands (remember, you are not using hands so far). Also remember to jump straight, without high knees nor rising your feet. Once you completed all these steps, you are good to move forward.</p>
|
72 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
73 |
+
<p class="ia2amp-p">You will start using a rope, consider buying one for you or make sure you will have yours reserved every time on your box. Otherwise mixing different ropes with different specs you make this process more difficult.</p>
|
74 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
75 |
+
<p class="ia2amp-p">Now it is time to start using a rope, but still, it is not time to try to perform the double under. You need to keep jumping as high as the previous step, but performing only a single under. You will notice that you will be jumping really high and will need to slow down a lot the rope speed, otherwise you will be landing and the rope will be arriving at your feet at same time. Slow down and get used to the high jumps. Try to keep as high as you did before without the rope. Once you perform 10 unbroken high jumps with slow rope speed, is time to move forward.</p>
|
76 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
77 |
+
<p class="ia2amp-p">Now you will be jumping as high as you did in both previous steps, but now you will speed up your rope trying to perform the double under. Performing these steps will raise your odds to accomplish the regular double unders.</p>
|
78 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
79 |
+
<p class="ia2amp-p">Once you start performing more regularly your double unders, is practice time. And by practice I mean: exhaustive practicing. Try to perform at least 200 double unders. This will definitely make you get more feeling and understand your body balance, jumping and wrist skills.</p>
|
80 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
81 |
+
<h2 class="ia2amp-h2">The hidden characteristics of Double Unders</h2>
|
82 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
83 |
+
<p class="ia2amp-p">Double unders are hard to get, but once you get used to it, you will perform it really smoothly. By looking to a more complex WOD where you have DU in it, you might underestimate how heavy the DU’s might be because it will:</p>
|
84 |
+
<div class="ia2amp-spacing after-p before-list"></div>
|
85 |
+
<ul class="ia2amp-list">
|
86 |
+
<li>burn your wrists/handle</li>
|
87 |
+
<li>exhaust your legs</li>
|
88 |
+
<li>raise/keep high your heart beat</li>
|
89 |
+
</ul>
|
90 |
+
<div class="ia2amp-spacing after-list before-p"></div>
|
91 |
+
<p class="ia2amp-p">These three might sound inoffensive but don’t mis-judge this. They will make you suffer, suffer hard depending on the WOD. If the WOD mixes some hang moves, pull ups, muscle ups or any other exercise that burns your grip, the rope might feel harder to spin. This will be the perfect timing to jump a little higher and save your wrists a little bit. On the other hand, if your WOD is really burning your legs, might be a good opportunity to save some energies by jumping little lower and spinning faster. If your WOD burns your grip + legs, try to keep a balance with the 50-50 strategy, and know that by the end of this WOD you’ll be supplicating for your life, I mean, your breath! 😛</p>
|
92 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
93 |
+
<h2 class="ia2amp-h2">Hints for warming up</h2>
|
94 |
+
<div class="ia2amp-spacing after-h2 before-list"></div>
|
95 |
+
<ul class="ia2amp-list">
|
96 |
+
<li>Perform sets of single unders</li>
|
97 |
+
<li>Run some short sprints (100m is enough)</li>
|
98 |
+
<li>Few box jump</li>
|
99 |
+
</ul>
|
100 |
+
<div class="ia2amp-spacing after-list"></div>
|
101 |
+
</article>
|
102 |
+
</body>
|
103 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test4-instant-article.html
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<link rel="canonical" href="http://blog.wod.expert/du-damm-u-double-unders/" />
|
5 |
+
<meta charset="utf-8" />
|
6 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
7 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
8 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
9 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
10 |
+
<meta property="op:markup_version" content="v1.0"/>
|
11 |
+
<meta property="fb:article_style" content="wod-gray"/>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<article>
|
15 |
+
<header>
|
16 |
+
<figure>
|
17 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2016/05/jumprope.jpg" />
|
18 |
+
</figure>
|
19 |
+
<h1>DU – Damm U (Double Unders)!</h1>
|
20 |
+
<time class="op-published" datetime="2016-05-15T20:57:00+00:00">May 15th, 8:57pm</time>
|
21 |
+
<time class="op-modified" datetime="2017-03-17T15:40:25+00:00">March 17th, 3:40pm</time>
|
22 |
+
<address>
|
23 |
+
<a>Éverton Rosário</a>
|
24 |
+
</address>
|
25 |
+
<h3 class="op-kicker">double under</h3>
|
26 |
+
</header>
|
27 |
+
<p>Damm you Double Unders (DU)! I guess lots of people will agree with the DAMM part… But why the Double Unders are so problematic since it is just a simple jumping rope? Well, maybe not that simple! 😉</p>
|
28 |
+
<figure>
|
29 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/elephant-jump-rope-300x233.gif" />
|
30 |
+
<figcaption>@MrWhaite</figcaption>
|
31 |
+
</figure>
|
32 |
+
<p>Jumping rope might be simple as most people were used to do it during school years. And by jumping rope I mean the single unders.</p>
|
33 |
+
<blockquote>
|
34 |
+
“A
|
35 |
+
<b>double under</b>
|
36 |
+
is a popular exercise done on a
|
37 |
+
<a href="http://athletics.wikia.com/wiki/Jump_rope">jump rope</a>
|
38 |
+
in which the rope makes two passes per jump instead of just one.”
|
39 |
+
<br />
|
40 |
+
<a href="http://athletics.wikia.com/wiki/Double_Unders">Athlepedia</a>
|
41 |
+
</blockquote>
|
42 |
+
<p>One of the key characteristics comparing the double unders to the single unders are 2:</p>
|
43 |
+
<ul>
|
44 |
+
<li>the speed you spin the rope; and</li>
|
45 |
+
<li>how high the jump is.</li>
|
46 |
+
</ul>
|
47 |
+
<p>In simple math therms, if you jump twice as high from your single under would be enough to perfectly accomplish the double unders. Another possibility is spinning twice as fast the rope, thus not needing to change how high you jump. The actual answer here is that none of the situations will be the correct answer, otherwise you will burn your wrists and your handle power, or you will burn your legs more than necessary. Combining the DU into a more complex WOD will make these 2 initial extreme options even more useless, since probably you will have any other exercise that will demand your handle or your legs, or even worst: both.</p>
|
48 |
+
<figure>
|
49 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2016/05/JumpROpe-copy-300x188.jpg" />
|
50 |
+
</figure>
|
51 |
+
<h2>Progression</h2>
|
52 |
+
<p>A good progression to perform your double unders if you still didn’t make it is to start without any rope! “Are you crazy?” you might be wondering. But no, Im not crazy or out of my mind. The point to start here is to start jumping consistently on your toes, not on your hills, and bending minimally as possible your knees. Once you are jumping consistently high, and by high, try jumping twice as high of your single under, or maybe even higher if you can. Once you can perform at least 10 sequence jumps high enough with not much difference between the jumps. At this high you can perform the “double tap” on your hips using your free hands (remember, you are not using hands so far). Also remember to jump straight, without high knees nor rising your feet. Once you completed all these steps, you are good to move forward.</p>
|
53 |
+
<p>You will start using a rope, consider buying one for you or make sure you will have yours reserved every time on your box. Otherwise mixing different ropes with different specs you make this process more difficult.</p>
|
54 |
+
<p>Now it is time to start using a rope, but still, it is not time to try to perform the double under. You need to keep jumping as high as the previous step, but performing only a single under. You will notice that you will be jumping really high and will need to slow down a lot the rope speed, otherwise you will be landing and the rope will be arriving at your feet at same time. Slow down and get used to the high jumps. Try to keep as high as you did before without the rope. Once you perform 10 unbroken high jumps with slow rope speed, is time to move forward.</p>
|
55 |
+
<p>Now you will be jumping as high as you did in both previous steps, but now you will speed up your rope trying to perform the double under. Performing these steps will raise your odds to accomplish the regular double unders.</p>
|
56 |
+
<p>Once you start performing more regularly your double unders, is practice time. And by practice I mean: exhaustive practicing. Try to perform at least 200 double unders. This will definitely make you get more feeling and understand your body balance, jumping and wrist skills.</p>
|
57 |
+
<h2>The hidden characteristics of Double Unders</h2>
|
58 |
+
<p>Double unders are hard to get, but once you get used to it, you will perform it really smoothly. By looking to a more complex WOD where you have DU in it, you might underestimate how heavy the DU’s might be because it will:</p>
|
59 |
+
<ul>
|
60 |
+
<li>burn your wrists/handle</li>
|
61 |
+
<li>exhaust your legs</li>
|
62 |
+
<li>raise/keep high your heart beat</li>
|
63 |
+
</ul>
|
64 |
+
<p>These three might sound inoffensive but don’t mis-judge this. They will make you suffer, suffer hard depending on the WOD. If the WOD mixes some hang moves, pull ups, muscle ups or any other exercise that burns your grip, the rope might feel harder to spin. This will be the perfect timing to jump a little higher and save your wrists a little bit. On the other hand, if your WOD is really burning your legs, might be a good opportunity to save some energies by jumping little lower and spinning faster. If your WOD burns your grip + legs, try to keep a balance with the 50-50 strategy, and know that by the end of this WOD you’ll be supplicating for your life, I mean, your breath! 😛</p>
|
65 |
+
<h2>Hints for warming up</h2>
|
66 |
+
<ul>
|
67 |
+
<li>Perform sets of single unders</li>
|
68 |
+
<li>Run some short sprints (100m is enough)</li>
|
69 |
+
<li>Few box jump</li>
|
70 |
+
</ul>
|
71 |
+
</article>
|
72 |
+
</body>
|
73 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test5-amp-converted.html
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<link rel="canonical" href="http://blog.wod.expert/wall-ball-or-ball-shot/"/>
|
11 |
+
<style amp-custom>amp-img.ia2amp-header-cover-img {transform: translate(0px, 0px);}div.ia2amp-cover-image {width: 380px;height: 240px;overflow: hidden;}html {background-color: rgb(238,238,238);}.ia2amp-header-category {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue;text-align: LEFT;text-transform: uppercase;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-header-bar {background-color: rgb(102,102,102);}.ia2amp-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-p {font-family: Georgia;text-align: LEFT;text-transform: none;color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;}.ia2amp-article a {font-family: Georgia;text-decoration: underline;color: rgb(0,0,0);}.ia2amp-blockquote {font-family: Georgia;text-align: LEFT;display: BLOCK;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 32px 0 46px;border-top-color: rgb(0,0,0);border-right-color: rgb(0,0,0);border-bottom-color: rgb(0,0,0);border-left-color: rgb(0,0,0);border-width: 0 0 0 2px;border-style: solid;}.ia2amp-pullquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h1 {font-family: Helvetica Neue Bold;display: INLINE;text-transform: none;background-color: rgb(0,255,255);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h2 {font-family: Helvetica Neue;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h1 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h2 {font-family: Georgia;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-figcaption cite {font-family: Helvetica Neue;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(191,191,191);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-footer {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}/*Global Styles*/ .ia2amp-header-bar { margin: -5px 0 0 0; height: 55px; font: 0/0 a; } .ia2amp-header-bar:before { content: ' '; display: inline-block; vertical-align: middle; height: 100%; width: 16.4px; } .ia2amp-header-bar-img-container { display: inline-block; vertical-align: middle; } .ia2amp-header-category { font-size: 10px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-header-h1 { font-size: 24px; line-height: 30px; display: block; font-weight: normal; } .ia2amp-header-h2 { font-size: 16px; line-height: 20px; display: block; font-weight: normal; } .ia2amp-header h3 { font-size: 8px; line-height: 12px; display: block; font-weight: normal; } .ia2amp-h1, .ia2amp-h2, .ia2amp-h3 { display: block; font-weight: normal; } .ia2amp-h1 { font-size: 19px; line-height: 23px; } .ia2amp-h2 { font-size: 16px; line-height: 20px; } .ia2amp-p { font-size: 14px; line-height: 20px; display: inline-block; } .ia2amp-p a { margin: 0; } .ia2amp-blockquote { font-size: 14px; line-height: 20px; padding: 0px 13.2px 0px 18.8px; } .ia2amp-spacing { display: block; height: 18.8px; margin: 0 16.4px 0 16.4px; } header figure figcaption { display: none; } .ia2amp-figure { margin: 0; } .ia2amp-op-small h1, .ia2amp-op-small h2 { font-size: 10px; display: block; } .ia2amp-op-medium h1, .ia2amp-op-medium h2 { font-size: 14px; display: block; } .ia2amp-op-large h1, .ia2amp-op-large h2 { font-size: 16px; display: block; } .ia2amp-op-extra-large h1, .ia2amp-op-extra-large h2 { font-size: 23px; display: block; } .ia2amp-figcaption cite { font-size: 8px; display: block; } .ia2amp-op-left { text-align: left; } .ia2amp-op-center { text-align: center; } .ia2amp-op-right { text-align: right; } .ia2amp-figure { position: relative; } figcaption.ia2amp-op-vertical-center { position: absolute; z-index: 1000; } .ia2amp-footer { display: block; font-size: 12px; line-height: 17px; } .ia2amp-footer aside p { margin: 0; } .ia2amp-spacing.after-header-bar.before-header-category { height: 18.8px; } .ia2amp-spacing.after-header-category.before-header-h1, .ia2amp-spacing.after-header-h1.before-header-h2 { height: 13.2px; } .ia2amp-spacing.after-h1.before-h2 { height: 13.2px; } .ia2amp-spacing.after-li.before-li { height: 13.2px; } .ia2amp-spacing.after-footer.before-footer { height: 18.8px; } .ia2amp-spacing.after-header-h1.before-header-author, .ia2amp-spacing.after-header-h2.before-header-author { height: 18.8px; } .ia2amp-spacing.after-header-author.before-header-date { height: 0; } .ia2amp-spacing.after-header-date.before-h1, .ia2amp-spacing.after-header-date.before-h2, .ia2amp-spacing.after-header-date.before-p { height: 26.4px; } .ia2amp-spacing.after-h1.before-p, .ia2amp-spacing.after-h2.before-p, .ia2amp-spacing.after-h3.before-p { height: 18.8px; } .ia2amp-spacing.after-blockquote.before-p { height: 18.8px; } .ia2amp-spacing.after-slideshow, .ia2amp-spacing.before-slideshow, .ia2amp-spacing.after-interactive, .ia2amp-spacing.before-interactive, .ia2amp-spacing.after-image, .ia2amp-spacing.before-image, .ia2amp-spacing.after-figcaption-small, .ia2amp-spacing.after-figcaption-medium, .ia2amp-spacing.after-figcaption-large, .ia2amp-spacing.after-figcaption-extra-large { height: 26.4px; } </style>
|
12 |
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"http://blog.wod.expert/wall-ball-or-ball-shot/","headline":"Wall Ball or Ball Shot?","datePublished":"2016-05-20T13:48:38+00:00","description":"\n Both expressions seems correct and in common shares the requisite of\n breaking parallel line\n while squatting. Just for correctness, the Wall Ball Shot is the best title to use.\n ","dateModified":"2017-03-17T15:38:31+00:00","author":{"@type":"Person","name":"\u00c9verton Ros\u00e1rio"},"image":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/03/rich-wallball.jpg","width":380,"height":240},"publisher":{"@type":"Organization","name":"WOD Expert","logo":{"@type":"ImageObject","url":"http://blog.wod.expert/wp-content/uploads/2017/04/wod-expert-amp-org-logo.png","width":600,"height":60}}}</script>
|
13 |
+
<title>Wall Ball or Ball Shot?</title>
|
14 |
+
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
|
15 |
+
</head>
|
16 |
+
<body class="ia2amp-body">
|
17 |
+
<header class="ia2amp-header">
|
18 |
+
<div class="ia2amp-cover-image">
|
19 |
+
<figure class="ia2amp-figure">
|
20 |
+
<amp-img class="ia2amp-header-cover-img" src="http://blog.wod.expert/wp-content/uploads/2017/03/rich-wallball.jpg" width="380" height="240"></amp-img>
|
21 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">Rich Froning at Wall Ball Shot</figcaption>
|
22 |
+
</figure>
|
23 |
+
</div>
|
24 |
+
<div class="ia2amp-header-bar">
|
25 |
+
<div class="ia2amp-header-bar-img-container">
|
26 |
+
<amp-img src="https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8" width="223" height="44"></amp-img>
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
<div class="ia2amp-spacing after-header-bar before-header-category"></div>
|
30 |
+
<h2 class="ia2amp-header-category">exercise</h2>
|
31 |
+
<div class="ia2amp-spacing after-header-category before-header-h1"></div>
|
32 |
+
<h1 class="ia2amp-header-h1">Wall Ball or Ball Shot?</h1>
|
33 |
+
<div class="ia2amp-spacing after-header-h1 before-header-author"></div>
|
34 |
+
<h3 class="ia2amp-header-author">By Éverton Rosário</h3>
|
35 |
+
<div class="ia2amp-spacing after-header-author before-header-date"></div>
|
36 |
+
<h3 class="ia2amp-header-date">May 20, 2016</h3>
|
37 |
+
<div class="ia2amp-spacing after-header-date before-p"></div>
|
38 |
+
</header>
|
39 |
+
<article class="ia2amp-article">
|
40 |
+
<p class="ia2amp-p">
|
41 |
+
Both expressions seems correct and in common shares the requisite of
|
42 |
+
<a href="http://blog.wod.expert/2016/05/01/breaking-parallel-line">breaking parallel line</a>
|
43 |
+
while squatting. Just for correctness, the Wall Ball Shot is the best title to use.
|
44 |
+
</p>
|
45 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
46 |
+
<p class="ia2amp-p">One thing that comes to mind is that when thinking about wall ball It reminds me of only one constraint to make it a valid movement. So if you throw the ball below the limit line it is a “no-rep”, otherwise +1 to your reps. 😉</p>
|
47 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
48 |
+
<p class="ia2amp-p">Looking to the wall ball shot perspective, not only the bottom limit is important, but also there is a top, left and right limits. In other words: you gotta hit the target.</p>
|
49 |
+
<div class="ia2amp-spacing after-p before-figcaption-small"></div>
|
50 |
+
<div class="ia2amp-image">
|
51 |
+
<figure class="ia2amp-figure">
|
52 |
+
<amp-img layout="responsive" src="http://blog.wod.expert/wp-content/uploads/2017/03/wallballshot-mark-rogue-300x189.jpg" width="380" height="240"></amp-img>
|
53 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small">Target used on most of competitions</figcaption>
|
54 |
+
</figure>
|
55 |
+
</div>
|
56 |
+
<div class="ia2amp-spacing after-figcaption-small before-p"></div>
|
57 |
+
<p class="ia2amp-p">CrossFit isn’t just about being strong and fast, but also precise. Always consider yourself doing your wall balls hitting at same target always. If you compete into any fitness competition, the odds of using a ball shot exercise increases, since the ball shot are easier equipment to have on open spaces. The wall, save for your box 😉</p>
|
58 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
59 |
+
<h2 class="ia2amp-h2">Hints for the exercise</h2>
|
60 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
61 |
+
<p class="ia2amp-p">Never stop looking at your target, the piece of metal, circle, line or the imaginary “X” mark on the wall. This will make your body foresee where you need to hit, and just throw there, you’ll gonna hit it!</p>
|
62 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
63 |
+
<p class="ia2amp-p">
|
64 |
+
Never forget to break the parallel, and while going down, don’t try to slow your descent, this will make you burn your muscles. Always remember, if you want to perform better on the WODs
|
65 |
+
<a href="http://blog.wod.expert/2016/06/06/always-save-energy">always think about saving energy</a>
|
66 |
+
.
|
67 |
+
</p>
|
68 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
69 |
+
<p class="ia2amp-p">Thinking about doing the wallball shots, never forget to use all your body as lever to accomplish the movement with the minimal effort possible. By this I mean:</p>
|
70 |
+
<div class="ia2amp-spacing after-p before-list"></div>
|
71 |
+
<ol class="ia2amp-list">
|
72 |
+
<li>Start movement by performing a “deadlift”getting the ball from floor</li>
|
73 |
+
<li>Go down as fast as you can, holding the ball at your face level, holding by the bottom of the ball</li>
|
74 |
+
<li>Break the parallel and then explode as fast as you can your legs</li>
|
75 |
+
<li>By the moment you are straight up, your ball will move up without any force</li>
|
76 |
+
<li>Push the ball up, like setting a volleyball ball, never forgetting to use your wrists, this will save some shoulders and legs energy</li>
|
77 |
+
<li>You HIT the target! Add one to your counting sequence, never forget this 😉 !</li>
|
78 |
+
<li>If your counting comes to the correct number, jump to number 11.</li>
|
79 |
+
<li>The ball will start to descend, keep your arms straight up waiting for the contact</li>
|
80 |
+
<li>Absorb the ball with your arms and wrists and start the descend, using the less amount of energy possible</li>
|
81 |
+
<li>Repeat from step 2!</li>
|
82 |
+
<li>You are done!</li>
|
83 |
+
</ol>
|
84 |
+
<div class="ia2amp-spacing after-list before-slideshow"></div>
|
85 |
+
<div class="ia2amp-slideshow">
|
86 |
+
<amp-carousel width="380" height="240">
|
87 |
+
<div class="ia2amp-slideshow-image">
|
88 |
+
<figure class="ia2amp-figure">
|
89 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/wallball-squat-150x150.jpg" width="380" height="240"></amp-img>
|
90 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>Squat preparing to throw</h1></figcaption>
|
91 |
+
</figure>
|
92 |
+
</div>
|
93 |
+
<div class="ia2amp-slideshow-image">
|
94 |
+
<figure class="ia2amp-figure">
|
95 |
+
<amp-img src="http://blog.wod.expert/wp-content/uploads/2017/03/wallball-throw-volleyball-150x150.jpg" width="380" height="240"></amp-img>
|
96 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>The wall ball throw using the wrists power, just like volleyball setting</h1></figcaption>
|
97 |
+
</figure>
|
98 |
+
</div>
|
99 |
+
</amp-carousel>
|
100 |
+
</div>
|
101 |
+
<div class="ia2amp-spacing after-slideshow before-h2"></div>
|
102 |
+
<h2 class="ia2amp-h2">Hints for warming up</h2>
|
103 |
+
<div class="ia2amp-spacing after-h2 before-list"></div>
|
104 |
+
<ul class="ia2amp-list">
|
105 |
+
<li>Perform sets of air squats</li>
|
106 |
+
<li>Use lighter med ball to perform few shots</li>
|
107 |
+
<li>Perform some sets of walking lunges</li>
|
108 |
+
</ul>
|
109 |
+
<div class="ia2amp-spacing after-list"></div>
|
110 |
+
</article>
|
111 |
+
</body>
|
112 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/test5-instant-article.html
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<link rel="canonical" href="http://blog.wod.expert/wall-ball-or-ball-shot/" />
|
5 |
+
<meta charset="utf-8" />
|
6 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
7 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
8 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
9 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
10 |
+
<meta property="op:markup_version" content="v1.0"/>
|
11 |
+
<meta property="fb:article_style" content="wod-gray"/>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<article>
|
15 |
+
<header>
|
16 |
+
<figure>
|
17 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/rich-wallball.jpg" />
|
18 |
+
<figcaption>Rich Froning at Wall Ball Shot</figcaption>
|
19 |
+
</figure>
|
20 |
+
<h1>Wall Ball or Ball Shot?</h1>
|
21 |
+
<time class="op-published" datetime="2016-05-20T13:48:38+00:00">May 20th, 1:48pm</time>
|
22 |
+
<time class="op-modified" datetime="2017-03-17T15:38:31+00:00">March 17th, 3:38pm</time>
|
23 |
+
<address>
|
24 |
+
<a>Éverton Rosário</a>
|
25 |
+
</address>
|
26 |
+
<h3 class="op-kicker">exercise</h3>
|
27 |
+
</header>
|
28 |
+
<p>
|
29 |
+
Both expressions seems correct and in common shares the requisite of
|
30 |
+
<a href="http://blog.wod.expert/2016/05/01/breaking-parallel-line">breaking parallel line</a>
|
31 |
+
while squatting. Just for correctness, the Wall Ball Shot is the best title to use.
|
32 |
+
</p>
|
33 |
+
<p>One thing that comes to mind is that when thinking about wall ball It reminds me of only one constraint to make it a valid movement. So if you throw the ball below the limit line it is a “no-rep”, otherwise +1 to your reps. 😉</p>
|
34 |
+
<p>Looking to the wall ball shot perspective, not only the bottom limit is important, but also there is a top, left and right limits. In other words: you gotta hit the target.</p>
|
35 |
+
<figure>
|
36 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/wallballshot-mark-rogue-300x189.jpg" />
|
37 |
+
<figcaption>Target used on most of competitions</figcaption>
|
38 |
+
</figure>
|
39 |
+
<p>CrossFit isn’t just about being strong and fast, but also precise. Always consider yourself doing your wall balls hitting at same target always. If you compete into any fitness competition, the odds of using a ball shot exercise increases, since the ball shot are easier equipment to have on open spaces. The wall, save for your box 😉</p>
|
40 |
+
<h2>Hints for the exercise</h2>
|
41 |
+
<p>Never stop looking at your target, the piece of metal, circle, line or the imaginary “X” mark on the wall. This will make your body foresee where you need to hit, and just throw there, you’ll gonna hit it!</p>
|
42 |
+
<p>
|
43 |
+
Never forget to break the parallel, and while going down, don’t try to slow your descent, this will make you burn your muscles. Always remember, if you want to perform better on the WODs
|
44 |
+
<a href="http://blog.wod.expert/2016/06/06/always-save-energy">always think about saving energy</a>
|
45 |
+
.
|
46 |
+
</p>
|
47 |
+
<p>Thinking about doing the wallball shots, never forget to use all your body as lever to accomplish the movement with the minimal effort possible. By this I mean:</p>
|
48 |
+
<ol>
|
49 |
+
<li>Start movement by performing a “deadlift”getting the ball from floor</li>
|
50 |
+
<li>Go down as fast as you can, holding the ball at your face level, holding by the bottom of the ball</li>
|
51 |
+
<li>Break the parallel and then explode as fast as you can your legs</li>
|
52 |
+
<li>By the moment you are straight up, your ball will move up without any force</li>
|
53 |
+
<li>Push the ball up, like setting a volleyball ball, never forgetting to use your wrists, this will save some shoulders and legs energy</li>
|
54 |
+
<li>You HIT the target! Add one to your counting sequence, never forget this 😉 !</li>
|
55 |
+
<li>If your counting comes to the correct number, jump to number 11.</li>
|
56 |
+
<li>The ball will start to descend, keep your arms straight up waiting for the contact</li>
|
57 |
+
<li>Absorb the ball with your arms and wrists and start the descend, using the less amount of energy possible</li>
|
58 |
+
<li>Repeat from step 2!</li>
|
59 |
+
<li>You are done!</li>
|
60 |
+
</ol>
|
61 |
+
<figure class="op-slideshow">
|
62 |
+
<figure>
|
63 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/wallball-squat-150x150.jpg" />
|
64 |
+
<figcaption>Squat preparing to throw</figcaption>
|
65 |
+
</figure>
|
66 |
+
<figure>
|
67 |
+
<img src="http://blog.wod.expert/wp-content/uploads/2017/03/wallball-throw-volleyball-150x150.jpg" />
|
68 |
+
<figcaption>The wall ball throw using the wrists power, just like volleyball setting</figcaption>
|
69 |
+
</figure>
|
70 |
+
</figure>
|
71 |
+
<h2>Hints for warming up</h2>
|
72 |
+
<ul>
|
73 |
+
<li>Perform sets of air squats</li>
|
74 |
+
<li>Use lighter med ball to perform few shots</li>
|
75 |
+
<li>Perform some sets of walking lunges</li>
|
76 |
+
</ul>
|
77 |
+
<p />
|
78 |
+
</article>
|
79 |
+
</body>
|
80 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/tutorial-amp-converted.html
ADDED
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!doctype html><html amp lang="en-US">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8"/>
|
4 |
+
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
|
5 |
+
<script src="https://cdn.ampproject.org/v0.js" async></script>
|
6 |
+
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
7 |
+
<noscript>
|
8 |
+
<style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style>
|
9 |
+
</noscript>
|
10 |
+
<link rel="canonical" href="http://blog.wod.expert/example1"/>
|
11 |
+
<style amp-custom>amp-img.ia2amp-header-cover-img {transform: translate(0px, 0px);}div.ia2amp-cover-image {width: 380px;height: 240px;overflow: hidden;}html {background-color: rgb(255,255,255);}.ia2amp-header-category {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header h3 {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-header-bar {background-color: rgb(255,255,255);}.ia2amp-h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-p {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-article a {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;text-decoration: underline;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-blockquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 32px 0 46px;border-top-color: rgb(0,0,0);border-right-color: rgb(0,0,0);border-bottom-color: rgb(0,0,0);border-left-color: rgb(0,0,0);border-width: 0 0 0 2px;border-style: solid;}.ia2amp-pullquote {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-pullquote cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h1 {font-family: Helvetica Neue Bold;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-small h2 {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-medium h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-large h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h1 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-op-extra-large h2 {font-family: Georgia;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(128,128,128);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-figcaption cite {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: uppercase;background-color: rgba(255,255,255,0);color: rgb(191,191,191);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}.ia2amp-footer {font-family: Helvetica Neue;text-align: LEFT;display: INLINE;text-transform: none;background-color: rgba(255,255,255,0);color: rgb(0,0,0);margin: 0 16.4px 0 16.4px;padding: 0 0 0 0;border-width: 0 0 0 0;border-style: solid;}/* Custom CSS for default style goes here */ /* p { background-color: rgb(255,00,00); } */ </style>
|
12 |
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"NewsArticle","mainEntityOfPage":"http://blog.wod.expert/example1","headline":" Instant Articles ","datePublished":"2016-02-04T08:00:00-08:00","description":"Yes, it\u2019s true. Instant Articles open on mobile devices really quickly.","dateModified":"2016-02-04T08:00:00-08:00","author":{"@type":"Person","name":"\n Instant Articles Team\n "},"image":{"@type":"ImageObject","url":"https://s3.amazonaws.com/instantarticles/examples/fb_beach_flower.jpg","width":380,"height":240}}</script>
|
13 |
+
<title> Instant Articles </title>
|
14 |
+
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
|
15 |
+
<script async custom-element="amp-video" src="https://cdn.ampproject.org/v0/amp-video-0.1.js"></script>
|
16 |
+
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
|
17 |
+
</head>
|
18 |
+
<body class="ia2amp-body">
|
19 |
+
<header class="ia2amp-header">
|
20 |
+
<div class="ia2amp-cover-image">
|
21 |
+
<amp-img class="ia2amp-header-cover-img" src="https://s3.amazonaws.com/instantarticles/examples/fb_beach_flower.jpg" width="380" height="240"></amp-img>
|
22 |
+
</div>
|
23 |
+
<div class="ia2amp-header-bar"></div>
|
24 |
+
<div class="ia2amp-spacing after-header-bar before-header-category"></div>
|
25 |
+
<h2 class="ia2amp-header-category">
|
26 |
+
Introduction
|
27 |
+
</h2>
|
28 |
+
<div class="ia2amp-spacing after-header-category before-header-h1"></div>
|
29 |
+
<h1 class="ia2amp-header-h1"> Instant Articles </h1>
|
30 |
+
<div class="ia2amp-spacing after-header-h1 before-header-h2"></div>
|
31 |
+
<h2 class="ia2amp-header-h2">Get familiar with your new storytelling tools. Make your media come alive, and keep readers coming back for more</h2>
|
32 |
+
<div class="ia2amp-spacing after-header-h2 before-header-author"></div>
|
33 |
+
<h3 class="ia2amp-header-author">By
|
34 |
+
Instant Articles Team
|
35 |
+
</h3>
|
36 |
+
<div class="ia2amp-spacing after-header-author before-header-date"></div>
|
37 |
+
<h3 class="ia2amp-header-date">February 04, 2016</h3>
|
38 |
+
<div class="ia2amp-spacing after-header-date before-p"></div>
|
39 |
+
</header>
|
40 |
+
<article class="ia2amp-article">
|
41 |
+
<p class="ia2amp-p">Yes, it’s true. Instant Articles open on mobile devices really quickly.</p>
|
42 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
43 |
+
<p class="ia2amp-p">But that’s just the beginning of it. Instant Articles are buttery smooth and addictive. Once you’ve read a few, you’ll never want to go back.</p>
|
44 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
45 |
+
<p class="ia2amp-p">The Facebook-native format is packed with innovative ways to tell deeply engaging, interactive stories. Thanks to the powerful, built-in media features and customizable typographic elements, Instant Articles gives you awesome new editorial tools to use while delivering a decidedly superior experience for your readers.</p>
|
46 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
47 |
+
<p class="ia2amp-p">More than half of Instant Articles readers scroll 90% of the way through their articles, while, historically, 38% of web readers haven’t made it past the first line of other online media.</p>
|
48 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
49 |
+
<p class="ia2amp-p">This article gives you a quick highlight tour of Instant Articles features and shows you how to make magic with the format. You’ll be happy to find that Instant Articles are not only delightful but surprisingly easy to create.</p>
|
50 |
+
<div class="ia2amp-spacing after-p before-h1"></div>
|
51 |
+
<h1 class="ia2amp-h1"> Photography </h1>
|
52 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
53 |
+
<p class="ia2amp-p">All photographs are interactive by default. When tapped an image will expand to fill the screen, then readers can tilt the phone back and forth to explore the margins.</p>
|
54 |
+
<div class="ia2amp-spacing after-p"></div>
|
55 |
+
<div class="ia2amp-image">
|
56 |
+
<figure class="ia2amp-figure">
|
57 |
+
<amp-img layout="responsive" src="https://s3.amazonaws.com/instantarticles/examples/fb_rails.jpg" width="380" height="240"></amp-img>
|
58 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>Photograph Example</h1>
|
59 |
+
Tap this image to make it expand. Tilt the phone right and left and see what happens.
|
60 |
+
|
61 |
+
<cite>Eduardo Tardin/Facebook</cite></figcaption>
|
62 |
+
</figure>
|
63 |
+
</div>
|
64 |
+
<div class="ia2amp-spacing before-p"></div>
|
65 |
+
<p class="ia2amp-p">To return to the article, tap the image again. The interactive mode works best with high-definition photos containing rich visual information. For low-resolution media, we recommend using the non-interactive setting so that it will remain in-line in the correct aspect ratio and your readers won’t tap into a mushy, pixelated experience.</p>
|
66 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
67 |
+
<h2 class="ia2amp-h2">Social Feedback</h2>
|
68 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
69 |
+
<p class="ia2amp-p">You can add native Facebook Likes and Comments buttons to images, giving readers extra opportunities to engage with individual elements in your stories. This feature currently works for photographs and videos.</p>
|
70 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
71 |
+
<h2 class="ia2amp-h2">Slideshow</h2>
|
72 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
73 |
+
<p class="ia2amp-p">You can also group collections of images into slideshows that scroll horizontally.</p>
|
74 |
+
<div class="ia2amp-spacing after-p before-slideshow"></div>
|
75 |
+
<div class="ia2amp-slideshow">
|
76 |
+
<figure class="ia2amp-figure">
|
77 |
+
<amp-carousel width="380" height="240">
|
78 |
+
<div class="ia2amp-slideshow-image">
|
79 |
+
<figure class="ia2amp-figure">
|
80 |
+
<amp-img src="https://s3.amazonaws.com/instantarticles/examples/fb_beach_flower.jpg" width="380" height="240"></amp-img>
|
81 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1> 1/5
|
82 |
+
This caption becomes visible once you enter the slideshow by tapping the first image.
|
83 |
+
Eduardo Tardin/Facebook
|
84 |
+
</h1></figcaption>
|
85 |
+
</figure>
|
86 |
+
</div>
|
87 |
+
<div class="ia2amp-slideshow-image">
|
88 |
+
<figure class="ia2amp-figure">
|
89 |
+
<amp-img src="https://s3.amazonaws.com/instantarticles/examples/fb_rocks.jpg" width="380" height="240"></amp-img>
|
90 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1> 2/5
|
91 |
+
Each photo in a slideshow can have its own caption.
|
92 |
+
Eduardo Tardin/Facebook
|
93 |
+
</h1></figcaption>
|
94 |
+
</figure>
|
95 |
+
</div>
|
96 |
+
<div class="ia2amp-slideshow-image">
|
97 |
+
<figure class="ia2amp-figure">
|
98 |
+
<amp-img src="https://s3.amazonaws.com/instantarticles/examples/fb_sunset.jpg" width="380" height="240"></amp-img>
|
99 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1> 3/5
|
100 |
+
This is the third photo of the slideshow.
|
101 |
+
Eduardo Tardin/Facebook
|
102 |
+
</h1></figcaption>
|
103 |
+
</figure>
|
104 |
+
</div>
|
105 |
+
<div class="ia2amp-slideshow-image">
|
106 |
+
<figure class="ia2amp-figure">
|
107 |
+
<amp-img src="https://s3.amazonaws.com/instantarticles/examples/fb_cave_ocean.jpg" width="380" height="240"></amp-img>
|
108 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1> 4/5
|
109 |
+
The fourth photo of the slideshow.
|
110 |
+
Eduardo Tardin/Facebook
|
111 |
+
</h1></figcaption>
|
112 |
+
</figure>
|
113 |
+
</div>
|
114 |
+
<div class="ia2amp-slideshow-image">
|
115 |
+
<figure class="ia2amp-figure">
|
116 |
+
<amp-img src="https://s3.amazonaws.com/instantarticles/examples/fb_boat.jpg" width="380" height="240"></amp-img>
|
117 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1> 5/5
|
118 |
+
The fifth photo of the slideshow.
|
119 |
+
Eduardo Tardin/Facebook
|
120 |
+
</h1></figcaption>
|
121 |
+
</figure>
|
122 |
+
</div>
|
123 |
+
</amp-carousel>
|
124 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>Slideshow Example</h1>
|
125 |
+
The slideshow caption is visible in-line in the main body of the story. You can also add individual captions for each image in the gallery, which become visible only after entering the slideshow. Tap on the first image to open it.
|
126 |
+
</figcaption>
|
127 |
+
</figure>
|
128 |
+
</div>
|
129 |
+
<div class="ia2amp-spacing after-slideshow"></div>
|
130 |
+
<div class="ia2amp-video">
|
131 |
+
<figure class="ia2amp-figure">
|
132 |
+
<amp-video src="https://s3.amazonaws.com/instantarticles/examples/fb_movie_pt.mov" width="380" height="240"></amp-video>
|
133 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1> 6+ </h1>
|
134 |
+
Adendum and mixed video + image in a slideshow.
|
135 |
+
|
136 |
+
<cite>Instant Articles/Facebook</cite></figcaption>
|
137 |
+
</figure>
|
138 |
+
</div>
|
139 |
+
<div class="ia2amp-spacing before-h1"></div>
|
140 |
+
<h1 class="ia2amp-h1">Video</h1>
|
141 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
142 |
+
<p class="ia2amp-p">Native videos in Instant Articles play automatically, by default, as soon as they scroll into view on the reader’s screen—a powerful way to make the page come to life. You have many options for presenting videos. Here’s an interactive one with play controls. </p>
|
143 |
+
<div class="ia2amp-spacing after-p"></div>
|
144 |
+
<div class="ia2amp-video">
|
145 |
+
<figure class="ia2amp-figure">
|
146 |
+
<amp-video src="https://s3.amazonaws.com/instantarticles/examples/fb_hiperlapse_sp.mp4" width="380" height="240"></amp-video>
|
147 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1><b>2:57</b> | Interactive Video Example</h1>
|
148 |
+
When this video first scrolls into sight, it appears in-line in its correct aspect ratio and plays automatically with the volume off. By tapping it, the video expands to fill the screen and can be turned to view horizontally. The soundtrack becomes audible, and play controls, with scrubber, are accessible.
|
149 |
+
</figcaption>
|
150 |
+
</figure>
|
151 |
+
</div>
|
152 |
+
<div class="ia2amp-spacing before-p"></div>
|
153 |
+
<p class="ia2amp-p"> To hide play controls, tap the video again; the pause/play icons and scrubber can be toggled on and off this way. You can also rotate the phone sideways while the video is in-line to view it in landscape mode.</p>
|
154 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
155 |
+
<p class="ia2amp-p">Alternately, try using a short video to add color and mood to a story. Disable the play controls and set it to loop with a cross-fade.</p>
|
156 |
+
<div class="ia2amp-spacing after-p"></div>
|
157 |
+
<div class="ia2amp-video">
|
158 |
+
<figure class="ia2amp-figure">
|
159 |
+
<amp-video src="https://s3.amazonaws.com/instantarticles/examples/fb_hiperlapse_sp.mp4" width="380" height="240"></amp-video>
|
160 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>Ambient Video Example</h1>
|
161 |
+
Tap the video to expand and then tilt to explore. Think of this kind of interactive video as a moving photograph. It gives curious readers an opportunity to explore a living scene and become immersed in a new way. Looping continuously, the video adds atmosphere to an article and can be used to emphasize a section break.
|
162 |
+
<cite>Eduardo Tardin/Facebook</cite></figcaption>
|
163 |
+
</figure>
|
164 |
+
</div>
|
165 |
+
<div class="ia2amp-spacing before-p"></div>
|
166 |
+
<p class="ia2amp-p">You can also ingest GIFs natively—no need for third-party players.</p>
|
167 |
+
<div class="ia2amp-spacing after-p"></div>
|
168 |
+
<div class="ia2amp-image">
|
169 |
+
<figure class="ia2amp-figure">
|
170 |
+
<amp-img layout="responsive" src="https://s3.amazonaws.com/instantarticles/examples/fb_cat.gif" width="380" height="240"></amp-img>
|
171 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-large ia2amp-op-vertical-below">
|
172 |
+
We know GIFs are exciting, but please try to calm down.
|
173 |
+
|
174 |
+
<cite>
|
175 |
+
Eduardo Tardin/Facebook
|
176 |
+
</cite></figcaption>
|
177 |
+
</figure>
|
178 |
+
</div>
|
179 |
+
<div class="ia2amp-spacing before-h1"></div>
|
180 |
+
<h1 class="ia2amp-h1"> Cartography </h1>
|
181 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
182 |
+
<p class="ia2amp-p">Another great way to add information and texture to your stories: maps! Instant Articles has two cartographic features that deliver additional context to news and help readers situate it in the wider world.</p>
|
183 |
+
<div class="ia2amp-spacing after-p"></div>
|
184 |
+
<div class="ia2amp-image">
|
185 |
+
<figure class="ia2amp-figure">
|
186 |
+
<amp-img layout="responsive" src="https://s3.amazonaws.com/instantarticles/examples/fb_volcano.jpg" width="380" height="240"></amp-img>
|
187 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-small"><h1>Geotagging Example</h1>
|
188 |
+
Major news events often occur in locations unfamiliar to readers. Photos and videos in Instant Articles can easily be geotagged, such as this image of Mount Etna, so that readers can tap the globe icon to see where the action is happening. By pinching this map, you can zoom in to see details on the snow-capped slopes of the volcano or zoom out far enough to see the boot of Italy—and beyond.
|
189 |
+
|
190 |
+
<cite>gnuckx/Flickr</cite></figcaption>
|
191 |
+
</figure>
|
192 |
+
</div>
|
193 |
+
<div class="ia2amp-spacing before-p"></div>
|
194 |
+
<p class="ia2amp-p">Rotating contour maps can be inserted in stories with a simple code block, giving readers a bird’s-eye view of topography and the ability to pinch and zoom in or out.</p>
|
195 |
+
<div class="ia2amp-spacing after-p"></div>
|
196 |
+
<div></div>
|
197 |
+
<div class="ia2amp-spacing before-h1"></div>
|
198 |
+
<h1 class="ia2amp-h1">Embeds</h1>
|
199 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
200 |
+
<p class="ia2amp-p">Instant Articles deliver rich, multimedia stories even when you don’t own all the source media files. You might want to publish evolving news about an incident captured in video on YouTube. Or a listicle made up entirely of Tweets, Facebook posts, Instagrams and Vines. Instant Articles seamlessly integrate all types of web-based embeds, including your own interactive graphics, video players, ads and social media, such as this post from Mark Zuckerberg.</p>
|
201 |
+
<div class="ia2amp-spacing after-p before-h1"></div>
|
202 |
+
<h1 class="ia2amp-h1">Typography</h1>
|
203 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
204 |
+
<p class="ia2amp-p">Don’t forget to make use of pull quotes and block quotes. Give the quote extra punch by customizing its color using the <a href="https://developers.facebook.com/docs/instant-articles/design/creating-styles">Style Editor</a>. </p>
|
205 |
+
<div class="ia2amp-spacing after-p before-pullquote"></div>
|
206 |
+
<aside class="ia2amp-pullquote">
|
207 |
+
Being connected means having opportunity. We’re connecting the world so one day everyone can fulfill their dreams.
|
208 |
+
|
209 |
+
<cite>Mark Zuckerberg</cite></aside>
|
210 |
+
<div class="ia2amp-spacing after-pullquote before-p"></div>
|
211 |
+
<p class="ia2amp-p">To include a long excerpt from another source, such as the following example from Sheryl Sandberg’s <em>Lean In: Women, Work, and the Will to Lead</em>, use a block quote. It’s in the same style as the body text but set off with a rule on the left margin.</p>
|
212 |
+
<div class="ia2amp-spacing after-p before-blockquote"></div>
|
213 |
+
<blockquote class="ia2amp-blockquote">
|
214 |
+
But knowing that things could be worse should not stop us from trying to make them better. When the suffragettes marched in the streets, they envisioned a century later, men and women would be truly equal. A century later, we are still squinting, trying to bring that vision into focus.
|
215 |
+
</blockquote>
|
216 |
+
<div class="ia2amp-spacing after-blockquote before-h1"></div>
|
217 |
+
<h1 class="ia2amp-h1">In-line Related Articles</h1>
|
218 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
219 |
+
<div class="ia2amp-spacing after-p before-spacing after-p"></div>
|
220 |
+
<p class="ia2amp-related-articles">Pique reader interest in more articles from your publication with an in-line related articles element. Choose up to 3 stories and guide readers to other engaging articles. </p>
|
221 |
+
<div class="ia2amp-spacing after-spacing after-p before-p"></div>
|
222 |
+
<p class="ia2amp-p">You can also add a related articles element in the footer. Scroll down to the bottom of the story to see that feature in action.</p>
|
223 |
+
<div class="ia2amp-spacing after-p before-h1"></div>
|
224 |
+
<h1 class="ia2amp-h1">Customizing the Formatting</h1>
|
225 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
226 |
+
<p class="ia2amp-p">To create advanced effects, you can play with different layout settings on your media elements. To create full-bleed layouts with a magazine-like feel, for example, you can crop a series of photos vertically and stack them in-line without spacing or text in between.</p>
|
227 |
+
<div class="ia2amp-spacing after-p before-h2"></div>
|
228 |
+
<h2 class="ia2amp-h2">Fullscreen Media</h2>
|
229 |
+
<div class="ia2amp-spacing after-h2 before-p"></div>
|
230 |
+
<p class="ia2amp-p"> Another option is to set images or videos to fullscreen mode, in which case the art crops automatically so that it bleeds off the screen frame and snaps gently into place. It’s kind of like a digital gatefold, giving readers a chance to enjoy a special moment in the story. See how this next image pauses briefly when you scroll it into view.</p>
|
231 |
+
<div class="ia2amp-spacing after-p"></div>
|
232 |
+
<div class="ia2amp-image">
|
233 |
+
<figure class="ia2amp-figure">
|
234 |
+
<amp-img layout="responsive" src="https://s3.amazonaws.com/instantarticles/examples/fb_station.jpg" width="380" height="240"></amp-img>
|
235 |
+
<figcaption class="ia2amp-figcaption ia2amp-op-large"><h1> “I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can’t see from the center.” </h1>
|
236 |
+
Kurt Vonnegut
|
237 |
+
</figcaption>
|
238 |
+
</figure>
|
239 |
+
</div>
|
240 |
+
<div class="ia2amp-spacing before-p"></div>
|
241 |
+
<p class="ia2amp-p">Visit the <a href="https://developers.facebook.com/docs/instant-articles/guides/design">Instant Articles Design Guide</a> to learn how to customize your typography and layout. The <a href="https://developers.facebook.com/docs/instant-articles/reference">Format Reference</a> describes the HTML-5 markup used to set interactive features and vary the presentation modes for media.</p>
|
242 |
+
<div class="ia2amp-spacing after-p before-h1"></div>
|
243 |
+
<h1 class="ia2amp-h1">Twitter embed</h1>
|
244 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
245 |
+
<p class="ia2amp-p">You can create any embed for other social networks as well. <a href="https://twitter.com/theellenshow/status/440322224407314432">Ellen #oscar</a>. </p>
|
246 |
+
<div class="ia2amp-spacing after-p before-h1"></div>
|
247 |
+
<h1 class="ia2amp-h1">Next</h1>
|
248 |
+
<div class="ia2amp-spacing after-h1 before-p"></div>
|
249 |
+
<p class="ia2amp-p">Get inspired by some of the incredible showcase articles that we’ve posted on the <a href="https://www.facebook.com/instantArticles/?fref=ts">Instant Articles Facebook page</a>. Whether you want to create a specially designed long read filled with multimedia elements or to quickly publish an on-the-scene video connected to an evolving news story, Instant Articles has the features and flexibility to help you deliver stories that not only load fast but are hard to forget.</p>
|
250 |
+
<div class="ia2amp-spacing after-p before-p"></div>
|
251 |
+
<p class="ia2amp-p">Look at this format as a tool box. How you choose to use Instant Articles and what you make with them are limited only by your imagination. We plan on continuously adding tools to the kit, based on your experiences and feedback. Our team is eager to work with publishers, bloggers and independent journalists to help you deliver your stories to new audiences with the most impact and multimedia goodness possible.</p>
|
252 |
+
<div class="ia2amp-spacing after-p"></div>
|
253 |
+
<footer class="ia2amp-footer">
|
254 |
+
<small>© Facebook</small>
|
255 |
+
</footer>
|
256 |
+
</article>
|
257 |
+
</body>
|
258 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/articles/tutorial-instant-article.html
ADDED
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html lang="en">
|
2 |
+
<head>
|
3 |
+
<meta charset="utf-8">
|
4 |
+
<link rel="canonical" href="http://blog.wod.expert/example1">
|
5 |
+
<link rel="stylesheet" title="default" href="#">
|
6 |
+
<title>Instant Articles</title>
|
7 |
+
<meta property="fb:article_style" content="default">
|
8 |
+
</head>
|
9 |
+
<body>
|
10 |
+
<article>
|
11 |
+
<header>
|
12 |
+
<!-- The header image shown inside your article -->
|
13 |
+
<figure>
|
14 |
+
<figure data-feedback="fb:likes,fb:comments">
|
15 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_beach_flower.jpg"/>
|
16 |
+
<figcaption class="op-vertical-bottom">
|
17 |
+
<h1 class="op-vertical-bottom"> 1/5 </h1>
|
18 |
+
This caption becomes visible once you enter the slideshow by tapping the first image.
|
19 |
+
<cite class="op-vertical-bottom">Eduardo Tardin/Facebook</cite>
|
20 |
+
</figcaption>
|
21 |
+
</figure>
|
22 |
+
</figure>
|
23 |
+
<!-- The title and subtitle shown in your article -->
|
24 |
+
<h1> Instant Articles </h1>
|
25 |
+
<h2>Get familiar with your new storytelling tools. Make your media come alive, and keep readers coming back for more</h2>
|
26 |
+
<!-- A kicker for your article -->
|
27 |
+
<h3 class="op-kicker">
|
28 |
+
Introduction
|
29 |
+
</h3>
|
30 |
+
<!-- The author of your article -->
|
31 |
+
<address>
|
32 |
+
Instant Articles Team
|
33 |
+
</address>
|
34 |
+
<!-- The published and last modified time stamps -->
|
35 |
+
<time class="op-published" dateTime="2016-2-04T08:00">February 4th 2016, 8:00 AM</time>
|
36 |
+
<time class="op-modified" dateTime="2016-2-04T08:00">February 4th 2016, 8:00 AM</time>
|
37 |
+
</header>
|
38 |
+
<p>Yes, it’s true. Instant Articles open on mobile devices really quickly.</p>
|
39 |
+
<p>But that’s just the beginning of it. Instant Articles are buttery smooth and addictive. Once you’ve read a few, you’ll never want to go back.</p>
|
40 |
+
<p>The Facebook-native format is packed with innovative ways to tell deeply engaging, interactive stories. Thanks to the powerful, built-in media features and customizable typographic elements, Instant Articles gives you awesome new editorial tools to use while delivering a decidedly superior experience for your readers.</p>
|
41 |
+
<p>More than half of Instant Articles readers scroll 90% of the way through their articles, while, historically, 38% of web readers haven’t made it past the first line of other online media.</p>
|
42 |
+
<p>This article gives you a quick highlight tour of Instant Articles features and shows you how to make magic with the format. You’ll be happy to find that Instant Articles are not only delightful but surprisingly easy to create.</p>
|
43 |
+
<h1> Photography </h1>
|
44 |
+
<p>All photographs are interactive by default. When tapped an image will expand to fill the screen, then readers can tilt the phone back and forth to explore the margins.</p>
|
45 |
+
<!-- Photo with caption -->
|
46 |
+
<figure data-feedback="fb:likes, fb:comments">
|
47 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_rails.jpg" />
|
48 |
+
<figcaption>
|
49 |
+
<h1>Photograph Example</h1>
|
50 |
+
Tap this image to make it expand. Tilt the phone right and left and see what happens.
|
51 |
+
<cite>Eduardo Tardin/Facebook</cite>
|
52 |
+
</figcaption>
|
53 |
+
</figure>
|
54 |
+
<p>To return to the article, tap the image again. The interactive mode works best with high-definition photos containing rich visual information. For low-resolution media, we recommend using the non-interactive setting so that it will remain in-line in the correct aspect ratio and your readers won’t tap into a mushy, pixelated experience.</p>
|
55 |
+
<h2>Social Feedback</h2>
|
56 |
+
<p>You can add native Facebook Likes and Comments buttons to images, giving readers extra opportunities to engage with individual elements in your stories. This feature currently works for photographs and videos.</p>
|
57 |
+
<h2>Slideshow</h2>
|
58 |
+
<p>You can also group collections of images into slideshows that scroll horizontally.</p>
|
59 |
+
<!-- Slideshow with multiple captions-->
|
60 |
+
<figure class="op-slideshow">
|
61 |
+
<figure data-feedback="fb:likes,fb:comments">
|
62 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_beach_flower.jpg"/>
|
63 |
+
<figcaption class="op-vertical-bottom">
|
64 |
+
<h1 class="op-vertical-bottom"> 1/5 </h1>
|
65 |
+
This caption becomes visible once you enter the slideshow by tapping the first image.
|
66 |
+
<cite class="op-vertical-bottom">Eduardo Tardin/Facebook</cite>
|
67 |
+
</figcaption>
|
68 |
+
</figure>
|
69 |
+
<figure data-feedback="fb:likes,fb:comments">
|
70 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_rocks.jpg" />
|
71 |
+
<figcaption class="op-vertical-bottom">
|
72 |
+
<h1 class=op-vertical-bottom> 2/5 </h1>
|
73 |
+
Each photo in a slideshow can have its own caption.
|
74 |
+
<cite class="op-vertical-bottom">Eduardo Tardin/Facebook</cite>
|
75 |
+
</figcaption>
|
76 |
+
</figure>
|
77 |
+
<figure data-feedback="fb:likes,fb:comments">
|
78 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_sunset.jpg" />
|
79 |
+
<figcaption class="op-vertical-bottom">
|
80 |
+
<h1 class="op-vertical-bottom"> 3/5 </h1>
|
81 |
+
This is the third photo of the slideshow.
|
82 |
+
<cite class="op-vertical-bottom">Eduardo Tardin/Facebook</cite>
|
83 |
+
</figcaption>
|
84 |
+
</figure>
|
85 |
+
<figure data-feedback="fb:likes,fb:comments">
|
86 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_cave_ocean.jpg" />
|
87 |
+
<figcaption class="op-vertical-bottom">
|
88 |
+
<h1 class=op-vertical-bottom> 4/5 </h1>
|
89 |
+
The fourth photo of the slideshow.
|
90 |
+
<cite class="op-vertical-bottom">Eduardo Tardin/Facebook</cite>
|
91 |
+
</figcaption>
|
92 |
+
</figure>
|
93 |
+
<figure data-feedback="fb:likes,fb:comments">
|
94 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_boat.jpg" />
|
95 |
+
<figcaption class="op-vertical-bottom">
|
96 |
+
<h1 class=op-vertical-bottom> 5/5 </h1>
|
97 |
+
The fifth photo of the slideshow.
|
98 |
+
<cite class="op-vertical-bottom">Eduardo Tardin/Facebook</cite>
|
99 |
+
</figcaption>
|
100 |
+
</figure>
|
101 |
+
<figcaption>
|
102 |
+
<h1>Slideshow Example</h1>
|
103 |
+
The slideshow caption is visible in-line in the main body of the story. You can also add individual captions for each image in the gallery, which become visible only after entering the slideshow. Tap on the first image to open it.
|
104 |
+
</figcaption>
|
105 |
+
</figure>
|
106 |
+
<figure data-mode=aspect-fit>
|
107 |
+
<video loop>
|
108 |
+
<source src="https://s3.amazonaws.com/instantarticles/examples/fb_movie_pt.mov" type="video/mov" />
|
109 |
+
</video>
|
110 |
+
<figcaption class="op-vertical-bottom">
|
111 |
+
<h1 class=op-vertical-bottom> 6+ </h1>
|
112 |
+
Adendum and mixed video + image in a slideshow.
|
113 |
+
<cite class="op-vertical-bottom">Instant Articles/Facebook</cite>
|
114 |
+
</figcaption>
|
115 |
+
</figure>
|
116 |
+
<h1>Video</h1>
|
117 |
+
<p>Native videos in Instant Articles play automatically, by default, as soon as they scroll into view on the reader’s screen—a powerful way to make the page come to life. You have many options for presenting videos. Here’s an interactive one with play controls. </p>
|
118 |
+
<!-- An interactive video with play controls -->
|
119 |
+
<figure data-feedback="fb:likes, fb:comments">
|
120 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_night.jpg" />
|
121 |
+
<video controls>
|
122 |
+
<source src="https://s3.amazonaws.com/instantarticles/examples/fb_hiperlapse_sp.mp4" />
|
123 |
+
</video>
|
124 |
+
<figcaption>
|
125 |
+
<h1><b>2:57</b> | Interactive Video Example</h1>
|
126 |
+
When this video first scrolls into sight, it appears in-line in its correct aspect ratio and plays automatically with the volume off. By tapping it, the video expands to fill the screen and can be turned to view horizontally. The soundtrack becomes audible, and play controls, with scrubber, are accessible.
|
127 |
+
</figcaption>
|
128 |
+
</figure>
|
129 |
+
<p> To hide play controls, tap the video again; the pause/play icons and scrubber can be toggled on and off this way. You can also rotate the phone sideways while the video is in-line to view it in landscape mode.</p>
|
130 |
+
<p>Alternately, try using a short video to add color and mood to a story. Disable the play controls and set it to loop with a cross-fade.</p>
|
131 |
+
<!-- A video set to loop and cross-fade with play controls disabled -->
|
132 |
+
<figure data-feedback="fb:likes, fb:comments" data-mode="aspect-fit">
|
133 |
+
<video loop data-fade>
|
134 |
+
<source src="https://s3.amazonaws.com/instantarticles/examples/fb_hiperlapse_sp.mp4" />
|
135 |
+
</video>
|
136 |
+
<figcaption>
|
137 |
+
<h1>Ambient Video Example</h1>
|
138 |
+
Tap the video to expand and then tilt to explore. Think of this kind of interactive video as a moving photograph. It gives curious readers an opportunity to explore a living scene and become immersed in a new way. Looping continuously, the video adds atmosphere to an article and can be used to emphasize a section break. <cite>Eduardo Tardin/Facebook</cite>
|
139 |
+
</figcaption>
|
140 |
+
</figure>
|
141 |
+
<p>You can also ingest GIFs natively—no need for third-party players.</p>
|
142 |
+
<!-- Native GIF example -->
|
143 |
+
<figure data-feedback="fb:likes, fb:comments">
|
144 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_cat.gif" />
|
145 |
+
<figcaption class="op-vertical-below op-large">
|
146 |
+
We know GIFs are exciting, but please try to calm down.
|
147 |
+
<cite>
|
148 |
+
Eduardo Tardin/Facebook
|
149 |
+
</cite>
|
150 |
+
</figcaption>
|
151 |
+
</figure>
|
152 |
+
<h1> Cartography </h1>
|
153 |
+
<p>Another great way to add information and texture to your stories: maps! Instant Articles has two cartographic features that deliver additional context to news and help readers situate it in the wider world.</p>
|
154 |
+
<!-- A geotagged image within your article -->
|
155 |
+
<figure data-feedback="fb:likes, fb:comments">
|
156 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_volcano.jpg" />
|
157 |
+
<figcaption>
|
158 |
+
<h1>Geotagging Example</h1>
|
159 |
+
Major news events often occur in locations unfamiliar to readers. Photos and videos in Instant Articles can easily be geotagged, such as this image of Mount Etna, so that readers can tap the globe icon to see where the action is happening. By pinching this map, you can zoom in to see details on the snow-capped slopes of the volcano or zoom out far enough to see the boot of Italy—and beyond.
|
160 |
+
<cite>gnuckx/Flickr</cite>
|
161 |
+
</figcaption>
|
162 |
+
<script type="application/json" class="op-geotag">
|
163 |
+
{
|
164 |
+
"type": "Feature",
|
165 |
+
"geometry":{
|
166 |
+
"type": "Point",
|
167 |
+
"coordinates":[37.7550, 14.9950] },
|
168 |
+
"properties":{
|
169 |
+
"title": "Mount Etna, Sicily",
|
170 |
+
"style": "hybrid",
|
171 |
+
"radius": 10000
|
172 |
+
}
|
173 |
+
}
|
174 |
+
</script>
|
175 |
+
</figure>
|
176 |
+
<p>Rotating contour maps can be inserted in stories with a simple code block, giving readers a bird’s-eye view of topography and the ability to pinch and zoom in or out.</p>
|
177 |
+
<!-- A map within your article -->
|
178 |
+
<figure class="op-map">
|
179 |
+
<figcaption>
|
180 |
+
<h1>Map Example</h1>
|
181 |
+
The pin on this map designates Facebook Media Central’s offices in New York City.
|
182 |
+
</figcaption>
|
183 |
+
<script type="application/json" class="op-geotag">
|
184 |
+
{
|
185 |
+
"type": "Feature",
|
186 |
+
"geometry":
|
187 |
+
{
|
188 |
+
"type": "Point",
|
189 |
+
"coordinates": [ [40.730852, -73.991364], [40.730852, -73.991364] ]
|
190 |
+
},
|
191 |
+
"properties":
|
192 |
+
{
|
193 |
+
"title": "770 Broadway, Manhattan, New York",
|
194 |
+
"radius": 100000,
|
195 |
+
"pivot": true,
|
196 |
+
"style": "satellite",
|
197 |
+
}
|
198 |
+
}
|
199 |
+
</script>
|
200 |
+
</figure>
|
201 |
+
<h1>Embeds</h1>
|
202 |
+
<p>Instant Articles deliver rich, multimedia stories even when you don’t own all the source media files. You might want to publish evolving news about an incident captured in video on YouTube. Or a listicle made up entirely of Tweets, Facebook posts, Instagrams and Vines. Instant Articles seamlessly integrate all types of web-based embeds, including your own interactive graphics, video players, ads and social media, such as this post from Mark Zuckerberg.</p>
|
203 |
+
<!-- Embedded social media example -->
|
204 |
+
<figure class="op-interactive">
|
205 |
+
<iframe>
|
206 |
+
<!-- Include social media embed code here -->
|
207 |
+
<div id="fb-root"></div>
|
208 |
+
<script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.3"; fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script>
|
209 |
+
<div class="fb-post" data-href="https://www.facebook.com/zuck/posts/10102531565693851" data-width="500">
|
210 |
+
<div class="fb-xfbml-parse-ignore">
|
211 |
+
<blockquote cite="https://www.facebook.com/zuck/posts/10102531565693851">
|
212 |
+
<p>The force is strong with this one.</p>
|
213 |
+
Posted by <a href="https://www.facebook.com/zuck">Mark Zuckerberg</a> on <a href="https://www.facebook.com/zuck/posts/10102531565693851">Thursday, December 17, 2015</a>
|
214 |
+
</blockquote>
|
215 |
+
</div>
|
216 |
+
</div>
|
217 |
+
</iframe>
|
218 |
+
</figure>
|
219 |
+
<h1>Typography</h1>
|
220 |
+
<p>Don’t forget to make use of pull quotes and block quotes. Give the quote extra punch by customizing its color using the <a href="https://developers.facebook.com/docs/instant-articles/design/creating-styles">Style Editor</a>. </p>
|
221 |
+
<!-- A pull quote within your article -->
|
222 |
+
<aside>
|
223 |
+
Being connected means having opportunity. We’re connecting the world so one day everyone can fulfill their dreams.
|
224 |
+
<cite>Mark Zuckerberg</cite>
|
225 |
+
</aside>
|
226 |
+
<p>To include a long excerpt from another source, such as the following example from Sheryl Sandberg’s <em>Lean In: Women, Work, and the Will to Lead</em>, use a block quote. It’s in the same style as the body text but set off with a rule on the left margin.</p>
|
227 |
+
<!-- A block quote within your article -->
|
228 |
+
<blockquote>
|
229 |
+
But knowing that things could be worse should not stop us from trying to make them better. When the suffragettes marched in the streets, they envisioned a century later, men and women would be truly equal. A century later, we are still squinting, trying to bring that vision into focus.
|
230 |
+
</blockquote>
|
231 |
+
<h1>In-line Related Articles</h1>
|
232 |
+
<p>Pique reader interest in more articles from your publication with an in-line related articles element. Choose up to 3 stories and guide readers to other engaging articles. </p>
|
233 |
+
<ul class="op-related-articles" title="Learn more about Instant Articles">
|
234 |
+
<li><a href="http://instantarticles.fb.com"></a></li>
|
235 |
+
<li><a href="https://www.facebook.com/facebookmedia"></a></li>
|
236 |
+
</ul>
|
237 |
+
<p>You can also add a related articles element in the footer. Scroll down to the bottom of the story to see that feature in action.</p>
|
238 |
+
<h1>Customizing the Formatting</h1>
|
239 |
+
<p>To create advanced effects, you can play with different layout settings on your media elements. To create full-bleed layouts with a magazine-like feel, for example, you can crop a series of photos vertically and stack them in-line without spacing or text in between.</p>
|
240 |
+
<h2>Fullscreen Media</h2>
|
241 |
+
<p> Another option is to set images or videos to fullscreen mode, in which case the art crops automatically so that it bleeds off the screen frame and snaps gently into place. It’s kind of like a digital gatefold, giving readers a chance to enjoy a special moment in the story. See how this next image pauses briefly when you scroll it into view.</p>
|
242 |
+
<!-- A fullscreen image that snaps into place -->
|
243 |
+
<figure data-mode="fullscreen">
|
244 |
+
<img src="https://s3.amazonaws.com/instantarticles/examples/fb_station.jpg" />
|
245 |
+
<figcaption class="op-vertical-bottom op-large">
|
246 |
+
<h1 class="op-vertical-bottom op-extra-large"> “I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can’t see from the center.” </h1>
|
247 |
+
Kurt Vonnegut
|
248 |
+
</figcaption>
|
249 |
+
</figure>
|
250 |
+
<p>Visit the <a href="https://developers.facebook.com/docs/instant-articles/guides/design">Instant Articles Design Guide</a> to learn how to customize your typography and layout. The <a href="https://developers.facebook.com/docs/instant-articles/reference">Format Reference</a> describes the HTML-5 markup used to set interactive features and vary the presentation modes for media.</p>
|
251 |
+
<h1>Twitter embed</h1>
|
252 |
+
<p>You can create any embed for other social networks as well. <a href="https://twitter.com/theellenshow/status/440322224407314432">Ellen #oscar</a>. </p>
|
253 |
+
<figure class="op-interactive">
|
254 |
+
<iframe>
|
255 |
+
<blockquote class="twitter-tweet" data-lang="pt">
|
256 |
+
<p lang="en" dir="ltr">If only Bradley's arm was longer. Best photo ever. <a href="https://twitter.com/hashtag/oscars?src=hash">#oscars</a> <a href="http://t.co/C9U5NOtGap">pic.twitter.com/C9U5NOtGap</a></p>
|
257 |
+
— Ellen DeGeneres (@TheEllenShow) <a href="https://twitter.com/TheEllenShow/status/440322224407314432">3 de março de 2014</a>
|
258 |
+
</blockquote>
|
259 |
+
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
|
260 |
+
</iframe>
|
261 |
+
</figure>
|
262 |
+
<h1>Next</h1>
|
263 |
+
<p>Get inspired by some of the incredible showcase articles that we’ve posted on the <a href="https://www.facebook.com/instantArticles/?fref=ts">Instant Articles Facebook page</a>. Whether you want to create a specially designed long read filled with multimedia elements or to quickly publish an on-the-scene video connected to an evolving news story, Instant Articles has the features and flexibility to help you deliver stories that not only load fast but are hard to forget.</p>
|
264 |
+
<p>Look at this format as a tool box. How you choose to use Instant Articles and what you make with them are limited only by your imagination. We plan on continuously adding tools to the kit, based on your experiences and feedback. Our team is eager to work with publishers, bloggers and independent journalists to help you deliver your stories to new audiences with the most impact and multimedia goodness possible.</p>
|
265 |
+
<footer>
|
266 |
+
<ul class="op-related-articles">
|
267 |
+
<li><a href="https://media.fb.com/2016/10/20/bringing-360-videos-and-photos-into-instant-articles"></a></li>
|
268 |
+
<li><a href="https://media.fb.com/2014/08/25/2014-emmys/"></a></li>
|
269 |
+
</ul>
|
270 |
+
<!-- Credits for your article -->
|
271 |
+
<aside>The footer section can be used for acknowledgements, author bios, related articles, or any other supplemental information.</aside>
|
272 |
+
<!-- Copyright details for your article -->
|
273 |
+
<small>© Facebook</small>
|
274 |
+
</footer>
|
275 |
+
</article>
|
276 |
+
</body>
|
277 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/default.amp-custom.css
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
Custom CSS for default style goes here
|
3 |
+
*/
|
4 |
+
|
5 |
+
/*
|
6 |
+
p {
|
7 |
+
background-color: rgb(255,00,00);
|
8 |
+
}
|
9 |
+
*/
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/default.style.json
ADDED
@@ -0,0 +1,1128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"background_color": "#FFFFFF",
|
3 |
+
"title": {
|
4 |
+
"background_color": "#00FFFFFF",
|
5 |
+
"border": {
|
6 |
+
"bottom": {
|
7 |
+
"width": 0
|
8 |
+
},
|
9 |
+
"left": {
|
10 |
+
"width": 0
|
11 |
+
},
|
12 |
+
"right": {
|
13 |
+
"width": 0
|
14 |
+
},
|
15 |
+
"top": {
|
16 |
+
"width": 0
|
17 |
+
}
|
18 |
+
},
|
19 |
+
"capitalization": "NONE",
|
20 |
+
"color": "#000000",
|
21 |
+
"display": "INLINE",
|
22 |
+
"font": "Georgia",
|
23 |
+
"line_height_scale": 1,
|
24 |
+
"margin": {
|
25 |
+
"left": {
|
26 |
+
"scaling_factor": 1,
|
27 |
+
"size": "DOCUMENT_MARGIN"
|
28 |
+
},
|
29 |
+
"right": {
|
30 |
+
"scaling_factor": 1,
|
31 |
+
"size": "DOCUMENT_MARGIN"
|
32 |
+
}
|
33 |
+
},
|
34 |
+
"padding": {
|
35 |
+
"bottom": {
|
36 |
+
"scaling_factor": 1,
|
37 |
+
"size": "NONE"
|
38 |
+
},
|
39 |
+
"left": {
|
40 |
+
"scaling_factor": 1,
|
41 |
+
"size": "NONE"
|
42 |
+
},
|
43 |
+
"right": {
|
44 |
+
"scaling_factor": 1,
|
45 |
+
"size": "NONE"
|
46 |
+
},
|
47 |
+
"top": {
|
48 |
+
"scaling_factor": 1,
|
49 |
+
"size": "NONE"
|
50 |
+
}
|
51 |
+
},
|
52 |
+
"text_alignment": "LEFT",
|
53 |
+
"text_size_scale": 1,
|
54 |
+
"underline": "NONE"
|
55 |
+
},
|
56 |
+
"subtitle": {
|
57 |
+
"background_color": "#00FFFFFF",
|
58 |
+
"border": {
|
59 |
+
"bottom": {
|
60 |
+
"width": 0
|
61 |
+
},
|
62 |
+
"left": {
|
63 |
+
"width": 0
|
64 |
+
},
|
65 |
+
"right": {
|
66 |
+
"width": 0
|
67 |
+
},
|
68 |
+
"top": {
|
69 |
+
"width": 0
|
70 |
+
}
|
71 |
+
},
|
72 |
+
"capitalization": "NONE",
|
73 |
+
"color": "#000000",
|
74 |
+
"display": "INLINE",
|
75 |
+
"font": "Georgia",
|
76 |
+
"line_height_scale": 1,
|
77 |
+
"margin": {
|
78 |
+
"left": {
|
79 |
+
"scaling_factor": 1,
|
80 |
+
"size": "DOCUMENT_MARGIN"
|
81 |
+
},
|
82 |
+
"right": {
|
83 |
+
"scaling_factor": 1,
|
84 |
+
"size": "DOCUMENT_MARGIN"
|
85 |
+
}
|
86 |
+
},
|
87 |
+
"padding": {
|
88 |
+
"bottom": {
|
89 |
+
"scaling_factor": 1,
|
90 |
+
"size": "NONE"
|
91 |
+
},
|
92 |
+
"left": {
|
93 |
+
"scaling_factor": 1,
|
94 |
+
"size": "NONE"
|
95 |
+
},
|
96 |
+
"right": {
|
97 |
+
"scaling_factor": 1,
|
98 |
+
"size": "NONE"
|
99 |
+
},
|
100 |
+
"top": {
|
101 |
+
"scaling_factor": 1,
|
102 |
+
"size": "NONE"
|
103 |
+
}
|
104 |
+
},
|
105 |
+
"text_alignment": "LEFT",
|
106 |
+
"text_size_scale": 1,
|
107 |
+
"underline": "NONE"
|
108 |
+
},
|
109 |
+
"kicker": {
|
110 |
+
"background_color": "#00FFFFFF",
|
111 |
+
"border": {
|
112 |
+
"bottom": {
|
113 |
+
"width": 0
|
114 |
+
},
|
115 |
+
"left": {
|
116 |
+
"width": 0
|
117 |
+
},
|
118 |
+
"right": {
|
119 |
+
"width": 0
|
120 |
+
},
|
121 |
+
"top": {
|
122 |
+
"width": 0
|
123 |
+
}
|
124 |
+
},
|
125 |
+
"capitalization": "ALL_CAPS",
|
126 |
+
"color": "#000000",
|
127 |
+
"display": "INLINE",
|
128 |
+
"font": "Helvetica Neue",
|
129 |
+
"line_height_scale": 1,
|
130 |
+
"margin": {
|
131 |
+
"left": {
|
132 |
+
"scaling_factor": 1,
|
133 |
+
"size": "DOCUMENT_MARGIN"
|
134 |
+
},
|
135 |
+
"right": {
|
136 |
+
"scaling_factor": 1,
|
137 |
+
"size": "DOCUMENT_MARGIN"
|
138 |
+
}
|
139 |
+
},
|
140 |
+
"padding": {
|
141 |
+
"bottom": {
|
142 |
+
"scaling_factor": 1,
|
143 |
+
"size": "NONE"
|
144 |
+
},
|
145 |
+
"left": {
|
146 |
+
"scaling_factor": 1,
|
147 |
+
"size": "NONE"
|
148 |
+
},
|
149 |
+
"right": {
|
150 |
+
"scaling_factor": 1,
|
151 |
+
"size": "NONE"
|
152 |
+
},
|
153 |
+
"top": {
|
154 |
+
"scaling_factor": 1,
|
155 |
+
"size": "NONE"
|
156 |
+
}
|
157 |
+
},
|
158 |
+
"text_alignment": "LEFT",
|
159 |
+
"text_size_scale": 1,
|
160 |
+
"underline": "NONE"
|
161 |
+
},
|
162 |
+
"byline": {
|
163 |
+
"background_color": "#00FFFFFF",
|
164 |
+
"border": {
|
165 |
+
"bottom": {
|
166 |
+
"width": 0
|
167 |
+
},
|
168 |
+
"left": {
|
169 |
+
"width": 0
|
170 |
+
},
|
171 |
+
"right": {
|
172 |
+
"width": 0
|
173 |
+
},
|
174 |
+
"top": {
|
175 |
+
"width": 0
|
176 |
+
}
|
177 |
+
},
|
178 |
+
"capitalization": "ALL_CAPS",
|
179 |
+
"color": "#000000",
|
180 |
+
"display": "INLINE",
|
181 |
+
"font": "Helvetica Neue",
|
182 |
+
"line_height_scale": 1,
|
183 |
+
"margin": {
|
184 |
+
"left": {
|
185 |
+
"scaling_factor": 1,
|
186 |
+
"size": "DOCUMENT_MARGIN"
|
187 |
+
},
|
188 |
+
"right": {
|
189 |
+
"scaling_factor": 1,
|
190 |
+
"size": "DOCUMENT_MARGIN"
|
191 |
+
}
|
192 |
+
},
|
193 |
+
"padding": {
|
194 |
+
"bottom": {
|
195 |
+
"scaling_factor": 1,
|
196 |
+
"size": "NONE"
|
197 |
+
},
|
198 |
+
"left": {
|
199 |
+
"scaling_factor": 1,
|
200 |
+
"size": "NONE"
|
201 |
+
},
|
202 |
+
"right": {
|
203 |
+
"scaling_factor": 1,
|
204 |
+
"size": "NONE"
|
205 |
+
},
|
206 |
+
"top": {
|
207 |
+
"scaling_factor": 1,
|
208 |
+
"size": "NONE"
|
209 |
+
}
|
210 |
+
},
|
211 |
+
"text_alignment": "LEFT",
|
212 |
+
"text_size_scale": 1,
|
213 |
+
"underline": "NONE"
|
214 |
+
},
|
215 |
+
"date_style": "MONTH_DAY_YEAR",
|
216 |
+
"primary_heading": {
|
217 |
+
"background_color": "#00FFFFFF",
|
218 |
+
"border": {
|
219 |
+
"bottom": {
|
220 |
+
"width": 0
|
221 |
+
},
|
222 |
+
"left": {
|
223 |
+
"width": 0
|
224 |
+
},
|
225 |
+
"right": {
|
226 |
+
"width": 0
|
227 |
+
},
|
228 |
+
"top": {
|
229 |
+
"width": 0
|
230 |
+
}
|
231 |
+
},
|
232 |
+
"capitalization": "NONE",
|
233 |
+
"color": "#000000",
|
234 |
+
"display": "INLINE",
|
235 |
+
"font": "Georgia",
|
236 |
+
"line_height_scale": 1,
|
237 |
+
"margin": {
|
238 |
+
"left": {
|
239 |
+
"scaling_factor": 1,
|
240 |
+
"size": "DOCUMENT_MARGIN"
|
241 |
+
},
|
242 |
+
"right": {
|
243 |
+
"scaling_factor": 1,
|
244 |
+
"size": "DOCUMENT_MARGIN"
|
245 |
+
}
|
246 |
+
},
|
247 |
+
"padding": {
|
248 |
+
"bottom": {
|
249 |
+
"scaling_factor": 1,
|
250 |
+
"size": "NONE"
|
251 |
+
},
|
252 |
+
"left": {
|
253 |
+
"scaling_factor": 1,
|
254 |
+
"size": "NONE"
|
255 |
+
},
|
256 |
+
"right": {
|
257 |
+
"scaling_factor": 1,
|
258 |
+
"size": "NONE"
|
259 |
+
},
|
260 |
+
"top": {
|
261 |
+
"scaling_factor": 1,
|
262 |
+
"size": "NONE"
|
263 |
+
}
|
264 |
+
},
|
265 |
+
"text_alignment": "LEFT",
|
266 |
+
"text_size_scale": 1,
|
267 |
+
"underline": "NONE"
|
268 |
+
},
|
269 |
+
"secondary_heading": {
|
270 |
+
"background_color": "#00FFFFFF",
|
271 |
+
"border": {
|
272 |
+
"bottom": {
|
273 |
+
"width": 0
|
274 |
+
},
|
275 |
+
"left": {
|
276 |
+
"width": 0
|
277 |
+
},
|
278 |
+
"right": {
|
279 |
+
"width": 0
|
280 |
+
},
|
281 |
+
"top": {
|
282 |
+
"width": 0
|
283 |
+
}
|
284 |
+
},
|
285 |
+
"capitalization": "NONE",
|
286 |
+
"color": "#000000",
|
287 |
+
"display": "INLINE",
|
288 |
+
"font": "Georgia",
|
289 |
+
"line_height_scale": 1,
|
290 |
+
"margin": {
|
291 |
+
"left": {
|
292 |
+
"scaling_factor": 1,
|
293 |
+
"size": "DOCUMENT_MARGIN"
|
294 |
+
},
|
295 |
+
"right": {
|
296 |
+
"scaling_factor": 1,
|
297 |
+
"size": "DOCUMENT_MARGIN"
|
298 |
+
}
|
299 |
+
},
|
300 |
+
"padding": {
|
301 |
+
"bottom": {
|
302 |
+
"scaling_factor": 1,
|
303 |
+
"size": "NONE"
|
304 |
+
},
|
305 |
+
"left": {
|
306 |
+
"scaling_factor": 1,
|
307 |
+
"size": "NONE"
|
308 |
+
},
|
309 |
+
"right": {
|
310 |
+
"scaling_factor": 1,
|
311 |
+
"size": "NONE"
|
312 |
+
},
|
313 |
+
"top": {
|
314 |
+
"scaling_factor": 1,
|
315 |
+
"size": "NONE"
|
316 |
+
}
|
317 |
+
},
|
318 |
+
"text_alignment": "LEFT",
|
319 |
+
"text_size_scale": 1,
|
320 |
+
"underline": "NONE"
|
321 |
+
},
|
322 |
+
"body_text": {
|
323 |
+
"background_color": "#00FFFFFF",
|
324 |
+
"border": {
|
325 |
+
"bottom": {
|
326 |
+
"width": 0
|
327 |
+
},
|
328 |
+
"left": {
|
329 |
+
"width": 0
|
330 |
+
},
|
331 |
+
"right": {
|
332 |
+
"width": 0
|
333 |
+
},
|
334 |
+
"top": {
|
335 |
+
"width": 0
|
336 |
+
}
|
337 |
+
},
|
338 |
+
"capitalization": "NONE",
|
339 |
+
"color": "#000000",
|
340 |
+
"display": "INLINE",
|
341 |
+
"font": "Georgia",
|
342 |
+
"line_height_scale": 1,
|
343 |
+
"margin": {
|
344 |
+
"left": {
|
345 |
+
"scaling_factor": 1,
|
346 |
+
"size": "DOCUMENT_MARGIN"
|
347 |
+
},
|
348 |
+
"right": {
|
349 |
+
"scaling_factor": 1,
|
350 |
+
"size": "DOCUMENT_MARGIN"
|
351 |
+
}
|
352 |
+
},
|
353 |
+
"padding": {
|
354 |
+
"bottom": {
|
355 |
+
"scaling_factor": 1,
|
356 |
+
"size": "NONE"
|
357 |
+
},
|
358 |
+
"left": {
|
359 |
+
"scaling_factor": 1,
|
360 |
+
"size": "NONE"
|
361 |
+
},
|
362 |
+
"right": {
|
363 |
+
"scaling_factor": 1,
|
364 |
+
"size": "NONE"
|
365 |
+
},
|
366 |
+
"top": {
|
367 |
+
"scaling_factor": 1,
|
368 |
+
"size": "NONE"
|
369 |
+
}
|
370 |
+
},
|
371 |
+
"text_alignment": "LEFT",
|
372 |
+
"text_size_scale": 1,
|
373 |
+
"underline": "NONE"
|
374 |
+
},
|
375 |
+
"inline_link": {
|
376 |
+
"background_color": "#00FFFFFF",
|
377 |
+
"border": {
|
378 |
+
"bottom": {
|
379 |
+
"width": 0
|
380 |
+
},
|
381 |
+
"left": {
|
382 |
+
"width": 0
|
383 |
+
},
|
384 |
+
"right": {
|
385 |
+
"width": 0
|
386 |
+
},
|
387 |
+
"top": {
|
388 |
+
"width": 0
|
389 |
+
}
|
390 |
+
},
|
391 |
+
"capitalization": "NONE",
|
392 |
+
"color": "#000000",
|
393 |
+
"display": "INLINE",
|
394 |
+
"font": "Georgia",
|
395 |
+
"line_height_scale": 1,
|
396 |
+
"margin": {
|
397 |
+
"left": {
|
398 |
+
"scaling_factor": 1,
|
399 |
+
"size": "DOCUMENT_MARGIN"
|
400 |
+
},
|
401 |
+
"right": {
|
402 |
+
"scaling_factor": 1,
|
403 |
+
"size": "DOCUMENT_MARGIN"
|
404 |
+
}
|
405 |
+
},
|
406 |
+
"padding": {
|
407 |
+
"bottom": {
|
408 |
+
"scaling_factor": 1,
|
409 |
+
"size": "NONE"
|
410 |
+
},
|
411 |
+
"left": {
|
412 |
+
"scaling_factor": 1,
|
413 |
+
"size": "NONE"
|
414 |
+
},
|
415 |
+
"right": {
|
416 |
+
"scaling_factor": 1,
|
417 |
+
"size": "NONE"
|
418 |
+
},
|
419 |
+
"top": {
|
420 |
+
"scaling_factor": 1,
|
421 |
+
"size": "NONE"
|
422 |
+
}
|
423 |
+
},
|
424 |
+
"text_alignment": "LEFT",
|
425 |
+
"text_size_scale": 1,
|
426 |
+
"underline": "SIMPLE_UNDERLINE"
|
427 |
+
},
|
428 |
+
"block_quote": {
|
429 |
+
"background_color": "#00FFFFFF",
|
430 |
+
"border": {
|
431 |
+
"bottom": {
|
432 |
+
"color": "#000000",
|
433 |
+
"width": 0
|
434 |
+
},
|
435 |
+
"left": {
|
436 |
+
"color": "#000000",
|
437 |
+
"width": 2
|
438 |
+
},
|
439 |
+
"right": {
|
440 |
+
"color": "#000000",
|
441 |
+
"width": 0
|
442 |
+
},
|
443 |
+
"top": {
|
444 |
+
"color": "#000000",
|
445 |
+
"width": 0
|
446 |
+
}
|
447 |
+
},
|
448 |
+
"capitalization": "NONE",
|
449 |
+
"color": "#000000",
|
450 |
+
"display": "INLINE",
|
451 |
+
"font": "Georgia",
|
452 |
+
"line_height_scale": 1,
|
453 |
+
"margin": {
|
454 |
+
"left": {
|
455 |
+
"scaling_factor": 1,
|
456 |
+
"size": "DOCUMENT_MARGIN"
|
457 |
+
},
|
458 |
+
"right": {
|
459 |
+
"scaling_factor": 1,
|
460 |
+
"size": "DOCUMENT_MARGIN"
|
461 |
+
}
|
462 |
+
},
|
463 |
+
"padding": {
|
464 |
+
"bottom": {
|
465 |
+
"scaling_factor": 1,
|
466 |
+
"size": "NONE"
|
467 |
+
},
|
468 |
+
"left": {
|
469 |
+
"scaling_factor": 1,
|
470 |
+
"size": "MEDIUM"
|
471 |
+
},
|
472 |
+
"right": {
|
473 |
+
"scaling_factor": 1,
|
474 |
+
"size": "SMALL"
|
475 |
+
},
|
476 |
+
"top": {
|
477 |
+
"scaling_factor": 1,
|
478 |
+
"size": "NONE"
|
479 |
+
}
|
480 |
+
},
|
481 |
+
"text_alignment": "LEFT",
|
482 |
+
"text_size_scale": 1,
|
483 |
+
"underline": "NONE"
|
484 |
+
},
|
485 |
+
"pull_quote": {
|
486 |
+
"background_color": "#00FFFFFF",
|
487 |
+
"border": {
|
488 |
+
"bottom": {
|
489 |
+
"width": 0
|
490 |
+
},
|
491 |
+
"left": {
|
492 |
+
"width": 0
|
493 |
+
},
|
494 |
+
"right": {
|
495 |
+
"width": 0
|
496 |
+
},
|
497 |
+
"top": {
|
498 |
+
"width": 0
|
499 |
+
}
|
500 |
+
},
|
501 |
+
"capitalization": "NONE",
|
502 |
+
"color": "#000000",
|
503 |
+
"display": "INLINE",
|
504 |
+
"font": "Georgia",
|
505 |
+
"line_height_scale": 1,
|
506 |
+
"margin": {
|
507 |
+
"left": {
|
508 |
+
"scaling_factor": 1,
|
509 |
+
"size": "DOCUMENT_MARGIN"
|
510 |
+
},
|
511 |
+
"right": {
|
512 |
+
"scaling_factor": 1,
|
513 |
+
"size": "DOCUMENT_MARGIN"
|
514 |
+
}
|
515 |
+
},
|
516 |
+
"padding": {
|
517 |
+
"bottom": {
|
518 |
+
"scaling_factor": 1,
|
519 |
+
"size": "NONE"
|
520 |
+
},
|
521 |
+
"left": {
|
522 |
+
"scaling_factor": 1,
|
523 |
+
"size": "NONE"
|
524 |
+
},
|
525 |
+
"right": {
|
526 |
+
"scaling_factor": 1,
|
527 |
+
"size": "NONE"
|
528 |
+
},
|
529 |
+
"top": {
|
530 |
+
"scaling_factor": 1,
|
531 |
+
"size": "NONE"
|
532 |
+
}
|
533 |
+
},
|
534 |
+
"text_alignment": "LEFT",
|
535 |
+
"text_size_scale": 1,
|
536 |
+
"underline": "NONE"
|
537 |
+
},
|
538 |
+
"pull_quote_attribution": {
|
539 |
+
"background_color": "#00FFFFFF",
|
540 |
+
"border": {
|
541 |
+
"bottom": {
|
542 |
+
"width": 0
|
543 |
+
},
|
544 |
+
"left": {
|
545 |
+
"width": 0
|
546 |
+
},
|
547 |
+
"right": {
|
548 |
+
"width": 0
|
549 |
+
},
|
550 |
+
"top": {
|
551 |
+
"width": 0
|
552 |
+
}
|
553 |
+
},
|
554 |
+
"capitalization": "ALL_CAPS",
|
555 |
+
"color": "#000000",
|
556 |
+
"display": "INLINE",
|
557 |
+
"font": "Helvetica Neue",
|
558 |
+
"line_height_scale": 1,
|
559 |
+
"margin": {
|
560 |
+
"left": {
|
561 |
+
"scaling_factor": 1,
|
562 |
+
"size": "DOCUMENT_MARGIN"
|
563 |
+
},
|
564 |
+
"right": {
|
565 |
+
"scaling_factor": 1,
|
566 |
+
"size": "DOCUMENT_MARGIN"
|
567 |
+
}
|
568 |
+
},
|
569 |
+
"padding": {
|
570 |
+
"bottom": {
|
571 |
+
"scaling_factor": 1,
|
572 |
+
"size": "NONE"
|
573 |
+
},
|
574 |
+
"left": {
|
575 |
+
"scaling_factor": 1,
|
576 |
+
"size": "NONE"
|
577 |
+
},
|
578 |
+
"right": {
|
579 |
+
"scaling_factor": 1,
|
580 |
+
"size": "NONE"
|
581 |
+
},
|
582 |
+
"top": {
|
583 |
+
"scaling_factor": 1,
|
584 |
+
"size": "NONE"
|
585 |
+
}
|
586 |
+
},
|
587 |
+
"text_alignment": "LEFT",
|
588 |
+
"text_size_scale": 1,
|
589 |
+
"underline": "NONE"
|
590 |
+
},
|
591 |
+
"caption_title_small": {
|
592 |
+
"background_color": "#00FFFFFF",
|
593 |
+
"border": {
|
594 |
+
"bottom": {
|
595 |
+
"width": 0
|
596 |
+
},
|
597 |
+
"left": {
|
598 |
+
"width": 0
|
599 |
+
},
|
600 |
+
"right": {
|
601 |
+
"width": 0
|
602 |
+
},
|
603 |
+
"top": {
|
604 |
+
"width": 0
|
605 |
+
}
|
606 |
+
},
|
607 |
+
"capitalization": "NONE",
|
608 |
+
"color": "#808080",
|
609 |
+
"display": "INLINE",
|
610 |
+
"font": "Helvetica Neue Bold",
|
611 |
+
"line_height_scale": 1,
|
612 |
+
"margin": {
|
613 |
+
"left": {
|
614 |
+
"scaling_factor": 1,
|
615 |
+
"size": "DOCUMENT_MARGIN"
|
616 |
+
},
|
617 |
+
"right": {
|
618 |
+
"scaling_factor": 1,
|
619 |
+
"size": "DOCUMENT_MARGIN"
|
620 |
+
}
|
621 |
+
},
|
622 |
+
"padding": {
|
623 |
+
"bottom": {
|
624 |
+
"scaling_factor": 1,
|
625 |
+
"size": "NONE"
|
626 |
+
},
|
627 |
+
"left": {
|
628 |
+
"scaling_factor": 1,
|
629 |
+
"size": "NONE"
|
630 |
+
},
|
631 |
+
"right": {
|
632 |
+
"scaling_factor": 1,
|
633 |
+
"size": "NONE"
|
634 |
+
},
|
635 |
+
"top": {
|
636 |
+
"scaling_factor": 1,
|
637 |
+
"size": "NONE"
|
638 |
+
}
|
639 |
+
},
|
640 |
+
"text_alignment": "LEFT",
|
641 |
+
"text_size_scale": 1,
|
642 |
+
"underline": "NONE"
|
643 |
+
},
|
644 |
+
"caption_title": {
|
645 |
+
"background_color": "#00FFFFFF",
|
646 |
+
"border": {
|
647 |
+
"bottom": {
|
648 |
+
"width": 0
|
649 |
+
},
|
650 |
+
"left": {
|
651 |
+
"width": 0
|
652 |
+
},
|
653 |
+
"right": {
|
654 |
+
"width": 0
|
655 |
+
},
|
656 |
+
"top": {
|
657 |
+
"width": 0
|
658 |
+
}
|
659 |
+
},
|
660 |
+
"capitalization": "NONE",
|
661 |
+
"color": "#808080",
|
662 |
+
"display": "INLINE",
|
663 |
+
"font": "Georgia",
|
664 |
+
"line_height_scale": 1,
|
665 |
+
"margin": {
|
666 |
+
"left": {
|
667 |
+
"scaling_factor": 1,
|
668 |
+
"size": "DOCUMENT_MARGIN"
|
669 |
+
},
|
670 |
+
"right": {
|
671 |
+
"scaling_factor": 1,
|
672 |
+
"size": "DOCUMENT_MARGIN"
|
673 |
+
}
|
674 |
+
},
|
675 |
+
"padding": {
|
676 |
+
"bottom": {
|
677 |
+
"scaling_factor": 1,
|
678 |
+
"size": "NONE"
|
679 |
+
},
|
680 |
+
"left": {
|
681 |
+
"scaling_factor": 1,
|
682 |
+
"size": "NONE"
|
683 |
+
},
|
684 |
+
"right": {
|
685 |
+
"scaling_factor": 1,
|
686 |
+
"size": "NONE"
|
687 |
+
},
|
688 |
+
"top": {
|
689 |
+
"scaling_factor": 1,
|
690 |
+
"size": "NONE"
|
691 |
+
}
|
692 |
+
},
|
693 |
+
"text_alignment": "LEFT",
|
694 |
+
"text_size_scale": 1,
|
695 |
+
"underline": "NONE"
|
696 |
+
},
|
697 |
+
"caption_title_large": {
|
698 |
+
"background_color": "#00FFFFFF",
|
699 |
+
"border": {
|
700 |
+
"bottom": {
|
701 |
+
"width": 0
|
702 |
+
},
|
703 |
+
"left": {
|
704 |
+
"width": 0
|
705 |
+
},
|
706 |
+
"right": {
|
707 |
+
"width": 0
|
708 |
+
},
|
709 |
+
"top": {
|
710 |
+
"width": 0
|
711 |
+
}
|
712 |
+
},
|
713 |
+
"capitalization": "NONE",
|
714 |
+
"color": "#808080",
|
715 |
+
"display": "INLINE",
|
716 |
+
"font": "Georgia",
|
717 |
+
"line_height_scale": 1,
|
718 |
+
"margin": {
|
719 |
+
"left": {
|
720 |
+
"scaling_factor": 1,
|
721 |
+
"size": "DOCUMENT_MARGIN"
|
722 |
+
},
|
723 |
+
"right": {
|
724 |
+
"scaling_factor": 1,
|
725 |
+
"size": "DOCUMENT_MARGIN"
|
726 |
+
}
|
727 |
+
},
|
728 |
+
"padding": {
|
729 |
+
"bottom": {
|
730 |
+
"scaling_factor": 1,
|
731 |
+
"size": "NONE"
|
732 |
+
},
|
733 |
+
"left": {
|
734 |
+
"scaling_factor": 1,
|
735 |
+
"size": "NONE"
|
736 |
+
},
|
737 |
+
"right": {
|
738 |
+
"scaling_factor": 1,
|
739 |
+
"size": "NONE"
|
740 |
+
},
|
741 |
+
"top": {
|
742 |
+
"scaling_factor": 1,
|
743 |
+
"size": "NONE"
|
744 |
+
}
|
745 |
+
},
|
746 |
+
"text_alignment": "LEFT",
|
747 |
+
"text_size_scale": 1,
|
748 |
+
"underline": "NONE"
|
749 |
+
},
|
750 |
+
"caption_title_extra_large": {
|
751 |
+
"background_color": "#00FFFFFF",
|
752 |
+
"border": {
|
753 |
+
"bottom": {
|
754 |
+
"width": 0
|
755 |
+
},
|
756 |
+
"left": {
|
757 |
+
"width": 0
|
758 |
+
},
|
759 |
+
"right": {
|
760 |
+
"width": 0
|
761 |
+
},
|
762 |
+
"top": {
|
763 |
+
"width": 0
|
764 |
+
}
|
765 |
+
},
|
766 |
+
"capitalization": "NONE",
|
767 |
+
"color": "#808080",
|
768 |
+
"display": "INLINE",
|
769 |
+
"font": "Georgia",
|
770 |
+
"line_height_scale": 1,
|
771 |
+
"margin": {
|
772 |
+
"left": {
|
773 |
+
"scaling_factor": 1,
|
774 |
+
"size": "DOCUMENT_MARGIN"
|
775 |
+
},
|
776 |
+
"right": {
|
777 |
+
"scaling_factor": 1,
|
778 |
+
"size": "DOCUMENT_MARGIN"
|
779 |
+
}
|
780 |
+
},
|
781 |
+
"padding": {
|
782 |
+
"bottom": {
|
783 |
+
"scaling_factor": 1,
|
784 |
+
"size": "NONE"
|
785 |
+
},
|
786 |
+
"left": {
|
787 |
+
"scaling_factor": 1,
|
788 |
+
"size": "NONE"
|
789 |
+
},
|
790 |
+
"right": {
|
791 |
+
"scaling_factor": 1,
|
792 |
+
"size": "NONE"
|
793 |
+
},
|
794 |
+
"top": {
|
795 |
+
"scaling_factor": 1,
|
796 |
+
"size": "NONE"
|
797 |
+
}
|
798 |
+
},
|
799 |
+
"text_alignment": "LEFT",
|
800 |
+
"text_size_scale": 1,
|
801 |
+
"underline": "NONE"
|
802 |
+
},
|
803 |
+
"caption_credit": {
|
804 |
+
"background_color": "#00FFFFFF",
|
805 |
+
"border": {
|
806 |
+
"bottom": {
|
807 |
+
"width": 0
|
808 |
+
},
|
809 |
+
"left": {
|
810 |
+
"width": 0
|
811 |
+
},
|
812 |
+
"right": {
|
813 |
+
"width": 0
|
814 |
+
},
|
815 |
+
"top": {
|
816 |
+
"width": 0
|
817 |
+
}
|
818 |
+
},
|
819 |
+
"capitalization": "ALL_CAPS",
|
820 |
+
"color": "#BFBFBF",
|
821 |
+
"display": "INLINE",
|
822 |
+
"font": "Helvetica Neue",
|
823 |
+
"line_height_scale": 1,
|
824 |
+
"margin": {
|
825 |
+
"left": {
|
826 |
+
"scaling_factor": 1,
|
827 |
+
"size": "DOCUMENT_MARGIN"
|
828 |
+
},
|
829 |
+
"right": {
|
830 |
+
"scaling_factor": 1,
|
831 |
+
"size": "DOCUMENT_MARGIN"
|
832 |
+
}
|
833 |
+
},
|
834 |
+
"padding": {
|
835 |
+
"bottom": {
|
836 |
+
"scaling_factor": 1,
|
837 |
+
"size": "NONE"
|
838 |
+
},
|
839 |
+
"left": {
|
840 |
+
"scaling_factor": 1,
|
841 |
+
"size": "NONE"
|
842 |
+
},
|
843 |
+
"right": {
|
844 |
+
"scaling_factor": 1,
|
845 |
+
"size": "NONE"
|
846 |
+
},
|
847 |
+
"top": {
|
848 |
+
"scaling_factor": 1,
|
849 |
+
"size": "NONE"
|
850 |
+
}
|
851 |
+
},
|
852 |
+
"text_alignment": "LEFT",
|
853 |
+
"text_size_scale": 1,
|
854 |
+
"underline": "NONE"
|
855 |
+
},
|
856 |
+
"caption_description_small": {
|
857 |
+
"background_color": "#00FFFFFF",
|
858 |
+
"border": {
|
859 |
+
"bottom": {
|
860 |
+
"width": 0
|
861 |
+
},
|
862 |
+
"left": {
|
863 |
+
"width": 0
|
864 |
+
},
|
865 |
+
"right": {
|
866 |
+
"width": 0
|
867 |
+
},
|
868 |
+
"top": {
|
869 |
+
"width": 0
|
870 |
+
}
|
871 |
+
},
|
872 |
+
"capitalization": "NONE",
|
873 |
+
"color": "#808080",
|
874 |
+
"display": "INLINE",
|
875 |
+
"font": "Helvetica Neue",
|
876 |
+
"line_height_scale": 1,
|
877 |
+
"margin": {
|
878 |
+
"left": {
|
879 |
+
"scaling_factor": 1,
|
880 |
+
"size": "DOCUMENT_MARGIN"
|
881 |
+
},
|
882 |
+
"right": {
|
883 |
+
"scaling_factor": 1,
|
884 |
+
"size": "DOCUMENT_MARGIN"
|
885 |
+
}
|
886 |
+
},
|
887 |
+
"padding": {
|
888 |
+
"bottom": {
|
889 |
+
"scaling_factor": 1,
|
890 |
+
"size": "NONE"
|
891 |
+
},
|
892 |
+
"left": {
|
893 |
+
"scaling_factor": 1,
|
894 |
+
"size": "NONE"
|
895 |
+
},
|
896 |
+
"right": {
|
897 |
+
"scaling_factor": 1,
|
898 |
+
"size": "NONE"
|
899 |
+
},
|
900 |
+
"top": {
|
901 |
+
"scaling_factor": 1,
|
902 |
+
"size": "NONE"
|
903 |
+
}
|
904 |
+
},
|
905 |
+
"text_alignment": "LEFT",
|
906 |
+
"text_size_scale": 1,
|
907 |
+
"underline": "NONE"
|
908 |
+
},
|
909 |
+
"caption_description": {
|
910 |
+
"background_color": "#00FFFFFF",
|
911 |
+
"border": {
|
912 |
+
"bottom": {
|
913 |
+
"width": 0
|
914 |
+
},
|
915 |
+
"left": {
|
916 |
+
"width": 0
|
917 |
+
},
|
918 |
+
"right": {
|
919 |
+
"width": 0
|
920 |
+
},
|
921 |
+
"top": {
|
922 |
+
"width": 0
|
923 |
+
}
|
924 |
+
},
|
925 |
+
"capitalization": "NONE",
|
926 |
+
"color": "#808080",
|
927 |
+
"display": "INLINE",
|
928 |
+
"font": "Georgia",
|
929 |
+
"line_height_scale": 1,
|
930 |
+
"margin": {
|
931 |
+
"left": {
|
932 |
+
"scaling_factor": 1,
|
933 |
+
"size": "DOCUMENT_MARGIN"
|
934 |
+
},
|
935 |
+
"right": {
|
936 |
+
"scaling_factor": 1,
|
937 |
+
"size": "DOCUMENT_MARGIN"
|
938 |
+
}
|
939 |
+
},
|
940 |
+
"padding": {
|
941 |
+
"bottom": {
|
942 |
+
"scaling_factor": 1,
|
943 |
+
"size": "NONE"
|
944 |
+
},
|
945 |
+
"left": {
|
946 |
+
"scaling_factor": 1,
|
947 |
+
"size": "NONE"
|
948 |
+
},
|
949 |
+
"right": {
|
950 |
+
"scaling_factor": 1,
|
951 |
+
"size": "NONE"
|
952 |
+
},
|
953 |
+
"top": {
|
954 |
+
"scaling_factor": 1,
|
955 |
+
"size": "NONE"
|
956 |
+
}
|
957 |
+
},
|
958 |
+
"text_alignment": "LEFT",
|
959 |
+
"text_size_scale": 1,
|
960 |
+
"underline": "NONE"
|
961 |
+
},
|
962 |
+
"caption_description_large": {
|
963 |
+
"background_color": "#00FFFFFF",
|
964 |
+
"border": {
|
965 |
+
"bottom": {
|
966 |
+
"width": 0
|
967 |
+
},
|
968 |
+
"left": {
|
969 |
+
"width": 0
|
970 |
+
},
|
971 |
+
"right": {
|
972 |
+
"width": 0
|
973 |
+
},
|
974 |
+
"top": {
|
975 |
+
"width": 0
|
976 |
+
}
|
977 |
+
},
|
978 |
+
"capitalization": "NONE",
|
979 |
+
"color": "#808080",
|
980 |
+
"display": "INLINE",
|
981 |
+
"font": "Georgia",
|
982 |
+
"line_height_scale": 1,
|
983 |
+
"margin": {
|
984 |
+
"left": {
|
985 |
+
"scaling_factor": 1,
|
986 |
+
"size": "DOCUMENT_MARGIN"
|
987 |
+
},
|
988 |
+
"right": {
|
989 |
+
"scaling_factor": 1,
|
990 |
+
"size": "DOCUMENT_MARGIN"
|
991 |
+
}
|
992 |
+
},
|
993 |
+
"padding": {
|
994 |
+
"bottom": {
|
995 |
+
"scaling_factor": 1,
|
996 |
+
"size": "NONE"
|
997 |
+
},
|
998 |
+
"left": {
|
999 |
+
"scaling_factor": 1,
|
1000 |
+
"size": "NONE"
|
1001 |
+
},
|
1002 |
+
"right": {
|
1003 |
+
"scaling_factor": 1,
|
1004 |
+
"size": "NONE"
|
1005 |
+
},
|
1006 |
+
"top": {
|
1007 |
+
"scaling_factor": 1,
|
1008 |
+
"size": "NONE"
|
1009 |
+
}
|
1010 |
+
},
|
1011 |
+
"text_alignment": "LEFT",
|
1012 |
+
"text_size_scale": 1,
|
1013 |
+
"underline": "NONE"
|
1014 |
+
},
|
1015 |
+
"caption_description_extra_large": {
|
1016 |
+
"background_color": "#00FFFFFF",
|
1017 |
+
"border": {
|
1018 |
+
"bottom": {
|
1019 |
+
"width": 0
|
1020 |
+
},
|
1021 |
+
"left": {
|
1022 |
+
"width": 0
|
1023 |
+
},
|
1024 |
+
"right": {
|
1025 |
+
"width": 0
|
1026 |
+
},
|
1027 |
+
"top": {
|
1028 |
+
"width": 0
|
1029 |
+
}
|
1030 |
+
},
|
1031 |
+
"capitalization": "NONE",
|
1032 |
+
"color": "#808080",
|
1033 |
+
"display": "INLINE",
|
1034 |
+
"font": "Georgia",
|
1035 |
+
"line_height_scale": 1,
|
1036 |
+
"margin": {
|
1037 |
+
"left": {
|
1038 |
+
"scaling_factor": 1,
|
1039 |
+
"size": "DOCUMENT_MARGIN"
|
1040 |
+
},
|
1041 |
+
"right": {
|
1042 |
+
"scaling_factor": 1,
|
1043 |
+
"size": "DOCUMENT_MARGIN"
|
1044 |
+
}
|
1045 |
+
},
|
1046 |
+
"padding": {
|
1047 |
+
"bottom": {
|
1048 |
+
"scaling_factor": 1,
|
1049 |
+
"size": "NONE"
|
1050 |
+
},
|
1051 |
+
"left": {
|
1052 |
+
"scaling_factor": 1,
|
1053 |
+
"size": "NONE"
|
1054 |
+
},
|
1055 |
+
"right": {
|
1056 |
+
"scaling_factor": 1,
|
1057 |
+
"size": "NONE"
|
1058 |
+
},
|
1059 |
+
"top": {
|
1060 |
+
"scaling_factor": 1,
|
1061 |
+
"size": "NONE"
|
1062 |
+
}
|
1063 |
+
},
|
1064 |
+
"text_alignment": "LEFT",
|
1065 |
+
"text_size_scale": 1,
|
1066 |
+
"underline": "NONE"
|
1067 |
+
},
|
1068 |
+
"footer": {
|
1069 |
+
"background_color": "#00FFFFFF",
|
1070 |
+
"border": {
|
1071 |
+
"bottom": {
|
1072 |
+
"width": 0
|
1073 |
+
},
|
1074 |
+
"left": {
|
1075 |
+
"width": 0
|
1076 |
+
},
|
1077 |
+
"right": {
|
1078 |
+
"width": 0
|
1079 |
+
},
|
1080 |
+
"top": {
|
1081 |
+
"width": 0
|
1082 |
+
}
|
1083 |
+
},
|
1084 |
+
"capitalization": "NONE",
|
1085 |
+
"color": "#000000",
|
1086 |
+
"display": "INLINE",
|
1087 |
+
"font": "Helvetica Neue",
|
1088 |
+
"line_height_scale": 1,
|
1089 |
+
"margin": {
|
1090 |
+
"left": {
|
1091 |
+
"scaling_factor": 1,
|
1092 |
+
"size": "DOCUMENT_MARGIN"
|
1093 |
+
},
|
1094 |
+
"right": {
|
1095 |
+
"scaling_factor": 1,
|
1096 |
+
"size": "DOCUMENT_MARGIN"
|
1097 |
+
}
|
1098 |
+
},
|
1099 |
+
"padding": {
|
1100 |
+
"bottom": {
|
1101 |
+
"scaling_factor": 1,
|
1102 |
+
"size": "NONE"
|
1103 |
+
},
|
1104 |
+
"left": {
|
1105 |
+
"scaling_factor": 1,
|
1106 |
+
"size": "NONE"
|
1107 |
+
},
|
1108 |
+
"right": {
|
1109 |
+
"scaling_factor": 1,
|
1110 |
+
"size": "NONE"
|
1111 |
+
},
|
1112 |
+
"top": {
|
1113 |
+
"scaling_factor": 1,
|
1114 |
+
"size": "NONE"
|
1115 |
+
}
|
1116 |
+
},
|
1117 |
+
"text_alignment": "LEFT",
|
1118 |
+
"text_size_scale": 1,
|
1119 |
+
"underline": "NONE"
|
1120 |
+
},
|
1121 |
+
"id": "1282952941794244",
|
1122 |
+
"name": "default",
|
1123 |
+
"is_default": true,
|
1124 |
+
"header": {
|
1125 |
+
"accent_color": "#989898",
|
1126 |
+
"background_color": "#FFFFFF"
|
1127 |
+
}
|
1128 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/AMP/wod-gray.style.json
ADDED
@@ -0,0 +1,993 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"background_color": "#EEEEEE",
|
3 |
+
"header": {
|
4 |
+
"logo": {
|
5 |
+
"dataURL": null,
|
6 |
+
"id": "1229084557204785",
|
7 |
+
"full_resolution_url": "https://fb-s-c-a.akamaihd.net/h-ak-xpa1/v/t39.5687-6/17351511_1229084560538118_5982709905105092608_n.png?_nc_log=1&oh=c8337650a88e7fdb6d31088a15a7d9d8&oe=599B24B5&__gda__=1502041799_7139cf314c7cdaa52fa44ba26fd253f8",
|
8 |
+
"full_resolution_width": 2600,
|
9 |
+
"full_resolution_height": 512,
|
10 |
+
"thumbnail_url": "https://fb-s-d-a.akamaihd.net/h-ak-xpf1/v/t39.5687-6/17634152_1374280939304404_1278222734471462912_n.png?_nc_log=1&oh=d3e95b10e960a9527ad643c47d821160&oe=598664D5&__gda__=1498346669_5ee6f5a2bd8d17474bfb46398d9b888a",
|
11 |
+
"article_scaling_factor": 1
|
12 |
+
},
|
13 |
+
"logo_scale": 1,
|
14 |
+
"accent_color": "#000000",
|
15 |
+
"background_color": "#666666",
|
16 |
+
"bar_color": null
|
17 |
+
},
|
18 |
+
"kicker": {
|
19 |
+
"font": "Helvetica Neue",
|
20 |
+
"color": "#000000",
|
21 |
+
"background_color": "#00FFFFFF",
|
22 |
+
"capitalization": "ALL_CAPS",
|
23 |
+
"text_alignment": "LEFT",
|
24 |
+
"display": "INLINE",
|
25 |
+
"line_height_scale": 1,
|
26 |
+
"text_size_scale": 1,
|
27 |
+
"margin": {
|
28 |
+
"right": {
|
29 |
+
"scaling_factor": 1,
|
30 |
+
"size": "DOCUMENT_MARGIN"
|
31 |
+
},
|
32 |
+
"left": {
|
33 |
+
"scaling_factor": 1,
|
34 |
+
"size": "DOCUMENT_MARGIN"
|
35 |
+
}
|
36 |
+
},
|
37 |
+
"border": {
|
38 |
+
"top": {
|
39 |
+
"width": 0
|
40 |
+
},
|
41 |
+
"right": {
|
42 |
+
"width": 0
|
43 |
+
},
|
44 |
+
"bottom": {
|
45 |
+
"width": 0
|
46 |
+
},
|
47 |
+
"left": {
|
48 |
+
"width": 0
|
49 |
+
}
|
50 |
+
},
|
51 |
+
"padding": {
|
52 |
+
"top": {
|
53 |
+
"scaling_factor": 1,
|
54 |
+
"size": "NONE"
|
55 |
+
},
|
56 |
+
"right": {
|
57 |
+
"scaling_factor": 1,
|
58 |
+
"size": "NONE"
|
59 |
+
},
|
60 |
+
"bottom": {
|
61 |
+
"scaling_factor": 1,
|
62 |
+
"size": "NONE"
|
63 |
+
},
|
64 |
+
"left": {
|
65 |
+
"scaling_factor": 1,
|
66 |
+
"size": "NONE"
|
67 |
+
}
|
68 |
+
}
|
69 |
+
},
|
70 |
+
"title": {
|
71 |
+
"font": "Georgia",
|
72 |
+
"color": "#000000",
|
73 |
+
"background_color": "#00FFFFFF",
|
74 |
+
"capitalization": "NONE",
|
75 |
+
"text_alignment": "LEFT",
|
76 |
+
"display": "INLINE",
|
77 |
+
"line_height_scale": 1,
|
78 |
+
"text_size_scale": 1,
|
79 |
+
"margin": {
|
80 |
+
"right": {
|
81 |
+
"scaling_factor": 1,
|
82 |
+
"size": "DOCUMENT_MARGIN"
|
83 |
+
},
|
84 |
+
"left": {
|
85 |
+
"scaling_factor": 1,
|
86 |
+
"size": "DOCUMENT_MARGIN"
|
87 |
+
}
|
88 |
+
},
|
89 |
+
"border": {
|
90 |
+
"top": {
|
91 |
+
"width": 0
|
92 |
+
},
|
93 |
+
"right": {
|
94 |
+
"width": 0
|
95 |
+
},
|
96 |
+
"bottom": {
|
97 |
+
"width": 0
|
98 |
+
},
|
99 |
+
"left": {
|
100 |
+
"width": 0
|
101 |
+
}
|
102 |
+
},
|
103 |
+
"padding": {
|
104 |
+
"top": {
|
105 |
+
"scaling_factor": 1,
|
106 |
+
"size": "NONE"
|
107 |
+
},
|
108 |
+
"right": {
|
109 |
+
"scaling_factor": 1,
|
110 |
+
"size": "NONE"
|
111 |
+
},
|
112 |
+
"bottom": {
|
113 |
+
"scaling_factor": 1,
|
114 |
+
"size": "NONE"
|
115 |
+
},
|
116 |
+
"left": {
|
117 |
+
"scaling_factor": 1,
|
118 |
+
"size": "NONE"
|
119 |
+
}
|
120 |
+
}
|
121 |
+
},
|
122 |
+
"subtitle": {
|
123 |
+
"font": "Georgia",
|
124 |
+
"color": "#000000",
|
125 |
+
"background_color": "#00FFFFFF",
|
126 |
+
"capitalization": "NONE",
|
127 |
+
"text_alignment": "LEFT",
|
128 |
+
"display": "INLINE",
|
129 |
+
"line_height_scale": 1,
|
130 |
+
"text_size_scale": 1,
|
131 |
+
"margin": {
|
132 |
+
"right": {
|
133 |
+
"scaling_factor": 1,
|
134 |
+
"size": "DOCUMENT_MARGIN"
|
135 |
+
},
|
136 |
+
"left": {
|
137 |
+
"scaling_factor": 1,
|
138 |
+
"size": "DOCUMENT_MARGIN"
|
139 |
+
}
|
140 |
+
},
|
141 |
+
"border": {
|
142 |
+
"top": {
|
143 |
+
"width": 0
|
144 |
+
},
|
145 |
+
"right": {
|
146 |
+
"width": 0
|
147 |
+
},
|
148 |
+
"bottom": {
|
149 |
+
"width": 0
|
150 |
+
},
|
151 |
+
"left": {
|
152 |
+
"width": 0
|
153 |
+
}
|
154 |
+
},
|
155 |
+
"padding": {
|
156 |
+
"top": {
|
157 |
+
"scaling_factor": 1,
|
158 |
+
"size": "NONE"
|
159 |
+
},
|
160 |
+
"right": {
|
161 |
+
"scaling_factor": 1,
|
162 |
+
"size": "NONE"
|
163 |
+
},
|
164 |
+
"bottom": {
|
165 |
+
"scaling_factor": 1,
|
166 |
+
"size": "NONE"
|
167 |
+
},
|
168 |
+
"left": {
|
169 |
+
"scaling_factor": 1,
|
170 |
+
"size": "NONE"
|
171 |
+
}
|
172 |
+
}
|
173 |
+
},
|
174 |
+
"byline": {
|
175 |
+
"font": "Helvetica Neue",
|
176 |
+
"color": "#000000",
|
177 |
+
"capitalization": "ALL_CAPS",
|
178 |
+
"text_alignment": "LEFT",
|
179 |
+
"line_height_scale": 1,
|
180 |
+
"text_size_scale": 1,
|
181 |
+
"margin": {
|
182 |
+
"right": {
|
183 |
+
"scaling_factor": 1,
|
184 |
+
"size": "DOCUMENT_MARGIN"
|
185 |
+
},
|
186 |
+
"left": {
|
187 |
+
"scaling_factor": 1,
|
188 |
+
"size": "DOCUMENT_MARGIN"
|
189 |
+
}
|
190 |
+
}
|
191 |
+
},
|
192 |
+
"date_style": "MONTH_DAY_YEAR",
|
193 |
+
"primary_heading": {
|
194 |
+
"font": "Georgia",
|
195 |
+
"color": "#000000",
|
196 |
+
"background_color": "#00FFFFFF",
|
197 |
+
"capitalization": "NONE",
|
198 |
+
"text_alignment": "LEFT",
|
199 |
+
"display": "INLINE",
|
200 |
+
"line_height_scale": 1,
|
201 |
+
"text_size_scale": 1,
|
202 |
+
"margin": {
|
203 |
+
"right": {
|
204 |
+
"scaling_factor": 1,
|
205 |
+
"size": "DOCUMENT_MARGIN"
|
206 |
+
},
|
207 |
+
"left": {
|
208 |
+
"scaling_factor": 1,
|
209 |
+
"size": "DOCUMENT_MARGIN"
|
210 |
+
}
|
211 |
+
},
|
212 |
+
"border": {
|
213 |
+
"top": {
|
214 |
+
"width": 0
|
215 |
+
},
|
216 |
+
"right": {
|
217 |
+
"width": 0
|
218 |
+
},
|
219 |
+
"bottom": {
|
220 |
+
"width": 0
|
221 |
+
},
|
222 |
+
"left": {
|
223 |
+
"width": 0
|
224 |
+
}
|
225 |
+
},
|
226 |
+
"padding": {
|
227 |
+
"top": {
|
228 |
+
"scaling_factor": 1,
|
229 |
+
"size": "NONE"
|
230 |
+
},
|
231 |
+
"right": {
|
232 |
+
"scaling_factor": 1,
|
233 |
+
"size": "NONE"
|
234 |
+
},
|
235 |
+
"bottom": {
|
236 |
+
"scaling_factor": 1,
|
237 |
+
"size": "NONE"
|
238 |
+
},
|
239 |
+
"left": {
|
240 |
+
"scaling_factor": 1,
|
241 |
+
"size": "NONE"
|
242 |
+
}
|
243 |
+
}
|
244 |
+
},
|
245 |
+
"secondary_heading": {
|
246 |
+
"font": "Georgia",
|
247 |
+
"color": "#000000",
|
248 |
+
"background_color": "#00FFFFFF",
|
249 |
+
"capitalization": "NONE",
|
250 |
+
"text_alignment": "LEFT",
|
251 |
+
"display": "INLINE",
|
252 |
+
"line_height_scale": 1,
|
253 |
+
"text_size_scale": 1,
|
254 |
+
"margin": {
|
255 |
+
"right": {
|
256 |
+
"scaling_factor": 1,
|
257 |
+
"size": "DOCUMENT_MARGIN"
|
258 |
+
},
|
259 |
+
"left": {
|
260 |
+
"scaling_factor": 1,
|
261 |
+
"size": "DOCUMENT_MARGIN"
|
262 |
+
}
|
263 |
+
},
|
264 |
+
"border": {
|
265 |
+
"top": {
|
266 |
+
"width": 0
|
267 |
+
},
|
268 |
+
"right": {
|
269 |
+
"width": 0
|
270 |
+
},
|
271 |
+
"bottom": {
|
272 |
+
"width": 0
|
273 |
+
},
|
274 |
+
"left": {
|
275 |
+
"width": 0
|
276 |
+
}
|
277 |
+
},
|
278 |
+
"padding": {
|
279 |
+
"top": {
|
280 |
+
"scaling_factor": 1,
|
281 |
+
"size": "NONE"
|
282 |
+
},
|
283 |
+
"right": {
|
284 |
+
"scaling_factor": 1,
|
285 |
+
"size": "NONE"
|
286 |
+
},
|
287 |
+
"bottom": {
|
288 |
+
"scaling_factor": 1,
|
289 |
+
"size": "NONE"
|
290 |
+
},
|
291 |
+
"left": {
|
292 |
+
"scaling_factor": 1,
|
293 |
+
"size": "NONE"
|
294 |
+
}
|
295 |
+
}
|
296 |
+
},
|
297 |
+
"body_text": {
|
298 |
+
"font": "Georgia",
|
299 |
+
"color": "#000000",
|
300 |
+
"capitalization": "NONE",
|
301 |
+
"text_alignment": "LEFT",
|
302 |
+
"line_height_scale": 1,
|
303 |
+
"text_size_scale": 1,
|
304 |
+
"margin": {
|
305 |
+
"right": {
|
306 |
+
"scaling_factor": 1,
|
307 |
+
"size": "DOCUMENT_MARGIN"
|
308 |
+
},
|
309 |
+
"left": {
|
310 |
+
"scaling_factor": 1,
|
311 |
+
"size": "DOCUMENT_MARGIN"
|
312 |
+
}
|
313 |
+
}
|
314 |
+
},
|
315 |
+
"inline_link": {
|
316 |
+
"color": "#000000",
|
317 |
+
"underline": "SIMPLE_UNDERLINE",
|
318 |
+
"font": "Georgia"
|
319 |
+
},
|
320 |
+
"block_quote": {
|
321 |
+
"font": "Georgia",
|
322 |
+
"color": "#000000",
|
323 |
+
"background_color": "#00FFFFFF",
|
324 |
+
"capitalization": "NONE",
|
325 |
+
"text_alignment": "LEFT",
|
326 |
+
"display": "BLOCK",
|
327 |
+
"line_height_scale": 1,
|
328 |
+
"text_size_scale": 1,
|
329 |
+
"margin": {
|
330 |
+
"right": {
|
331 |
+
"scaling_factor": 1,
|
332 |
+
"size": "DOCUMENT_MARGIN"
|
333 |
+
},
|
334 |
+
"left": {
|
335 |
+
"scaling_factor": 1,
|
336 |
+
"size": "DOCUMENT_MARGIN"
|
337 |
+
}
|
338 |
+
},
|
339 |
+
"border": {
|
340 |
+
"top": {
|
341 |
+
"color": "#000000",
|
342 |
+
"width": 0
|
343 |
+
},
|
344 |
+
"right": {
|
345 |
+
"color": "#000000",
|
346 |
+
"width": 0
|
347 |
+
},
|
348 |
+
"bottom": {
|
349 |
+
"color": "#000000",
|
350 |
+
"width": 0
|
351 |
+
},
|
352 |
+
"left": {
|
353 |
+
"color": "#000000",
|
354 |
+
"width": 2
|
355 |
+
}
|
356 |
+
},
|
357 |
+
"padding": {
|
358 |
+
"top": {
|
359 |
+
"scaling_factor": 1,
|
360 |
+
"size": "NONE"
|
361 |
+
},
|
362 |
+
"right": {
|
363 |
+
"scaling_factor": 1,
|
364 |
+
"size": "SMALL"
|
365 |
+
},
|
366 |
+
"bottom": {
|
367 |
+
"scaling_factor": 1,
|
368 |
+
"size": "NONE"
|
369 |
+
},
|
370 |
+
"left": {
|
371 |
+
"scaling_factor": 1,
|
372 |
+
"size": "MEDIUM"
|
373 |
+
}
|
374 |
+
}
|
375 |
+
},
|
376 |
+
"pull_quote": {
|
377 |
+
"font": "Georgia",
|
378 |
+
"color": "#000000",
|
379 |
+
"background_color": "#00FFFFFF",
|
380 |
+
"capitalization": "NONE",
|
381 |
+
"text_alignment": "LEFT",
|
382 |
+
"display": "INLINE",
|
383 |
+
"line_height_scale": 1,
|
384 |
+
"text_size_scale": 1,
|
385 |
+
"margin": {
|
386 |
+
"right": {
|
387 |
+
"scaling_factor": 1,
|
388 |
+
"size": "DOCUMENT_MARGIN"
|
389 |
+
},
|
390 |
+
"left": {
|
391 |
+
"scaling_factor": 1,
|
392 |
+
"size": "DOCUMENT_MARGIN"
|
393 |
+
}
|
394 |
+
},
|
395 |
+
"border": {
|
396 |
+
"top": {
|
397 |
+
"width": 0
|
398 |
+
},
|
399 |
+
"right": {
|
400 |
+
"width": 0
|
401 |
+
},
|
402 |
+
"bottom": {
|
403 |
+
"width": 0
|
404 |
+
},
|
405 |
+
"left": {
|
406 |
+
"width": 0
|
407 |
+
}
|
408 |
+
},
|
409 |
+
"padding": {
|
410 |
+
"top": {
|
411 |
+
"scaling_factor": 1,
|
412 |
+
"size": "NONE"
|
413 |
+
},
|
414 |
+
"right": {
|
415 |
+
"scaling_factor": 1,
|
416 |
+
"size": "NONE"
|
417 |
+
},
|
418 |
+
"bottom": {
|
419 |
+
"scaling_factor": 1,
|
420 |
+
"size": "NONE"
|
421 |
+
},
|
422 |
+
"left": {
|
423 |
+
"scaling_factor": 1,
|
424 |
+
"size": "NONE"
|
425 |
+
}
|
426 |
+
}
|
427 |
+
},
|
428 |
+
"pull_quote_attribution": {
|
429 |
+
"font": "Helvetica Neue",
|
430 |
+
"color": "#000000",
|
431 |
+
"background_color": "#00FFFFFF",
|
432 |
+
"capitalization": "ALL_CAPS",
|
433 |
+
"text_alignment": "LEFT",
|
434 |
+
"display": "INLINE",
|
435 |
+
"line_height_scale": 1,
|
436 |
+
"text_size_scale": 1,
|
437 |
+
"margin": {
|
438 |
+
"right": {
|
439 |
+
"scaling_factor": 1,
|
440 |
+
"size": "DOCUMENT_MARGIN"
|
441 |
+
},
|
442 |
+
"left": {
|
443 |
+
"scaling_factor": 1,
|
444 |
+
"size": "DOCUMENT_MARGIN"
|
445 |
+
}
|
446 |
+
},
|
447 |
+
"border": {
|
448 |
+
"top": {
|
449 |
+
"width": 0
|
450 |
+
},
|
451 |
+
"right": {
|
452 |
+
"width": 0
|
453 |
+
},
|
454 |
+
"bottom": {
|
455 |
+
"width": 0
|
456 |
+
},
|
457 |
+
"left": {
|
458 |
+
"width": 0
|
459 |
+
}
|
460 |
+
},
|
461 |
+
"padding": {
|
462 |
+
"top": {
|
463 |
+
"scaling_factor": 1,
|
464 |
+
"size": "NONE"
|
465 |
+
},
|
466 |
+
"right": {
|
467 |
+
"scaling_factor": 1,
|
468 |
+
"size": "NONE"
|
469 |
+
},
|
470 |
+
"bottom": {
|
471 |
+
"scaling_factor": 1,
|
472 |
+
"size": "NONE"
|
473 |
+
},
|
474 |
+
"left": {
|
475 |
+
"scaling_factor": 1,
|
476 |
+
"size": "NONE"
|
477 |
+
}
|
478 |
+
}
|
479 |
+
},
|
480 |
+
"caption_title_small": {
|
481 |
+
"font": "Helvetica Neue Bold",
|
482 |
+
"color": "#808080",
|
483 |
+
"background_color": "#00FFFF",
|
484 |
+
"capitalization": "NONE",
|
485 |
+
"display": "INLINE",
|
486 |
+
"line_height_scale": 1,
|
487 |
+
"text_size_scale": 1,
|
488 |
+
"margin": {
|
489 |
+
"right": {
|
490 |
+
"scaling_factor": 1,
|
491 |
+
"size": "DOCUMENT_MARGIN"
|
492 |
+
},
|
493 |
+
"left": {
|
494 |
+
"scaling_factor": 1,
|
495 |
+
"size": "DOCUMENT_MARGIN"
|
496 |
+
}
|
497 |
+
},
|
498 |
+
"border": {
|
499 |
+
"top": {
|
500 |
+
"width": 0
|
501 |
+
},
|
502 |
+
"right": {
|
503 |
+
"width": 0
|
504 |
+
},
|
505 |
+
"bottom": {
|
506 |
+
"width": 0
|
507 |
+
},
|
508 |
+
"left": {
|
509 |
+
"width": 0
|
510 |
+
}
|
511 |
+
},
|
512 |
+
"padding": {
|
513 |
+
"top": {
|
514 |
+
"scaling_factor": 1,
|
515 |
+
"size": "NONE"
|
516 |
+
},
|
517 |
+
"right": {
|
518 |
+
"scaling_factor": 1,
|
519 |
+
"size": "NONE"
|
520 |
+
},
|
521 |
+
"bottom": {
|
522 |
+
"scaling_factor": 1,
|
523 |
+
"size": "NONE"
|
524 |
+
},
|
525 |
+
"left": {
|
526 |
+
"scaling_factor": 1,
|
527 |
+
"size": "NONE"
|
528 |
+
}
|
529 |
+
}
|
530 |
+
},
|
531 |
+
"caption_description_small": {
|
532 |
+
"font": "Helvetica Neue",
|
533 |
+
"color": "#808080",
|
534 |
+
"background_color": "#00FFFFFF",
|
535 |
+
"capitalization": "NONE",
|
536 |
+
"display": "INLINE",
|
537 |
+
"line_height_scale": 1,
|
538 |
+
"text_size_scale": 1,
|
539 |
+
"margin": {
|
540 |
+
"right": {
|
541 |
+
"scaling_factor": 1,
|
542 |
+
"size": "DOCUMENT_MARGIN"
|
543 |
+
},
|
544 |
+
"left": {
|
545 |
+
"scaling_factor": 1,
|
546 |
+
"size": "DOCUMENT_MARGIN"
|
547 |
+
}
|
548 |
+
},
|
549 |
+
"border": {
|
550 |
+
"top": {
|
551 |
+
"width": 0
|
552 |
+
},
|
553 |
+
"right": {
|
554 |
+
"width": 0
|
555 |
+
},
|
556 |
+
"bottom": {
|
557 |
+
"width": 0
|
558 |
+
},
|
559 |
+
"left": {
|
560 |
+
"width": 0
|
561 |
+
}
|
562 |
+
},
|
563 |
+
"padding": {
|
564 |
+
"top": {
|
565 |
+
"scaling_factor": 1,
|
566 |
+
"size": "NONE"
|
567 |
+
},
|
568 |
+
"right": {
|
569 |
+
"scaling_factor": 1,
|
570 |
+
"size": "NONE"
|
571 |
+
},
|
572 |
+
"bottom": {
|
573 |
+
"scaling_factor": 1,
|
574 |
+
"size": "NONE"
|
575 |
+
},
|
576 |
+
"left": {
|
577 |
+
"scaling_factor": 1,
|
578 |
+
"size": "NONE"
|
579 |
+
}
|
580 |
+
}
|
581 |
+
},
|
582 |
+
"caption_credit": {
|
583 |
+
"font": "Helvetica Neue",
|
584 |
+
"color": "#BFBFBF",
|
585 |
+
"background_color": "#00FFFFFF",
|
586 |
+
"capitalization": "ALL_CAPS",
|
587 |
+
"display": "INLINE",
|
588 |
+
"line_height_scale": 1,
|
589 |
+
"text_size_scale": 1,
|
590 |
+
"margin": {
|
591 |
+
"right": {
|
592 |
+
"scaling_factor": 1,
|
593 |
+
"size": "DOCUMENT_MARGIN"
|
594 |
+
},
|
595 |
+
"left": {
|
596 |
+
"scaling_factor": 1,
|
597 |
+
"size": "DOCUMENT_MARGIN"
|
598 |
+
}
|
599 |
+
},
|
600 |
+
"border": {
|
601 |
+
"top": {
|
602 |
+
"width": 0
|
603 |
+
},
|
604 |
+
"right": {
|
605 |
+
"width": 0
|
606 |
+
},
|
607 |
+
"bottom": {
|
608 |
+
"width": 0
|
609 |
+
},
|
610 |
+
"left": {
|
611 |
+
"width": 0
|
612 |
+
}
|
613 |
+
},
|
614 |
+
"padding": {
|
615 |
+
"top": {
|
616 |
+
"scaling_factor": 1,
|
617 |
+
"size": "NONE"
|
618 |
+
},
|
619 |
+
"right": {
|
620 |
+
"scaling_factor": 1,
|
621 |
+
"size": "NONE"
|
622 |
+
},
|
623 |
+
"bottom": {
|
624 |
+
"scaling_factor": 1,
|
625 |
+
"size": "NONE"
|
626 |
+
},
|
627 |
+
"left": {
|
628 |
+
"scaling_factor": 1,
|
629 |
+
"size": "NONE"
|
630 |
+
}
|
631 |
+
}
|
632 |
+
},
|
633 |
+
"caption_title": {
|
634 |
+
"font": "Georgia",
|
635 |
+
"color": "#808080",
|
636 |
+
"background_color": "#00FFFFFF",
|
637 |
+
"capitalization": "NONE",
|
638 |
+
"display": "INLINE",
|
639 |
+
"line_height_scale": 1,
|
640 |
+
"text_size_scale": 1,
|
641 |
+
"margin": {
|
642 |
+
"right": {
|
643 |
+
"scaling_factor": 1,
|
644 |
+
"size": "DOCUMENT_MARGIN"
|
645 |
+
},
|
646 |
+
"left": {
|
647 |
+
"scaling_factor": 1,
|
648 |
+
"size": "DOCUMENT_MARGIN"
|
649 |
+
}
|
650 |
+
},
|
651 |
+
"border": {
|
652 |
+
"top": {
|
653 |
+
"width": 0
|
654 |
+
},
|
655 |
+
"right": {
|
656 |
+
"width": 0
|
657 |
+
},
|
658 |
+
"bottom": {
|
659 |
+
"width": 0
|
660 |
+
},
|
661 |
+
"left": {
|
662 |
+
"width": 0
|
663 |
+
}
|
664 |
+
},
|
665 |
+
"padding": {
|
666 |
+
"top": {
|
667 |
+
"scaling_factor": 1,
|
668 |
+
"size": "NONE"
|
669 |
+
},
|
670 |
+
"right": {
|
671 |
+
"scaling_factor": 1,
|
672 |
+
"size": "NONE"
|
673 |
+
},
|
674 |
+
"bottom": {
|
675 |
+
"scaling_factor": 1,
|
676 |
+
"size": "NONE"
|
677 |
+
},
|
678 |
+
"left": {
|
679 |
+
"scaling_factor": 1,
|
680 |
+
"size": "NONE"
|
681 |
+
}
|
682 |
+
}
|
683 |
+
},
|
684 |
+
"caption_description": {
|
685 |
+
"font": "Georgia",
|
686 |
+
"color": "#808080",
|
687 |
+
"background_color": "#00FFFFFF",
|
688 |
+
"capitalization": "NONE",
|
689 |
+
"display": "INLINE",
|
690 |
+
"line_height_scale": 1,
|
691 |
+
"text_size_scale": 1,
|
692 |
+
"margin": {
|
693 |
+
"right": {
|
694 |
+
"scaling_factor": 1,
|
695 |
+
"size": "DOCUMENT_MARGIN"
|
696 |
+
},
|
697 |
+
"left": {
|
698 |
+
"scaling_factor": 1,
|
699 |
+
"size": "DOCUMENT_MARGIN"
|
700 |
+
}
|
701 |
+
},
|
702 |
+
"border": {
|
703 |
+
"top": {
|
704 |
+
"width": 0
|
705 |
+
},
|
706 |
+
"right": {
|
707 |
+
"width": 0
|
708 |
+
},
|
709 |
+
"bottom": {
|
710 |
+
"width": 0
|
711 |
+
},
|
712 |
+
"left": {
|
713 |
+
"width": 0
|
714 |
+
}
|
715 |
+
},
|
716 |
+
"padding": {
|
717 |
+
"top": {
|
718 |
+
"scaling_factor": 1,
|
719 |
+
"size": "NONE"
|
720 |
+
},
|
721 |
+
"right": {
|
722 |
+
"scaling_factor": 1,
|
723 |
+
"size": "NONE"
|
724 |
+
},
|
725 |
+
"bottom": {
|
726 |
+
"scaling_factor": 1,
|
727 |
+
"size": "NONE"
|
728 |
+
},
|
729 |
+
"left": {
|
730 |
+
"scaling_factor": 1,
|
731 |
+
"size": "NONE"
|
732 |
+
}
|
733 |
+
}
|
734 |
+
},
|
735 |
+
"caption_title_large": {
|
736 |
+
"font": "Georgia",
|
737 |
+
"color": "#808080",
|
738 |
+
"background_color": "#00FFFFFF",
|
739 |
+
"capitalization": "NONE",
|
740 |
+
"display": "INLINE",
|
741 |
+
"line_height_scale": 1,
|
742 |
+
"text_size_scale": 1,
|
743 |
+
"margin": {
|
744 |
+
"right": {
|
745 |
+
"scaling_factor": 1,
|
746 |
+
"size": "DOCUMENT_MARGIN"
|
747 |
+
},
|
748 |
+
"left": {
|
749 |
+
"scaling_factor": 1,
|
750 |
+
"size": "DOCUMENT_MARGIN"
|
751 |
+
}
|
752 |
+
},
|
753 |
+
"border": {
|
754 |
+
"top": {
|
755 |
+
"width": 0
|
756 |
+
},
|
757 |
+
"right": {
|
758 |
+
"width": 0
|
759 |
+
},
|
760 |
+
"bottom": {
|
761 |
+
"width": 0
|
762 |
+
},
|
763 |
+
"left": {
|
764 |
+
"width": 0
|
765 |
+
}
|
766 |
+
},
|
767 |
+
"padding": {
|
768 |
+
"top": {
|
769 |
+
"scaling_factor": 1,
|
770 |
+
"size": "NONE"
|
771 |
+
},
|
772 |
+
"right": {
|
773 |
+
"scaling_factor": 1,
|
774 |
+
"size": "NONE"
|
775 |
+
},
|
776 |
+
"bottom": {
|
777 |
+
"scaling_factor": 1,
|
778 |
+
"size": "NONE"
|
779 |
+
},
|
780 |
+
"left": {
|
781 |
+
"scaling_factor": 1,
|
782 |
+
"size": "NONE"
|
783 |
+
}
|
784 |
+
}
|
785 |
+
},
|
786 |
+
"caption_description_large": {
|
787 |
+
"font": "Georgia",
|
788 |
+
"color": "#808080",
|
789 |
+
"background_color": "#00FFFFFF",
|
790 |
+
"capitalization": "NONE",
|
791 |
+
"display": "INLINE",
|
792 |
+
"line_height_scale": 1,
|
793 |
+
"text_size_scale": 1,
|
794 |
+
"margin": {
|
795 |
+
"right": {
|
796 |
+
"scaling_factor": 1,
|
797 |
+
"size": "DOCUMENT_MARGIN"
|
798 |
+
},
|
799 |
+
"left": {
|
800 |
+
"scaling_factor": 1,
|
801 |
+
"size": "DOCUMENT_MARGIN"
|
802 |
+
}
|
803 |
+
},
|
804 |
+
"border": {
|
805 |
+
"top": {
|
806 |
+
"width": 0
|
807 |
+
},
|
808 |
+
"right": {
|
809 |
+
"width": 0
|
810 |
+
},
|
811 |
+
"bottom": {
|
812 |
+
"width": 0
|
813 |
+
},
|
814 |
+
"left": {
|
815 |
+
"width": 0
|
816 |
+
}
|
817 |
+
},
|
818 |
+
"padding": {
|
819 |
+
"top": {
|
820 |
+
"scaling_factor": 1,
|
821 |
+
"size": "NONE"
|
822 |
+
},
|
823 |
+
"right": {
|
824 |
+
"scaling_factor": 1,
|
825 |
+
"size": "NONE"
|
826 |
+
},
|
827 |
+
"bottom": {
|
828 |
+
"scaling_factor": 1,
|
829 |
+
"size": "NONE"
|
830 |
+
},
|
831 |
+
"left": {
|
832 |
+
"scaling_factor": 1,
|
833 |
+
"size": "NONE"
|
834 |
+
}
|
835 |
+
}
|
836 |
+
},
|
837 |
+
"caption_title_extra_large": {
|
838 |
+
"font": "Georgia",
|
839 |
+
"color": "#808080",
|
840 |
+
"background_color": "#00FFFFFF",
|
841 |
+
"capitalization": "NONE",
|
842 |
+
"display": "INLINE",
|
843 |
+
"line_height_scale": 1,
|
844 |
+
"text_size_scale": 1,
|
845 |
+
"margin": {
|
846 |
+
"right": {
|
847 |
+
"scaling_factor": 1,
|
848 |
+
"size": "DOCUMENT_MARGIN"
|
849 |
+
},
|
850 |
+
"left": {
|
851 |
+
"scaling_factor": 1,
|
852 |
+
"size": "DOCUMENT_MARGIN"
|
853 |
+
}
|
854 |
+
},
|
855 |
+
"border": {
|
856 |
+
"top": {
|
857 |
+
"width": 0
|
858 |
+
},
|
859 |
+
"right": {
|
860 |
+
"width": 0
|
861 |
+
},
|
862 |
+
"bottom": {
|
863 |
+
"width": 0
|
864 |
+
},
|
865 |
+
"left": {
|
866 |
+
"width": 0
|
867 |
+
}
|
868 |
+
},
|
869 |
+
"padding": {
|
870 |
+
"top": {
|
871 |
+
"scaling_factor": 1,
|
872 |
+
"size": "NONE"
|
873 |
+
},
|
874 |
+
"right": {
|
875 |
+
"scaling_factor": 1,
|
876 |
+
"size": "NONE"
|
877 |
+
},
|
878 |
+
"bottom": {
|
879 |
+
"scaling_factor": 1,
|
880 |
+
"size": "NONE"
|
881 |
+
},
|
882 |
+
"left": {
|
883 |
+
"scaling_factor": 1,
|
884 |
+
"size": "NONE"
|
885 |
+
}
|
886 |
+
}
|
887 |
+
},
|
888 |
+
"caption_description_extra_large": {
|
889 |
+
"font": "Georgia",
|
890 |
+
"color": "#808080",
|
891 |
+
"background_color": "#00FFFFFF",
|
892 |
+
"capitalization": "NONE",
|
893 |
+
"display": "INLINE",
|
894 |
+
"line_height_scale": 1,
|
895 |
+
"text_size_scale": 1,
|
896 |
+
"margin": {
|
897 |
+
"right": {
|
898 |
+
"scaling_factor": 1,
|
899 |
+
"size": "DOCUMENT_MARGIN"
|
900 |
+
},
|
901 |
+
"left": {
|
902 |
+
"scaling_factor": 1,
|
903 |
+
"size": "DOCUMENT_MARGIN"
|
904 |
+
}
|
905 |
+
},
|
906 |
+
"border": {
|
907 |
+
"top": {
|
908 |
+
"width": 0
|
909 |
+
},
|
910 |
+
"right": {
|
911 |
+
"width": 0
|
912 |
+
},
|
913 |
+
"bottom": {
|
914 |
+
"width": 0
|
915 |
+
},
|
916 |
+
"left": {
|
917 |
+
"width": 0
|
918 |
+
}
|
919 |
+
},
|
920 |
+
"padding": {
|
921 |
+
"top": {
|
922 |
+
"scaling_factor": 1,
|
923 |
+
"size": "NONE"
|
924 |
+
},
|
925 |
+
"right": {
|
926 |
+
"scaling_factor": 1,
|
927 |
+
"size": "NONE"
|
928 |
+
},
|
929 |
+
"bottom": {
|
930 |
+
"scaling_factor": 1,
|
931 |
+
"size": "NONE"
|
932 |
+
},
|
933 |
+
"left": {
|
934 |
+
"scaling_factor": 1,
|
935 |
+
"size": "NONE"
|
936 |
+
}
|
937 |
+
}
|
938 |
+
},
|
939 |
+
"footer": {
|
940 |
+
"font": "Helvetica Neue",
|
941 |
+
"color": "#000000",
|
942 |
+
"background_color": "#00FFFFFF",
|
943 |
+
"capitalization": "NONE",
|
944 |
+
"text_alignment": "LEFT",
|
945 |
+
"display": "INLINE",
|
946 |
+
"line_height_scale": 1,
|
947 |
+
"text_size_scale": 1,
|
948 |
+
"margin": {
|
949 |
+
"right": {
|
950 |
+
"scaling_factor": 1,
|
951 |
+
"size": "DOCUMENT_MARGIN"
|
952 |
+
},
|
953 |
+
"left": {
|
954 |
+
"scaling_factor": 1,
|
955 |
+
"size": "DOCUMENT_MARGIN"
|
956 |
+
}
|
957 |
+
},
|
958 |
+
"border": {
|
959 |
+
"top": {
|
960 |
+
"width": 0
|
961 |
+
},
|
962 |
+
"right": {
|
963 |
+
"width": 0
|
964 |
+
},
|
965 |
+
"bottom": {
|
966 |
+
"width": 0
|
967 |
+
},
|
968 |
+
"left": {
|
969 |
+
"width": 0
|
970 |
+
}
|
971 |
+
},
|
972 |
+
"padding": {
|
973 |
+
"top": {
|
974 |
+
"scaling_factor": 1,
|
975 |
+
"size": "NONE"
|
976 |
+
},
|
977 |
+
"right": {
|
978 |
+
"scaling_factor": 1,
|
979 |
+
"size": "NONE"
|
980 |
+
},
|
981 |
+
"bottom": {
|
982 |
+
"scaling_factor": 1,
|
983 |
+
"size": "NONE"
|
984 |
+
},
|
985 |
+
"left": {
|
986 |
+
"scaling_factor": 1,
|
987 |
+
"size": "NONE"
|
988 |
+
}
|
989 |
+
}
|
990 |
+
},
|
991 |
+
"id": "1755859684428101",
|
992 |
+
"name": "wod-gray"
|
993 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/CSSBuilderTest.php
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
use PHPUnit\Framework;
|
12 |
+
|
13 |
+
class CSSBuilderTest extends Framework\TestCase
|
14 |
+
{
|
15 |
+
protected function setUp()
|
16 |
+
{
|
17 |
+
\Logger::configure(
|
18 |
+
[
|
19 |
+
'rootLogger' => [
|
20 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
21 |
+
],
|
22 |
+
'appenders' => [
|
23 |
+
'facebook-instantarticles-traverser' => [
|
24 |
+
'class' => 'LoggerAppenderConsole',
|
25 |
+
'threshold' => 'INFO',
|
26 |
+
'layout' => [
|
27 |
+
'class' => 'LoggerLayoutSimple'
|
28 |
+
]
|
29 |
+
]
|
30 |
+
]
|
31 |
+
]
|
32 |
+
);
|
33 |
+
}
|
34 |
+
|
35 |
+
public function genSimpleCSSFormatted($prefix = '')
|
36 |
+
{
|
37 |
+
return
|
38 |
+
".{$prefix}someClass {\n".
|
39 |
+
" width: 300px;\n".
|
40 |
+
" height: 400px;\n".
|
41 |
+
"}";
|
42 |
+
}
|
43 |
+
|
44 |
+
public function genSpacingCSSFormatted($prefix = '')
|
45 |
+
{
|
46 |
+
return
|
47 |
+
".{$prefix}someClass {\n".
|
48 |
+
" width: 300px;\n".
|
49 |
+
" height: 400px;\n".
|
50 |
+
"}\n".
|
51 |
+
"\n".
|
52 |
+
".{$prefix}someClass + .{$prefix}spacing {\n".
|
53 |
+
" height: 18px;\n".
|
54 |
+
"}";
|
55 |
+
}
|
56 |
+
|
57 |
+
public function genMarginCSSFormatted($prefix = '')
|
58 |
+
{
|
59 |
+
return
|
60 |
+
".{$prefix}someClass {\n".
|
61 |
+
" margin: 0 10px 5px 0;\n".
|
62 |
+
" height: 400px;\n".
|
63 |
+
"}";
|
64 |
+
}
|
65 |
+
|
66 |
+
public function genArrayCSSFormatted($prefix = '')
|
67 |
+
{
|
68 |
+
return
|
69 |
+
".{$prefix}someClass1, .{$prefix}someClass2 {\n".
|
70 |
+
" width: 300px;\n".
|
71 |
+
" height: 400px;\n".
|
72 |
+
"}\n".
|
73 |
+
"\n".
|
74 |
+
".{$prefix}someClass1 {\n".
|
75 |
+
" color: #fff;\n".
|
76 |
+
"}";
|
77 |
+
}
|
78 |
+
|
79 |
+
public function genOtherCSSFormatted($prefix = '')
|
80 |
+
{
|
81 |
+
return
|
82 |
+
".{$prefix}otherClass {\n".
|
83 |
+
" background-color: #aabbcc;\n".
|
84 |
+
" border-width: 2px;\n".
|
85 |
+
"}";
|
86 |
+
}
|
87 |
+
|
88 |
+
public function genSimpleCSS($prefix = '')
|
89 |
+
{
|
90 |
+
return
|
91 |
+
".{$prefix}someClass {".
|
92 |
+
"width: 300px;".
|
93 |
+
"height: 400px;".
|
94 |
+
"}";
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
|
99 |
+
public function testSimpleCSS()
|
100 |
+
{
|
101 |
+
$expected = $this->genSimpleCSS();
|
102 |
+
|
103 |
+
$cssBuilder = new CSSBuilder();
|
104 |
+
$cssBuilder->addProperty('.someClass', 'width', '300px')
|
105 |
+
->addProperty('.someClass', 'height', '400px');
|
106 |
+
$result = $cssBuilder->build(false);
|
107 |
+
$this->assertEquals($expected, $result);
|
108 |
+
}
|
109 |
+
|
110 |
+
public function testSimpleCSSFormatted()
|
111 |
+
{
|
112 |
+
$expected = $this->genSimpleCSSFormatted();
|
113 |
+
|
114 |
+
$cssBuilder = new CSSBuilder('');
|
115 |
+
$cssBuilder->addProperty('.someClass', 'width', '300px')
|
116 |
+
->addProperty('.someClass', 'height', '400px');
|
117 |
+
$result = $cssBuilder->build(true);
|
118 |
+
$this->assertEquals($expected, $result);
|
119 |
+
}
|
120 |
+
|
121 |
+
public function testMultipleCSSFormatted()
|
122 |
+
{
|
123 |
+
$expected = $this->genSimpleCSSFormatted()."\n\n".$this->genOtherCSSFormatted();
|
124 |
+
|
125 |
+
$cssBuilder = new CSSBuilder('');
|
126 |
+
$cssBuilder->addProperty('.someClass', 'width', '300px')
|
127 |
+
->addProperty('.someClass', 'height', '400px')
|
128 |
+
->addProperty('.otherClass', 'background-color', '#aabbcc')
|
129 |
+
->addProperty('.otherClass', 'border-width', '2px');
|
130 |
+
$result = $cssBuilder->build(true);
|
131 |
+
$this->assertEquals($expected, $result);
|
132 |
+
}
|
133 |
+
|
134 |
+
public function testMultipleCSSFormattedWithPrefix()
|
135 |
+
{
|
136 |
+
$expected = $this->genSimpleCSSFormatted('myprefix-');
|
137 |
+
|
138 |
+
$cssBuilder = new CSSBuilder('myprefix-');
|
139 |
+
$cssBuilder->addToSelector('someClass', 'width', '300px')
|
140 |
+
->addToSelector('someClass', 'height', '400px');
|
141 |
+
$result = $cssBuilder->build(true);
|
142 |
+
$this->assertEquals($expected, $result);
|
143 |
+
}
|
144 |
+
|
145 |
+
public function testMultipleDimmensionCSSFormattedWithPrefix()
|
146 |
+
{
|
147 |
+
$expected = $this->genSimpleCSSFormatted('myprefix-');
|
148 |
+
|
149 |
+
$cssBuilder = new CSSBuilder('myprefix-');
|
150 |
+
$cssBuilder->addDimensionToSelector('someClass', 'width', '300', 'px')
|
151 |
+
->addDimensionToSelector('someClass', 'height', '400', 'px');
|
152 |
+
$result = $cssBuilder->build(true);
|
153 |
+
$this->assertEquals($expected, $result);
|
154 |
+
}
|
155 |
+
|
156 |
+
public function testSpacingCSSFormattedWithPrefix()
|
157 |
+
{
|
158 |
+
$expected = $this->genSpacingCSSFormatted('myprefix-');
|
159 |
+
|
160 |
+
$cssBuilder = new CSSBuilder('myprefix-');
|
161 |
+
$cssBuilder->addDimensionToSelector('someClass', 'width', '300', 'px')
|
162 |
+
->addDimensionToSelector('someClass', 'height', '400', 'px')
|
163 |
+
->addHeightSpacingToSelector('someClass', '18');
|
164 |
+
$result = $cssBuilder->build(true);
|
165 |
+
$this->assertEquals($expected, $result);
|
166 |
+
}
|
167 |
+
|
168 |
+
public function testTopRightBottomLeftCSSFormattedWithPrefix()
|
169 |
+
{
|
170 |
+
$expected = $this->genMarginCSSFormatted('myprefix-');
|
171 |
+
|
172 |
+
$cssBuilder = new CSSBuilder('myprefix-');
|
173 |
+
$cssBuilder->addTopRightBottomLeftToSelector('someClass', 'margin', null, '10', 5, 0, 'px')
|
174 |
+
->addDimensionToSelector('someClass', 'height', '400', 'px');
|
175 |
+
$result = $cssBuilder->build(true);
|
176 |
+
$this->assertEquals($expected, $result);
|
177 |
+
}
|
178 |
+
|
179 |
+
public function testArrayCSSFormattedWithPrefix()
|
180 |
+
{
|
181 |
+
$expected = $this->genArrayCSSFormatted('myprefix-');
|
182 |
+
|
183 |
+
$cssBuilder = new CSSBuilder('myprefix-');
|
184 |
+
$cssBuilder->addToSelector(array('someClass1', 'someClass2'), 'width', '300px')
|
185 |
+
->addToSelector(array('someClass1', 'someClass2'), 'height', '400px')
|
186 |
+
->addToSelector('someClass1', 'color', '#fff');
|
187 |
+
$result = $cssBuilder->build(true);
|
188 |
+
$this->assertEquals($expected, $result);
|
189 |
+
}
|
190 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/FileUtilsPHPUnitTestCase.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Parser\Parser;
|
12 |
+
use PHPUnit\Framework;
|
13 |
+
|
14 |
+
class FileUtilsPHPUnitTestCase extends Framework\TestCase
|
15 |
+
{
|
16 |
+
protected function setUp()
|
17 |
+
{
|
18 |
+
\Logger::configure(
|
19 |
+
[
|
20 |
+
'rootLogger' => [
|
21 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
22 |
+
],
|
23 |
+
'appenders' => [
|
24 |
+
'facebook-instantarticles-traverser' => [
|
25 |
+
'class' => 'LoggerAppenderConsole',
|
26 |
+
'threshold' => 'INFO',
|
27 |
+
'layout' => [
|
28 |
+
'class' => 'LoggerLayoutSimple'
|
29 |
+
]
|
30 |
+
]
|
31 |
+
]
|
32 |
+
]
|
33 |
+
);
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Loads HTML file using by default file_get_contents
|
38 |
+
*/
|
39 |
+
public function loadHTMLFile($file)
|
40 |
+
{
|
41 |
+
return file_get_contents($file);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Helper method that loads HTML file into DOMDocument instance, encoding as HTML-ENTITIES and using by default utf-8.
|
46 |
+
* @param string $file The file name/path that will be loaded
|
47 |
+
* @param string $encoding "utf-8" by default. Supports the format informed.
|
48 |
+
*/
|
49 |
+
public function loadDOMDocument($file, $encoding = 'utf-8')
|
50 |
+
{
|
51 |
+
$fileContent = $this->loadHTMLFile($file, $encoding);
|
52 |
+
return $this->loadDOMDocumentFromString($fileContent, $encoding);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Helper method that loads HTML file into DOMDocument instance, encoding as HTML-ENTITIES and using by default utf-8.
|
57 |
+
* @param string $fileContent The file content
|
58 |
+
* @param string $encoding "utf-8" by default. Supports the format informed.
|
59 |
+
*/
|
60 |
+
public function loadDOMDocumentFromString($fileContent, $encoding = 'utf-8')
|
61 |
+
{
|
62 |
+
libxml_use_internal_errors(true);
|
63 |
+
$document = new \DOMDocument('1.0');
|
64 |
+
$document->loadHTML('<?xml encoding="' . $encoding. '"?>'.$fileContent);
|
65 |
+
libxml_use_internal_errors(false);
|
66 |
+
return $document;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Helper method that will load file, parse as Instant Article and return the element.
|
71 |
+
* @param string $file File name to be loaded/parsed as InstantArticle.
|
72 |
+
* @param string $encoding "utf-8" by default. Supports and loads the instant article treating file with the informed encoding.
|
73 |
+
*/
|
74 |
+
public function loadInstantArticle($file, $encoding = 'utf-8')
|
75 |
+
{
|
76 |
+
$document = $this->loadDOMDocument($file, $encoding);
|
77 |
+
$parser = new Parser();
|
78 |
+
return $parser->parse($document);
|
79 |
+
}
|
80 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/Greeting.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
|
12 |
+
/*
|
13 |
+
* Sample class used for testing the Observer.
|
14 |
+
*/
|
15 |
+
class Greeting
|
16 |
+
{
|
17 |
+
private $greeting;
|
18 |
+
|
19 |
+
public function __construct($greeting)
|
20 |
+
{
|
21 |
+
$this->greeting = $greeting;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Says hello to someone
|
26 |
+
*/
|
27 |
+
public static function hello($name)
|
28 |
+
{
|
29 |
+
return "Hello $name";
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Method that returns a string greeting someone
|
34 |
+
*/
|
35 |
+
public function greet($name, $middleName = null, $lastName = null)
|
36 |
+
{
|
37 |
+
$name = ($this->greeting).' '.$name;
|
38 |
+
if ($middleName) {
|
39 |
+
$name = $name.' '.$middleName;
|
40 |
+
}
|
41 |
+
if ($lastName) {
|
42 |
+
$name = $name.' '.$lastName;
|
43 |
+
}
|
44 |
+
return $name;
|
45 |
+
}
|
46 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/HookTest.php
ADDED
@@ -0,0 +1,252 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Validators\Type;
|
12 |
+
use PHPUnit\Framework;
|
13 |
+
|
14 |
+
class HookTest extends Framework\TestCase
|
15 |
+
{
|
16 |
+
protected function setUp()
|
17 |
+
{
|
18 |
+
\Logger::configure(
|
19 |
+
[
|
20 |
+
'rootLogger' => [
|
21 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
22 |
+
],
|
23 |
+
'appenders' => [
|
24 |
+
'facebook-instantarticles-traverser' => [
|
25 |
+
'class' => 'LoggerAppenderConsole',
|
26 |
+
'threshold' => 'INFO',
|
27 |
+
'layout' => [
|
28 |
+
'class' => 'LoggerLayoutSimple'
|
29 |
+
]
|
30 |
+
]
|
31 |
+
]
|
32 |
+
]
|
33 |
+
);
|
34 |
+
}
|
35 |
+
|
36 |
+
public function methodHook()
|
37 |
+
{
|
38 |
+
return 'result';
|
39 |
+
}
|
40 |
+
|
41 |
+
public function methodHookReplacing($param1 = null, $param2 = null)
|
42 |
+
{
|
43 |
+
return 'REPLACED' . (isset($param1) && !Type::isTextEmpty($param1) ? '-'.$param1.'-'.$param2 : '');
|
44 |
+
}
|
45 |
+
|
46 |
+
public static function staticMethodHook()
|
47 |
+
{
|
48 |
+
return 'STATIC';
|
49 |
+
}
|
50 |
+
|
51 |
+
public function methodHookBefore1($objToChange)
|
52 |
+
{
|
53 |
+
$objToChange->first = '1st';
|
54 |
+
}
|
55 |
+
|
56 |
+
public function methodHookTestingBefore($objToChange)
|
57 |
+
{
|
58 |
+
return 'MAIN-WITH-BEFORE-'.$objToChange->first.'-'.$objToChange->second;
|
59 |
+
}
|
60 |
+
|
61 |
+
public function methodHookAfter2($objToChange)
|
62 |
+
{
|
63 |
+
$objToChange->second = '2nd';
|
64 |
+
}
|
65 |
+
|
66 |
+
public function methodHookTestingAfter($objToChange)
|
67 |
+
{
|
68 |
+
return 'MAIN-WITH-AFTER-'.$objToChange->first.'-'.$objToChange->second;
|
69 |
+
}
|
70 |
+
|
71 |
+
public static function staticMethodHookParams($arg1, $arg2)
|
72 |
+
{
|
73 |
+
return 'STATIC-with-params-'.$arg1.'-'.$arg2;
|
74 |
+
}
|
75 |
+
|
76 |
+
public function testHookDefault()
|
77 |
+
{
|
78 |
+
$hook = Hook::create();
|
79 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
80 |
+
$this->assertEquals('result', $result);
|
81 |
+
}
|
82 |
+
|
83 |
+
public function testHookReplacingDefault()
|
84 |
+
{
|
85 |
+
$hook = Hook::create();
|
86 |
+
$hook->setHook('hook_name', array($this, 'methodHookReplacing'));
|
87 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
88 |
+
$this->assertEquals('REPLACED', $result);
|
89 |
+
}
|
90 |
+
|
91 |
+
public function testHookReplacingDefaultRemoved()
|
92 |
+
{
|
93 |
+
$hook = Hook::create();
|
94 |
+
$hook->setHook('hook_name', array($this, 'methodHookReplacing'));
|
95 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
96 |
+
$this->assertEquals('REPLACED', $result);
|
97 |
+
|
98 |
+
$hook->removeHook('hook_name');
|
99 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
100 |
+
$this->assertEquals('result', $result);
|
101 |
+
}
|
102 |
+
|
103 |
+
public function testHookRemovingSomethingNeverAdded()
|
104 |
+
{
|
105 |
+
$hook = Hook::create();
|
106 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
107 |
+
$this->assertEquals('result', $result);
|
108 |
+
|
109 |
+
$hook->removeHook('hook_name');
|
110 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
111 |
+
$this->assertEquals('result', $result);
|
112 |
+
}
|
113 |
+
|
114 |
+
public function testHookDefaultBefore()
|
115 |
+
{
|
116 |
+
$hook = Hook::create();
|
117 |
+
$objToChange = new \StdClass;
|
118 |
+
$objToChange->first = '1';
|
119 |
+
$objToChange->second = '2';
|
120 |
+
|
121 |
+
// Calls method without overriding the value, so the return should be 1
|
122 |
+
$objToChange->first = '1';
|
123 |
+
$objToChange->second = '2';
|
124 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingBefore'), array($objToChange));
|
125 |
+
$this->assertEquals('MAIN-WITH-BEFORE-1-2', $result);
|
126 |
+
|
127 |
+
// Calls method overriding the value, so the return should be 1st
|
128 |
+
$objToChange->first = '1';
|
129 |
+
$objToChange->second = '2';
|
130 |
+
$hook->setBeforeHook('hook_name', array($this, 'methodHookBefore1'), array($objToChange));
|
131 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingBefore'), array($objToChange));
|
132 |
+
$this->assertEquals('MAIN-WITH-BEFORE-1st-2', $result);
|
133 |
+
}
|
134 |
+
|
135 |
+
public function testHookDefaultAfter()
|
136 |
+
{
|
137 |
+
$hook = Hook::create();
|
138 |
+
$objToChange = new \StdClass;
|
139 |
+
$objToChange->first = '1';
|
140 |
+
$objToChange->second = '2';
|
141 |
+
|
142 |
+
// Calls method without overriding the value, so the return should be 1
|
143 |
+
$objToChange->first = '1';
|
144 |
+
$objToChange->second = '2';
|
145 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingAfter'), array($objToChange));
|
146 |
+
$this->assertEquals('MAIN-WITH-AFTER-1-2', $result);
|
147 |
+
|
148 |
+
// Calls method overriding the value, so the return should be 2nd
|
149 |
+
$objToChange->first = '1';
|
150 |
+
$objToChange->second = '2';
|
151 |
+
$hook->setAfterHook('hook_name', array($this, 'methodHookAfter2'), array($objToChange));
|
152 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingAfter'), array($objToChange));
|
153 |
+
$this->assertEquals('MAIN-WITH-AFTER-1-2', $result);
|
154 |
+
$this->assertEquals('2nd', $objToChange->second);
|
155 |
+
}
|
156 |
+
|
157 |
+
public function testHookDefaultBeforeAndAfter()
|
158 |
+
{
|
159 |
+
$hook = Hook::create();
|
160 |
+
$objToChange = new \StdClass;
|
161 |
+
$objToChange->first = '1';
|
162 |
+
$objToChange->second = '2';
|
163 |
+
|
164 |
+
// Calls method without overriding the value, so the return should be 1
|
165 |
+
$objToChange->first = '1';
|
166 |
+
$objToChange->second = '2';
|
167 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingBefore'), array($objToChange));
|
168 |
+
$this->assertEquals('MAIN-WITH-BEFORE-1-2', $result);
|
169 |
+
|
170 |
+
// Calls method overriding the value, so the return should be 1st
|
171 |
+
$objToChange->first = '1';
|
172 |
+
$objToChange->second = '2';
|
173 |
+
$hook->setBeforeHook('hook_name', array($this, 'methodHookBefore1'), array($objToChange));
|
174 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingBefore'), array($objToChange));
|
175 |
+
$this->assertEquals('MAIN-WITH-BEFORE-1st-2', $result);
|
176 |
+
|
177 |
+
// Calls method overriding the value, so the return should be 2nd
|
178 |
+
$objToChange->first = '1';
|
179 |
+
$objToChange->second = '2';
|
180 |
+
$hook->setAfterHook('hook_name', array($this, 'methodHookAfter2'), array($objToChange));
|
181 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingAfter'), array($objToChange));
|
182 |
+
$this->assertEquals('MAIN-WITH-AFTER-1st-2', $result);
|
183 |
+
$this->assertEquals('2nd', $objToChange->second);
|
184 |
+
}
|
185 |
+
|
186 |
+
public function testHookDefaultBeforeAndAfterRemoved()
|
187 |
+
{
|
188 |
+
$hook = Hook::create();
|
189 |
+
$objToChange = new \StdClass;
|
190 |
+
|
191 |
+
// Calls method without overriding the value, so the return should be 1
|
192 |
+
$objToChange->first = '1';
|
193 |
+
$objToChange->second = '2';
|
194 |
+
$hook->setBeforeHook('hook_name', array($this, 'methodHookBefore1'), array($objToChange));
|
195 |
+
$hook->setAfterHook('hook_name', array($this, 'methodHookAfter2'), array($objToChange));
|
196 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingAfter'), array($objToChange));
|
197 |
+
$this->assertEquals('MAIN-WITH-AFTER-1st-2', $result);
|
198 |
+
$this->assertEquals('2nd', $objToChange->second);
|
199 |
+
|
200 |
+
$objToChange->first = '1';
|
201 |
+
$objToChange->second = '2';
|
202 |
+
$hook->clearHooks('hook_name');
|
203 |
+
$result = $hook->call('hook_name', array($this, 'methodHookTestingBefore'), array($objToChange));
|
204 |
+
$this->assertEquals('MAIN-WITH-BEFORE-1-2', $result);
|
205 |
+
}
|
206 |
+
|
207 |
+
public function testHookReplacingDefaultParams()
|
208 |
+
{
|
209 |
+
$hook = Hook::create();
|
210 |
+
$hook->setHook('hook_name', array($this, 'methodHookReplacing'), array('param1', 'param2'));
|
211 |
+
$result = $hook->call('hook_name', array($this, 'methodHook'));
|
212 |
+
$this->assertEquals('REPLACED-param1-param2', $result);
|
213 |
+
}
|
214 |
+
|
215 |
+
public function testHookStaticMethod()
|
216 |
+
{
|
217 |
+
$hook = Hook::create();
|
218 |
+
$result = $hook->call('hook_name', array('Facebook\InstantArticles\Utils\HookTest', 'staticMethodHook'));
|
219 |
+
$this->assertEquals('STATIC', $result);
|
220 |
+
}
|
221 |
+
|
222 |
+
public function testHookStaticMethodParams()
|
223 |
+
{
|
224 |
+
$hook = Hook::create();
|
225 |
+
$result = $hook->call('hook_name', array('Facebook\InstantArticles\Utils\HookTest', 'staticMethodHookParams'), array('param1', 'param2'));
|
226 |
+
$this->assertEquals('STATIC-with-params-param1-param2', $result);
|
227 |
+
}
|
228 |
+
|
229 |
+
public function testHookFunctionNoClass()
|
230 |
+
{
|
231 |
+
$hook = Hook::create();
|
232 |
+
$result = $hook->call('hook_name', 'Facebook\InstantArticles\Utils\functionOutsideClass');
|
233 |
+
$this->assertEquals('OUTSIDER', $result);
|
234 |
+
}
|
235 |
+
|
236 |
+
public function testHookFunctionNoClassWithParam()
|
237 |
+
{
|
238 |
+
$hook = Hook::create();
|
239 |
+
$result = $hook->call('hook_name', 'Facebook\InstantArticles\Utils\functionOutsideClassWithParams', array('param1'));
|
240 |
+
$this->assertEquals('OUTSIDER-with-param-param1', $result);
|
241 |
+
}
|
242 |
+
}
|
243 |
+
|
244 |
+
function functionOutsideClass()
|
245 |
+
{
|
246 |
+
return 'OUTSIDER';
|
247 |
+
}
|
248 |
+
|
249 |
+
function functionOutsideClassWithParams($arg1)
|
250 |
+
{
|
251 |
+
return 'OUTSIDER-with-param-'.$arg1;
|
252 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/tests/Facebook/InstantArticles/Utils/ObserverTest.php
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2017-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Utils;
|
10 |
+
|
11 |
+
use PHPUnit\Framework;
|
12 |
+
|
13 |
+
class ObserverTest extends Framework\TestCase
|
14 |
+
{
|
15 |
+
protected function setUp()
|
16 |
+
{
|
17 |
+
\Logger::configure(
|
18 |
+
[
|
19 |
+
'rootLogger' => [
|
20 |
+
'appenders' => ['facebook-instantarticles-traverser']
|
21 |
+
],
|
22 |
+
'appenders' => [
|
23 |
+
'facebook-instantarticles-traverser' => [
|
24 |
+
'class' => 'LoggerAppenderConsole',
|
25 |
+
'threshold' => 'INFO',
|
26 |
+
'layout' => [
|
27 |
+
'class' => 'LoggerLayoutSimple'
|
28 |
+
]
|
29 |
+
]
|
30 |
+
]
|
31 |
+
]
|
32 |
+
);
|
33 |
+
}
|
34 |
+
|
35 |
+
public function testNoFilter()
|
36 |
+
{
|
37 |
+
$observererver = Observer::create();
|
38 |
+
$name = $observererver->applyFilters('name', "Bob");
|
39 |
+
$this->assertEquals('Bob', $name);
|
40 |
+
}
|
41 |
+
|
42 |
+
public function testSingleFilter()
|
43 |
+
{
|
44 |
+
$observer = Observer::create();
|
45 |
+
$observer->addFilter('name', function ($name) {
|
46 |
+
return "$name-san";
|
47 |
+
|
48 |
+
});
|
49 |
+
$name = $observer->applyFilters('name', "Bob");
|
50 |
+
$this->assertEquals('Bob-san', $name);
|
51 |
+
}
|
52 |
+
|
53 |
+
public function testStaticFilter()
|
54 |
+
{
|
55 |
+
$observer = Observer::create();
|
56 |
+
$observer->addFilter('name', array("Facebook\InstantArticles\Utils\Greeting", "hello"));
|
57 |
+
|
58 |
+
$name = $observer->applyFilters('name', "Bob");
|
59 |
+
$this->assertEquals('Hello Bob', $name);
|
60 |
+
}
|
61 |
+
|
62 |
+
public function testFilterWithReferences()
|
63 |
+
{
|
64 |
+
$mr = new Greeting("Mr.");
|
65 |
+
$hello = new Greeting("Hello");
|
66 |
+
|
67 |
+
$observer = Observer::create();
|
68 |
+
$observer->addFilter('name', array(&$mr, "greet"));
|
69 |
+
$observer->addFilter('name', array(&$hello, "greet"));
|
70 |
+
|
71 |
+
$name = $observer->applyFilters('name', "Bob");
|
72 |
+
$this->assertEquals('Hello Mr. Bob', $name);
|
73 |
+
}
|
74 |
+
|
75 |
+
public function testFilterWithParameters()
|
76 |
+
{
|
77 |
+
$hello = new Greeting("Hello");
|
78 |
+
|
79 |
+
$observer = Observer::create();
|
80 |
+
$observer->addFilter('name', array(&$hello, "greet"), 10, 4);
|
81 |
+
|
82 |
+
$name = $observer->applyFilters('name', "Spongebob", "Square", "Pants");
|
83 |
+
$this->assertEquals('Hello Spongebob Square Pants', $name);
|
84 |
+
}
|
85 |
+
|
86 |
+
public function testFilterWithReferencesAndParameters()
|
87 |
+
{
|
88 |
+
$hello = new Greeting("Hello");
|
89 |
+
$mr = new Greeting("Mr.");
|
90 |
+
|
91 |
+
$observer = Observer::create();
|
92 |
+
$observer->addFilter('name', array(&$hello, "greet"), 11, 2);
|
93 |
+
$observer->addFilter('name', array(&$mr, "greet"), 10, 1);
|
94 |
+
|
95 |
+
$name = $observer->applyFilters('name', "Bob", "Bobby");
|
96 |
+
$this->assertEquals('Hello Mr. Bob Bobby', $name);
|
97 |
+
}
|
98 |
+
|
99 |
+
public function testRemoveFilterWithReferencesParameters()
|
100 |
+
{
|
101 |
+
$hello = new Greeting("Hello");
|
102 |
+
$mr = new Greeting("Mr.");
|
103 |
+
|
104 |
+
$observer = Observer::create();
|
105 |
+
$observer->addFilter('name', array(&$hello, "greet"), 11, 2);
|
106 |
+
$observer->addFilter('name', array(&$mr, "greet"), 10, 1);
|
107 |
+
|
108 |
+
$name = $observer->applyFilters('name', "Bob", "Bobby");
|
109 |
+
$this->assertEquals('Hello Mr. Bob Bobby', $name);
|
110 |
+
|
111 |
+
$observer->removeFilter('name', array(&$mr, "greet"), 10);
|
112 |
+
|
113 |
+
$name = $observer->applyFilters('name', "Bob", "Bobby");
|
114 |
+
$this->assertEquals('Hello Bob Bobby', $name);
|
115 |
+
}
|
116 |
+
|
117 |
+
public function testRemoveAllFiltersWithReferencesAndParameters()
|
118 |
+
{
|
119 |
+
$hello = new Greeting("Hello");
|
120 |
+
$mr = new Greeting("Mr.");
|
121 |
+
|
122 |
+
$observer = Observer::create();
|
123 |
+
$observer->addFilter('name', array(&$hello, "greet"), 11, 2);
|
124 |
+
$observer->addFilter('name', array(&$mr, "greet"), 10, 1);
|
125 |
+
|
126 |
+
$name = $observer->applyFilters('name', "Bob", "Bobby");
|
127 |
+
$this->assertEquals('Hello Mr. Bob Bobby', $name);
|
128 |
+
|
129 |
+
$observer->removeAllFilters('name', 11);
|
130 |
+
|
131 |
+
$name = $observer->applyFilters('name', "Bob", "Bobby");
|
132 |
+
$this->assertEquals('Mr. Bob', $name);
|
133 |
+
|
134 |
+
$observer->removeAllFilters('name');
|
135 |
+
|
136 |
+
$name = $observer->applyFilters('name', "Bob", "Bobby");
|
137 |
+
$this->assertEquals('Bob', $name);
|
138 |
+
}
|
139 |
+
|
140 |
+
public function testHasFilter()
|
141 |
+
{
|
142 |
+
$hello = new Greeting("Hello");
|
143 |
+
$mr = new Greeting("Mr.");
|
144 |
+
$mrs = new Greeting("Mrs.");
|
145 |
+
|
146 |
+
$observer = Observer::create();
|
147 |
+
$observer->addFilter('name', array(&$hello, "greet"), 11, 2);
|
148 |
+
$observer->addFilter('name', array(&$mr, "greet"), 10, 1);
|
149 |
+
|
150 |
+
$this->assertEquals(11, $observer->hasFilter('name', array(&$hello, "greet")));
|
151 |
+
$this->assertEquals(10, $observer->hasFilter('name', array(&$mr, "greet")));
|
152 |
+
$this->assertFalse($observer->hasFilter('name', array(&$mrs, "greet")));
|
153 |
+
$this->assertTrue($observer->hasFilter('name'));
|
154 |
+
}
|
155 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-php/.travis.yml
CHANGED
@@ -6,6 +6,7 @@ matrix:
|
|
6 |
- php: 5.5
|
7 |
- php: 5.6
|
8 |
- php: 7
|
|
|
9 |
env: WITH_CS=true
|
10 |
|
11 |
cache:
|
6 |
- php: 5.5
|
7 |
- php: 5.6
|
8 |
- php: 7
|
9 |
+
- php: 7.1
|
10 |
env: WITH_CS=true
|
11 |
|
12 |
cache:
|
vendor/facebook/facebook-instant-articles-sdk-php/README.md
CHANGED
@@ -11,19 +11,31 @@ The SDK consists of three components:
|
|
11 |
- **Client**: A simple wrapper around the [Instant Articles API](https://developers.facebook.com/docs/instant-articles/api), which can be used for publishing Instant Articles on Facebook. The client provides a CRUD interface for Instant Articles as well as a helper for authentication. The client depends on the main [Facebook SDK for PHP](https://github.com/facebook/facebook-php-sdk-v4) as an interface to the Graph API and Facebook Login.
|
12 |
|
13 |
## Quick Start
|
14 |
-
You can find examples on how to use the different components of this SDK to integrate with your CMS in the [Getting Started section](https://developers.facebook.com/docs/instant-articles/sdk/#getting-started) of the documentation.
|
15 |
|
16 |
-
|
17 |
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
|
|
|
|
|
|
20 |
```sh
|
21 |
-
|
22 |
```
|
23 |
|
24 |
-
|
25 |
|
26 |
-
[Composer](https://getcomposer.org/) is a prerequisite for testing and developing. [Install composer globally](https://getcomposer.org/doc/00-intro.md#globally), then install project dependencies by running this command in the project root directory:
|
27 |
```sh
|
28 |
$ composer install
|
29 |
```
|
@@ -53,6 +65,10 @@ If you change structure, paths, namespaces, etc., make sure you run the [autoloa
|
|
53 |
$ composer dump-autoload
|
54 |
```
|
55 |
|
|
|
|
|
|
|
|
|
56 |
## Troubleshooting
|
57 |
|
58 |
If you are encountering problems, the following tips may help in troubleshooting issues:
|
@@ -65,10 +81,6 @@ If you are encountering problems, the following tips may help in troubleshooting
|
|
65 |
|
66 |
- Refer to the existing [tests of the `Elements`](https://github.com/facebook/facebook-instant-articles-sdk-php/tree/master/tests/Facebook/InstantArticles/Elements) for examples of what is required of each and to potentially create your own tests (which can be run with `$ composer test`).
|
67 |
|
68 |
-
## Contributing
|
69 |
-
|
70 |
-
For us to accept contributions you will have to first have signed the [Contributor License Agreement](https://code.facebook.com/cla). Please see [CONTRIBUTING](https://github.com/facebook/facebook-instant-articles-sdk-php/blob/master/CONTRIBUTING.md) for details.
|
71 |
-
|
72 |
## License
|
73 |
|
74 |
Please see the [license file](https://github.com/facebook/facebook-instant-articles-sdk-php/blob/master/LICENSE) for more information.
|
11 |
- **Client**: A simple wrapper around the [Instant Articles API](https://developers.facebook.com/docs/instant-articles/api), which can be used for publishing Instant Articles on Facebook. The client provides a CRUD interface for Instant Articles as well as a helper for authentication. The client depends on the main [Facebook SDK for PHP](https://github.com/facebook/facebook-php-sdk-v4) as an interface to the Graph API and Facebook Login.
|
12 |
|
13 |
## Quick Start
|
|
|
14 |
|
15 |
+
The Facebook Instant Articles PHP SDK can be installed with the [Composer](https://getcomposer.org/) dependency manager by running this command on your project's root folder:
|
16 |
|
17 |
+
```sh
|
18 |
+
$ composer require facebook/facebook-instant-articles-sdk-php
|
19 |
+
```
|
20 |
+
|
21 |
+
After the installation, you can include the auto loader script in your source with:
|
22 |
+
|
23 |
+
```PHP
|
24 |
+
require_once('vendor/autoload.php');
|
25 |
+
```
|
26 |
+
|
27 |
+
## Official Documentation
|
28 |
+
You can find examples on how to use the different components of this SDK to integrate it with your CMS in the [Getting Started](https://developers.facebook.com/docs/instant-articles/sdk/#getting-started) section of the documentation.
|
29 |
|
30 |
+
## Contributing
|
31 |
+
|
32 |
+
Clone the repository
|
33 |
```sh
|
34 |
+
$ git clone https://github.com/facebook/facebook-instant-articles-sdk-php.git
|
35 |
```
|
36 |
|
37 |
+
[Composer](https://getcomposer.org/) is a prerequisite for testing and developing. [Install composer globally](https://getcomposer.org/doc/00-intro.md#globally), then install project dependencies by running this command in the project's root directory:
|
38 |
|
|
|
39 |
```sh
|
40 |
$ composer install
|
41 |
```
|
65 |
$ composer dump-autoload
|
66 |
```
|
67 |
|
68 |
+
___
|
69 |
+
**For us to accept contributions you will have to first sign the [Contributor License Agreement](https://code.facebook.com/cla). Please see [CONTRIBUTING](https://github.com/facebook/facebook-instant-articles-sdk-php/blob/master/CONTRIBUTING.md) for details.**
|
70 |
+
___
|
71 |
+
|
72 |
## Troubleshooting
|
73 |
|
74 |
If you are encountering problems, the following tips may help in troubleshooting issues:
|
81 |
|
82 |
- Refer to the existing [tests of the `Elements`](https://github.com/facebook/facebook-instant-articles-sdk-php/tree/master/tests/Facebook/InstantArticles/Elements) for examples of what is required of each and to potentially create your own tests (which can be run with `$ composer test`).
|
83 |
|
|
|
|
|
|
|
|
|
84 |
## License
|
85 |
|
86 |
Please see the [license file](https://github.com/facebook/facebook-instant-articles-sdk-php/blob/master/LICENSE) for more information.
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/Analytics.php
CHANGED
@@ -45,7 +45,7 @@ class Analytics extends ElementWithHTML
|
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
-
* Sets the source for the
|
49 |
*
|
50 |
* @param string $source The source of the content for your ad.
|
51 |
*
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* Sets the source for the analytics.
|
49 |
*
|
50 |
* @param string $source The source of the content for your ad.
|
51 |
*
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/Emphasized.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2016-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Elements;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* An emphasized text.
|
13 |
+
*
|
14 |
+
* @see {link:https://developers.facebook.com/docs/instant-articles/reference/body-text}
|
15 |
+
*/
|
16 |
+
class Emphasized extends FormattedText
|
17 |
+
{
|
18 |
+
private function __construct()
|
19 |
+
{
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return Emphasized
|
24 |
+
*/
|
25 |
+
public static function create()
|
26 |
+
{
|
27 |
+
return new self();
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Structure and create <em> node.
|
32 |
+
*
|
33 |
+
* @param \DOMDocument $document - The document where this element will be appended (optional).
|
34 |
+
*
|
35 |
+
* @return \DOMElement
|
36 |
+
*/
|
37 |
+
public function toDOMElement($document = null)
|
38 |
+
{
|
39 |
+
if (!$document) {
|
40 |
+
$document = new \DOMDocument();
|
41 |
+
}
|
42 |
+
|
43 |
+
if (!$this->isValid()) {
|
44 |
+
return $this->emptyElement($document);
|
45 |
+
}
|
46 |
+
|
47 |
+
$emphasized = $document->createElement('em');
|
48 |
+
|
49 |
+
$emphasized->appendChild($this->textToDOMDocumentFragment($document));
|
50 |
+
|
51 |
+
return $emphasized;
|
52 |
+
}
|
53 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/InstantArticle.php
CHANGED
@@ -34,7 +34,7 @@ use Facebook\InstantArticles\Validators\Type;
|
|
34 |
|
35 |
class InstantArticle extends Element implements Container, InstantArticleInterface
|
36 |
{
|
37 |
-
const CURRENT_VERSION = '1.
|
38 |
|
39 |
/**
|
40 |
* The meta properties that are used on <head>
|
@@ -56,6 +56,11 @@ class InstantArticle extends Element implements Container, InstantArticleInterfa
|
|
56 |
*/
|
57 |
private $isAutomaticAdPlaced = true;
|
58 |
|
|
|
|
|
|
|
|
|
|
|
59 |
/**
|
60 |
* @var string The charset that will be used. "utf-8" by default.
|
61 |
*/
|
@@ -98,7 +103,6 @@ class InstantArticle extends Element implements Container, InstantArticleInterfa
|
|
98 |
/**
|
99 |
* Private constructor. It must be used the Factory method
|
100 |
* @see InstantArticle#create() For building objects
|
101 |
-
* @return InstantArticle object.
|
102 |
*/
|
103 |
private function __construct()
|
104 |
{
|
@@ -170,6 +174,21 @@ class InstantArticle extends Element implements Container, InstantArticleInterfa
|
|
170 |
return $this;
|
171 |
}
|
172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
/**
|
174 |
* Updates article to use RTL orientation.
|
175 |
*/
|
@@ -449,10 +468,14 @@ class InstantArticle extends Element implements Container, InstantArticleInterfa
|
|
449 |
|
450 |
$this->addMetaProperty('op:markup_version', $this->markupVersion);
|
451 |
if ($this->header && count($this->header->getAds()) > 0) {
|
452 |
-
$this->
|
453 |
-
|
454 |
-
|
455 |
-
|
|
|
|
|
|
|
|
|
456 |
}
|
457 |
|
458 |
if ($this->style) {
|
34 |
|
35 |
class InstantArticle extends Element implements Container, InstantArticleInterface
|
36 |
{
|
37 |
+
const CURRENT_VERSION = '1.6.1';
|
38 |
|
39 |
/**
|
40 |
* The meta properties that are used on <head>
|
56 |
*/
|
57 |
private $isAutomaticAdPlaced = true;
|
58 |
|
59 |
+
/**
|
60 |
+
* @var string The ad density that will be used. "default" by default
|
61 |
+
*/
|
62 |
+
private $adDensity = 'default';
|
63 |
+
|
64 |
/**
|
65 |
* @var string The charset that will be used. "utf-8" by default.
|
66 |
*/
|
103 |
/**
|
104 |
* Private constructor. It must be used the Factory method
|
105 |
* @see InstantArticle#create() For building objects
|
|
|
106 |
*/
|
107 |
private function __construct()
|
108 |
{
|
174 |
return $this;
|
175 |
}
|
176 |
|
177 |
+
/**
|
178 |
+
* Sets the ad density to be used for auto ad placement
|
179 |
+
*
|
180 |
+
* @param string $adDensity Ad density
|
181 |
+
*
|
182 |
+
* @return $this
|
183 |
+
*/
|
184 |
+
public function withAdDensity($adDensity)
|
185 |
+
{
|
186 |
+
Type::enforce($adDensity, Type::STRING);
|
187 |
+
$this->adDensity = $adDensity;
|
188 |
+
|
189 |
+
return $this;
|
190 |
+
}
|
191 |
+
|
192 |
/**
|
193 |
* Updates article to use RTL orientation.
|
194 |
*/
|
468 |
|
469 |
$this->addMetaProperty('op:markup_version', $this->markupVersion);
|
470 |
if ($this->header && count($this->header->getAds()) > 0) {
|
471 |
+
if ($this->isAutomaticAdPlaced) {
|
472 |
+
$this->addMetaProperty(
|
473 |
+
'fb:use_automatic_ad_placement',
|
474 |
+
'enable=true ad_density=' . $this->adDensity
|
475 |
+
);
|
476 |
+
} else {
|
477 |
+
$this->addMetaProperty('fb:use_automatic_ad_placement', 'false');
|
478 |
+
}
|
479 |
}
|
480 |
|
481 |
if ($this->style) {
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Elements/TextContainer.php
CHANGED
@@ -23,7 +23,7 @@ abstract class TextContainer extends Element implements Container
|
|
23 |
/**
|
24 |
* @var array The content is a list of strings and FormattingElements
|
25 |
*/
|
26 |
-
private $textChildren =
|
27 |
|
28 |
/**
|
29 |
* Adds content to the formatted text.
|
@@ -40,6 +40,14 @@ abstract class TextContainer extends Element implements Container
|
|
40 |
return $this;
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/**
|
44 |
* @return string[]|FormattedText[]|TextContainer[] All text token for this text container.
|
45 |
*/
|
23 |
/**
|
24 |
* @var array The content is a list of strings and FormattingElements
|
25 |
*/
|
26 |
+
private $textChildren = array();
|
27 |
|
28 |
/**
|
29 |
* Adds content to the formatted text.
|
40 |
return $this;
|
41 |
}
|
42 |
|
43 |
+
/**
|
44 |
+
* Clears the text.
|
45 |
+
*/
|
46 |
+
public function clearText()
|
47 |
+
{
|
48 |
+
$this->textChildren = array();
|
49 |
+
}
|
50 |
+
|
51 |
/**
|
52 |
* @return string[]|FormattedText[]|TextContainer[] All text token for this text container.
|
53 |
*/
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Parser/Parser.php
CHANGED
@@ -14,12 +14,14 @@ use Facebook\InstantArticles\Validators\Type;
|
|
14 |
|
15 |
class Parser
|
16 |
{
|
|
|
17 |
/**
|
18 |
* @param string|DOMDocument $document The document html of an Instant Article
|
|
|
19 |
*
|
20 |
* @return InstantArticle filled element that was parsed from the DOMDocument parameter
|
21 |
*/
|
22 |
-
public function parse($content)
|
23 |
{
|
24 |
if (Type::is($content, Type::STRING)) {
|
25 |
libxml_use_internal_errors(true);
|
@@ -33,9 +35,11 @@ class Parser
|
|
33 |
$json_file = file_get_contents(__DIR__ . '/instant-articles-rules.json');
|
34 |
|
35 |
$instant_article = InstantArticle::create();
|
36 |
-
$transformer = new Transformer();
|
37 |
-
$transformer->loadRules($json_file);
|
38 |
|
|
|
|
|
|
|
|
|
39 |
$transformer->transform($instant_article, $document);
|
40 |
|
41 |
return $instant_article;
|
14 |
|
15 |
class Parser
|
16 |
{
|
17 |
+
|
18 |
/**
|
19 |
* @param string|DOMDocument $document The document html of an Instant Article
|
20 |
+
* @param Transformer $transformer The Transformer instance to use. A fresh one will be created by default.
|
21 |
*
|
22 |
* @return InstantArticle filled element that was parsed from the DOMDocument parameter
|
23 |
*/
|
24 |
+
public function parse($content, $transformer = null)
|
25 |
{
|
26 |
if (Type::is($content, Type::STRING)) {
|
27 |
libxml_use_internal_errors(true);
|
35 |
$json_file = file_get_contents(__DIR__ . '/instant-articles-rules.json');
|
36 |
|
37 |
$instant_article = InstantArticle::create();
|
|
|
|
|
38 |
|
39 |
+
if ($transformer === null) {
|
40 |
+
$transformer = new Transformer();
|
41 |
+
}
|
42 |
+
$transformer->loadRules($json_file);
|
43 |
$transformer->transform($instant_article, $document);
|
44 |
|
45 |
return $instant_article;
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Parser/instant-articles-rules.json
CHANGED
@@ -56,6 +56,10 @@
|
|
56 |
"class": "ItalicRule",
|
57 |
"selector" : "i"
|
58 |
},
|
|
|
|
|
|
|
|
|
59 |
{
|
60 |
"class": "BoldRule",
|
61 |
"selector" : "b"
|
@@ -245,6 +249,15 @@
|
|
245 |
{
|
246 |
"class": "AuthorRule",
|
247 |
"selector" : "address",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
"properties" : {
|
249 |
"author.url" : {
|
250 |
"type" : "string",
|
@@ -534,7 +547,7 @@
|
|
534 |
},
|
535 |
{
|
536 |
"class": "GeoTagRule",
|
537 |
-
"selector" : "script
|
538 |
"properties" : {
|
539 |
"map.geotag" : {
|
540 |
"type" : "string",
|
56 |
"class": "ItalicRule",
|
57 |
"selector" : "i"
|
58 |
},
|
59 |
+
{
|
60 |
+
"class": "EmphasizedRule",
|
61 |
+
"selector" : "em"
|
62 |
+
},
|
63 |
{
|
64 |
"class": "BoldRule",
|
65 |
"selector" : "b"
|
249 |
{
|
250 |
"class": "AuthorRule",
|
251 |
"selector" : "address",
|
252 |
+
"properties" : {
|
253 |
+
"author.name" : {
|
254 |
+
"type" : "string"
|
255 |
+
}
|
256 |
+
}
|
257 |
+
},
|
258 |
+
{
|
259 |
+
"class": "AuthorRule",
|
260 |
+
"selector" : "//header/address[a]",
|
261 |
"properties" : {
|
262 |
"author.url" : {
|
263 |
"type" : "string",
|
547 |
},
|
548 |
{
|
549 |
"class": "GeoTagRule",
|
550 |
+
"selector" : "script",
|
551 |
"properties" : {
|
552 |
"map.geotag" : {
|
553 |
"type" : "string",
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Rules/EmphasizedRule.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2016-present, Facebook, Inc.
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* This source code is licensed under the license found in the
|
7 |
+
* LICENSE file in the root directory of this source tree.
|
8 |
+
*/
|
9 |
+
namespace Facebook\InstantArticles\Transformer\Rules;
|
10 |
+
|
11 |
+
use Facebook\InstantArticles\Elements\TextContainer;
|
12 |
+
use Facebook\InstantArticles\Elements\Emphasized;
|
13 |
+
|
14 |
+
class EmphasizedRule extends ConfigurationSelectorRule
|
15 |
+
{
|
16 |
+
public function getContextClass()
|
17 |
+
{
|
18 |
+
return TextContainer::getClassName();
|
19 |
+
}
|
20 |
+
|
21 |
+
public static function create()
|
22 |
+
{
|
23 |
+
return new EmphasizedRule();
|
24 |
+
}
|
25 |
+
|
26 |
+
public static function createFrom($configuration)
|
27 |
+
{
|
28 |
+
return self::create()->withSelector($configuration['selector']);
|
29 |
+
}
|
30 |
+
|
31 |
+
public function apply($transformer, $text_container, $element)
|
32 |
+
{
|
33 |
+
$emphasized = Emphasized::create();
|
34 |
+
$text_container->appendText($emphasized);
|
35 |
+
$transformer->transform($emphasized, $element);
|
36 |
+
return $text_container;
|
37 |
+
}
|
38 |
+
}
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Rules/InstantArticleRule.php
CHANGED
@@ -78,6 +78,13 @@ class InstantArticleRule extends ConfigurationSelectorRule
|
|
78 |
$auto_ad_placement = $this->getProperty(self::PROPERTY_AUTO_AD_PLACEMENT, $node);
|
79 |
if ($auto_ad_placement === 'false') {
|
80 |
$instant_article->disableAutomaticAdPlacement();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
$style = $this->getProperty(self::PROPERTY_STYLE, $node);
|
78 |
$auto_ad_placement = $this->getProperty(self::PROPERTY_AUTO_AD_PLACEMENT, $node);
|
79 |
if ($auto_ad_placement === 'false') {
|
80 |
$instant_article->disableAutomaticAdPlacement();
|
81 |
+
} else {
|
82 |
+
$instant_article->enableAutomaticAdPlacement();
|
83 |
+
$pairs = explode(' ', $auto_ad_placement, 2);
|
84 |
+
if (count($pairs) === 2) {
|
85 |
+
list($name, $value) = explode('=', $pairs[1], 2);
|
86 |
+
$instant_article->withAdDensity($value);
|
87 |
+
}
|
88 |
}
|
89 |
|
90 |
$style = $this->getProperty(self::PROPERTY_STYLE, $node);
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Rules/TimeRule.php
CHANGED
@@ -12,6 +12,13 @@ use Facebook\InstantArticles\Elements\Time;
|
|
12 |
use Facebook\InstantArticles\Elements\Header;
|
13 |
use Facebook\InstantArticles\Transformer\Warnings\InvalidSelector;
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
class TimeRule extends ConfigurationSelectorRule
|
16 |
{
|
17 |
const PROPERTY_TIME_TYPE_DEPRECATED = 'article.time_type';
|
@@ -62,7 +69,7 @@ class TimeRule extends ConfigurationSelectorRule
|
|
62 |
$time_string = $this->getProperty(self::PROPERTY_TIME, $node);
|
63 |
if ($time_string) {
|
64 |
$time = Time::create($this->type);
|
65 |
-
$time->withDatetime(new \DateTime($time_string));
|
66 |
$header->withTime($time);
|
67 |
} else {
|
68 |
$transformer->addWarning(
|
12 |
use Facebook\InstantArticles\Elements\Header;
|
13 |
use Facebook\InstantArticles\Transformer\Warnings\InvalidSelector;
|
14 |
|
15 |
+
/**
|
16 |
+
* Rule to parse dates from the document.
|
17 |
+
*
|
18 |
+
* The time zone used will be the default time zone defined on the Transformer.
|
19 |
+
*
|
20 |
+
* @see Transformer::getDefaultDateTimeZone()
|
21 |
+
*/
|
22 |
class TimeRule extends ConfigurationSelectorRule
|
23 |
{
|
24 |
const PROPERTY_TIME_TYPE_DEPRECATED = 'article.time_type';
|
69 |
$time_string = $this->getProperty(self::PROPERTY_TIME, $node);
|
70 |
if ($time_string) {
|
71 |
$time = Time::create($this->type);
|
72 |
+
$time->withDatetime(new \DateTime($time_string, $transformer->getDefaultDateTimeZone()));
|
73 |
$header->withTime($time);
|
74 |
} else {
|
75 |
$transformer->addWarning(
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Transformer/Transformer.php
CHANGED
@@ -46,12 +46,25 @@ class Transformer
|
|
46 |
*/
|
47 |
private $instantArticle;
|
48 |
|
|
|
|
|
|
|
|
|
|
|
49 |
/**
|
50 |
* Flag attribute added to elements processed by a getter, so they
|
51 |
* are not processed again by other rules.
|
52 |
*/
|
53 |
const INSTANT_ARTICLES_PARSED_FLAG = 'data-instant-articles-element-processed';
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
* Clones a node for appending to raw-html containing Elements like Interactive.
|
57 |
*
|
@@ -337,7 +350,7 @@ class Transformer
|
|
337 |
/**
|
338 |
* Overrides all rules already set in this transformer instance.
|
339 |
*
|
340 |
-
* @
|
341 |
*/
|
342 |
public function setRules($rules)
|
343 |
{
|
@@ -349,4 +362,25 @@ class Transformer
|
|
349 |
$this->addRule($rule);
|
350 |
}
|
351 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
}
|
46 |
*/
|
47 |
private $instantArticle;
|
48 |
|
49 |
+
/**
|
50 |
+
* @var DateTimeZone the timezone for parsing dates. It defaults to 'America/Los_Angeles', but can be customized.
|
51 |
+
*/
|
52 |
+
private $defaultDateTimeZone;
|
53 |
+
|
54 |
/**
|
55 |
* Flag attribute added to elements processed by a getter, so they
|
56 |
* are not processed again by other rules.
|
57 |
*/
|
58 |
const INSTANT_ARTICLES_PARSED_FLAG = 'data-instant-articles-element-processed';
|
59 |
|
60 |
+
/**
|
61 |
+
* Initializes default values.
|
62 |
+
*/
|
63 |
+
public function __construct()
|
64 |
+
{
|
65 |
+
$this->defaultDateTimeZone = new \DateTimeZone('America/Los_Angeles');
|
66 |
+
}
|
67 |
+
|
68 |
/**
|
69 |
* Clones a node for appending to raw-html containing Elements like Interactive.
|
70 |
*
|
350 |
/**
|
351 |
* Overrides all rules already set in this transformer instance.
|
352 |
*
|
353 |
+
* @param Rule[] $rules List of configured rules.
|
354 |
*/
|
355 |
public function setRules($rules)
|
356 |
{
|
362 |
$this->addRule($rule);
|
363 |
}
|
364 |
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Sets the default timezone for parsing dates.
|
368 |
+
*
|
369 |
+
* @param DateTimeZone $dateTimeZone
|
370 |
+
*/
|
371 |
+
public function setDefaultDateTimeZone($dateTimeZone)
|
372 |
+
{
|
373 |
+
Type::enforce($dateTimeZone, 'DateTimeZone');
|
374 |
+
$this->defaultDateTimeZone = $dateTimeZone;
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Gets the default timezone for parsing dates.
|
379 |
+
*
|
380 |
+
* @return DateTimeZone
|
381 |
+
*/
|
382 |
+
public function getDefaultDateTimeZone()
|
383 |
+
{
|
384 |
+
return $this->defaultDateTimeZone;
|
385 |
+
}
|
386 |
}
|
vendor/facebook/facebook-instant-articles-sdk-php/src/Facebook/InstantArticles/Validators/Type.php
CHANGED
@@ -386,6 +386,7 @@ class Type
|
|
386 |
* "\n" => true
|
387 |
* "a" => false
|
388 |
* " a " => false
|
|
|
389 |
*
|
390 |
* @param string $text The text that will be checked.
|
391 |
* @return true if empty, false otherwise.
|
@@ -396,8 +397,7 @@ class Type
|
|
396 |
return true;
|
397 |
}
|
398 |
// Stripes empty spaces, , <br/>, new lines
|
399 |
-
$text =
|
400 |
-
$text = preg_replace("/[\r\n\s]+/", "", $text);
|
401 |
$text = str_replace(" ", "", $text);
|
402 |
|
403 |
return empty($text);
|
386 |
* "\n" => true
|
387 |
* "a" => false
|
388 |
* " a " => false
|
389 |
+
* " " => true
|
390 |
*
|
391 |
* @param string $text The text that will be checked.
|
392 |
* @return true if empty, false otherwise.
|
397 |
return true;
|
398 |
}
|
399 |
// Stripes empty spaces, , <br/>, new lines
|
400 |
+
$text = preg_replace("/\s+/", "", $text);
|
|
|
401 |
$text = str_replace(" ", "", $text);
|
402 |
|
403 |
return empty($text);
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/ImageTest.php
CHANGED
@@ -42,13 +42,13 @@ class ImageTest extends \PHPUnit_Framework_TestCase
|
|
42 |
->withURL('https://jpeg.org/images/jpegls-home.jpg')
|
43 |
->withCaption(
|
44 |
Caption::create()
|
45 |
-
->appendText('
|
46 |
);
|
47 |
|
48 |
$expected =
|
49 |
'<figure>'.
|
50 |
'<img src="https://jpeg.org/images/jpegls-home.jpg"/>'.
|
51 |
-
'<figcaption
|
52 |
'</figure>';
|
53 |
|
54 |
$rendered = $image->render();
|
42 |
->withURL('https://jpeg.org/images/jpegls-home.jpg')
|
43 |
->withCaption(
|
44 |
Caption::create()
|
45 |
+
->appendText('<3 some caption to the image')
|
46 |
);
|
47 |
|
48 |
$expected =
|
49 |
'<figure>'.
|
50 |
'<img src="https://jpeg.org/images/jpegls-home.jpg"/>'.
|
51 |
+
'<figcaption><3 some caption to the image</figcaption>'.
|
52 |
'</figure>';
|
53 |
|
54 |
$rendered = $image->render();
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/InstantArticleTest.php
CHANGED
@@ -221,7 +221,7 @@ class InstantArticleTest extends \PHPUnit_Framework_TestCase
|
|
221 |
'<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>'.
|
222 |
'<meta property="op:generator:version" content="'.InstantArticle::CURRENT_VERSION.'"/>'.
|
223 |
'<meta property="op:markup_version" content="v1.0"/>'.
|
224 |
-
'<meta property="fb:use_automatic_ad_placement" content="true"/>'.
|
225 |
'<meta property="fb:article_style" content="myarticlestyle"/>'.
|
226 |
'</head>'.
|
227 |
'<body>'.
|
@@ -282,6 +282,38 @@ class InstantArticleTest extends \PHPUnit_Framework_TestCase
|
|
282 |
$this->assertEquals($expected, $this->article->render());
|
283 |
}
|
284 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
public function testInstantArticleAlmostEmpty()
|
286 |
{
|
287 |
$article =
|
221 |
'<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>'.
|
222 |
'<meta property="op:generator:version" content="'.InstantArticle::CURRENT_VERSION.'"/>'.
|
223 |
'<meta property="op:markup_version" content="v1.0"/>'.
|
224 |
+
'<meta property="fb:use_automatic_ad_placement" content="enable=true ad_density=default"/>'.
|
225 |
'<meta property="fb:article_style" content="myarticlestyle"/>'.
|
226 |
'</head>'.
|
227 |
'<body>'.
|
282 |
$this->assertEquals($expected, $this->article->render());
|
283 |
}
|
284 |
|
285 |
+
public function testRenderWithoutAds()
|
286 |
+
{
|
287 |
+
$article =
|
288 |
+
InstantArticle::create()
|
289 |
+
->disableAutomaticAdPlacement()
|
290 |
+
->withHeader(
|
291 |
+
Header::create()
|
292 |
+
->addAd(
|
293 |
+
Ad::create()
|
294 |
+
)
|
295 |
+
);
|
296 |
+
$result = $article->render();
|
297 |
+
$expected =
|
298 |
+
'<!doctype html>'.
|
299 |
+
'<html>'.
|
300 |
+
'<head>'.
|
301 |
+
'<link rel="canonical" href=""/>'.
|
302 |
+
'<meta charset="utf-8"/>'.
|
303 |
+
'<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>'.
|
304 |
+
'<meta property="op:generator:version" content="'.InstantArticle::CURRENT_VERSION.'"/>'.
|
305 |
+
'<meta property="op:markup_version" content="v1.0"/>'.
|
306 |
+
'<meta property="fb:use_automatic_ad_placement" content="false"/>'.
|
307 |
+
'</head>'.
|
308 |
+
'<body>'.
|
309 |
+
'<article>'.
|
310 |
+
'</article>'.
|
311 |
+
'</body>'.
|
312 |
+
'</html>';
|
313 |
+
|
314 |
+
$this->assertEquals($expected, $result);
|
315 |
+
}
|
316 |
+
|
317 |
public function testInstantArticleAlmostEmpty()
|
318 |
{
|
319 |
$article =
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/ParagraphTest.php
CHANGED
@@ -48,11 +48,13 @@ class ParagraphTest extends \PHPUnit_Framework_TestCase
|
|
48 |
->appendText(' a ')
|
49 |
->appendText(Italic::create()->appendText('paragraph'))
|
50 |
->appendText(' for ')
|
|
|
|
|
51 |
->appendText(Bold::create()->appendText('testing.'));
|
52 |
|
53 |
$expected =
|
54 |
'<p>'.
|
55 |
-
'<b>Some</b> text to be <i>within</i> a <i>paragraph</i> for <b>testing.</b>'.
|
56 |
'</p>';
|
57 |
|
58 |
$rendered = $paragraph->render();
|
48 |
->appendText(' a ')
|
49 |
->appendText(Italic::create()->appendText('paragraph'))
|
50 |
->appendText(' for ')
|
51 |
+
->appendText(Emphasized::create()->appendText('additional'))
|
52 |
+
->appendText(' ')
|
53 |
->appendText(Bold::create()->appendText('testing.'));
|
54 |
|
55 |
$expected =
|
56 |
'<p>'.
|
57 |
+
'<b>Some</b> text to be <i>within</i> a <i>paragraph</i> for <em>additional</em> <b>testing.</b>'.
|
58 |
'</p>';
|
59 |
|
60 |
$rendered = $paragraph->render();
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/Validators/InstantArticleValidatorTest.php
CHANGED
@@ -113,7 +113,7 @@ class InstantArticleValidatorTest extends \PHPUnit_Framework_TestCase
|
|
113 |
$this->assertEquals($expected, $result);
|
114 |
|
115 |
$warnings = InstantArticleValidator::check($article);
|
116 |
-
$this->
|
117 |
}
|
118 |
|
119 |
public function testFooter()
|
@@ -125,7 +125,7 @@ class InstantArticleValidatorTest extends \PHPUnit_Framework_TestCase
|
|
125 |
|
126 |
$warnings = array();
|
127 |
InstantArticleValidator::getReport(array($footer), $warnings);
|
128 |
-
$this->
|
129 |
$this->assertContains('Footer must have at least one of the', $warnings[0]->__toString());
|
130 |
}
|
131 |
}
|
113 |
$this->assertEquals($expected, $result);
|
114 |
|
115 |
$warnings = InstantArticleValidator::check($article);
|
116 |
+
$this->assertCount(9, $warnings);
|
117 |
}
|
118 |
|
119 |
public function testFooter()
|
125 |
|
126 |
$warnings = array();
|
127 |
InstantArticleValidator::getReport(array($footer), $warnings);
|
128 |
+
$this->assertCount(1, $warnings);
|
129 |
$this->assertContains('Footer must have at least one of the', $warnings[0]->__toString());
|
130 |
}
|
131 |
}
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Elements/Validators/TypeTest.php
CHANGED
@@ -340,13 +340,15 @@ class TypeTest extends \PHPUnit_Framework_TestCase
|
|
340 |
$this->assertFalse(Type::isTextEmpty("\nnot empty\t"));
|
341 |
$this->assertFalse(Type::isTextEmpty(" not empty "));
|
342 |
$this->assertFalse(Type::isTextEmpty(" not empty"));
|
|
|
|
|
343 |
}
|
344 |
|
345 |
public function testStringEmpty()
|
346 |
{
|
347 |
$this->assertTrue(Type::isTextEmpty(""));
|
348 |
$this->assertTrue(Type::isTextEmpty(" "));
|
349 |
-
$this->assertTrue(Type::isTextEmpty("\t\
|
350 |
$this->assertTrue(Type::isTextEmpty(" "));
|
351 |
$this->assertTrue(Type::isTextEmpty("\n"));
|
352 |
}
|
340 |
$this->assertFalse(Type::isTextEmpty("\nnot empty\t"));
|
341 |
$this->assertFalse(Type::isTextEmpty(" not empty "));
|
342 |
$this->assertFalse(Type::isTextEmpty(" not empty"));
|
343 |
+
$this->assertFalse(Type::isTextEmpty("<3 strings"));
|
344 |
+
$this->assertFalse(Type::isTextEmpty("<br />"));
|
345 |
}
|
346 |
|
347 |
public function testStringEmpty()
|
348 |
{
|
349 |
$this->assertTrue(Type::isTextEmpty(""));
|
350 |
$this->assertTrue(Type::isTextEmpty(" "));
|
351 |
+
$this->assertTrue(Type::isTextEmpty("\t\n\r"));
|
352 |
$this->assertTrue(Type::isTextEmpty(" "));
|
353 |
$this->assertTrue(Type::isTextEmpty("\n"));
|
354 |
}
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/ParserTest.php
CHANGED
@@ -8,6 +8,8 @@
|
|
8 |
*/
|
9 |
namespace Facebook\InstantArticles\Parser;
|
10 |
|
|
|
|
|
11 |
class ParserTest extends \PHPUnit_Framework_TestCase
|
12 |
{
|
13 |
protected function setUp()
|
@@ -60,4 +62,54 @@ class ParserTest extends \PHPUnit_Framework_TestCase
|
|
60 |
|
61 |
$this->assertEquals($html_file, $result);
|
62 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
8 |
*/
|
9 |
namespace Facebook\InstantArticles\Parser;
|
10 |
|
11 |
+
use Facebook\InstantArticles\Transformer\Transformer;
|
12 |
+
|
13 |
class ParserTest extends \PHPUnit_Framework_TestCase
|
14 |
{
|
15 |
protected function setUp()
|
62 |
|
63 |
$this->assertEquals($html_file, $result);
|
64 |
}
|
65 |
+
|
66 |
+
public function testSelfParseStringNoTimezone()
|
67 |
+
{
|
68 |
+
$html_file_no_timezone = file_get_contents(__DIR__ . '/instant-article-example-no-timezone.html');
|
69 |
+
$html_file_standard_timezone = file_get_contents(__DIR__ . '/instant-article-example-standard-timezone.html');
|
70 |
+
|
71 |
+
$parser = new Parser();
|
72 |
+
$instant_article = $parser->parse($html_file_no_timezone);
|
73 |
+
$instant_article->addMetaProperty('op:generator:version', '1.0.0');
|
74 |
+
$instant_article->addMetaProperty('op:generator:transformer:version', '1.0.0');
|
75 |
+
$result = $instant_article->render('', true)."\n";
|
76 |
+
|
77 |
+
$this->assertEquals($html_file_standard_timezone, $result);
|
78 |
+
}
|
79 |
+
|
80 |
+
public function testSelfParseStringNoTimezoneWithDefaultNYC()
|
81 |
+
{
|
82 |
+
$html_file_no_timezone = file_get_contents(__DIR__ . '/instant-article-example-no-timezone.html');
|
83 |
+
$html_file_standard_timezone = file_get_contents(__DIR__ . '/instant-article-example-nyc-timezone.html');
|
84 |
+
|
85 |
+
$transformer = new Transformer();
|
86 |
+
$transformer->setDefaultDateTimeZone(new \DateTimeZone('America/New_York'));
|
87 |
+
|
88 |
+
$parser = new Parser();
|
89 |
+
$instant_article = $parser->parse($html_file_no_timezone, $transformer);
|
90 |
+
$instant_article->addMetaProperty('op:generator:version', '1.0.0');
|
91 |
+
$instant_article->addMetaProperty('op:generator:transformer:version', '1.0.0');
|
92 |
+
$result = $instant_article->render('', true)."\n";
|
93 |
+
|
94 |
+
$this->assertEquals($html_file_standard_timezone, $result);
|
95 |
+
}
|
96 |
+
|
97 |
+
public function testSelfParseAdPlacementOptions()
|
98 |
+
{
|
99 |
+
$html_file = file_get_contents(__DIR__ . '/instant-article-example-ads.html');
|
100 |
+
|
101 |
+
libxml_use_internal_errors(true);
|
102 |
+
$document = new \DOMDocument();
|
103 |
+
$document->loadHTML($html_file);
|
104 |
+
libxml_use_internal_errors(false);
|
105 |
+
|
106 |
+
$parser = new Parser();
|
107 |
+
$instant_article = $parser->parse($document);
|
108 |
+
$instant_article->addMetaProperty('op:generator:version', '1.0.0');
|
109 |
+
$instant_article->addMetaProperty('op:generator:transformer:version', '1.0.0');
|
110 |
+
|
111 |
+
$result = $instant_article->render('', true)."\n";
|
112 |
+
|
113 |
+
$this->assertEquals($html_file, $result);
|
114 |
+
}
|
115 |
}
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-ads.html
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head>
|
3 |
+
<link rel="canonical" href="http://foo.com/article.html"/>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
6 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
7 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
8 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
9 |
+
<meta property="op:markup_version" content="v1.0"/>
|
10 |
+
<meta property="fb:use_automatic_ad_placement" content="enable=true ad_density=medium"/>
|
11 |
+
<meta property="fb:article_style" content="myarticlestyle"/>
|
12 |
+
</head>
|
13 |
+
<body>
|
14 |
+
<article>
|
15 |
+
<header>
|
16 |
+
<figure>
|
17 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
18 |
+
<figcaption>Some caption to the image</figcaption>
|
19 |
+
</figure>
|
20 |
+
<h1>Big Top Title</h1>
|
21 |
+
<h2>Smaller SubTitle</h2>
|
22 |
+
<time class="op-published" datetime="1984-08-14T19:30:00+00:00">August 14th, 7:30pm</time>
|
23 |
+
<time class="op-modified" datetime="2016-02-10T10:00:00+00:00">February 10th, 10:00am</time>
|
24 |
+
<address><a>Author Name</a>Author more detailed description</address>
|
25 |
+
<address><a href="http://facebook.com/author" rel="facebook">Author in FB</a>Author user in facebook</address>
|
26 |
+
<h3 class="op-kicker">Some kicker of this article</h3>
|
27 |
+
<figure class="op-ad">
|
28 |
+
<iframe src="http://foo.com"></iframe>
|
29 |
+
</figure>
|
30 |
+
</header>
|
31 |
+
<p>Some text to be within a paragraph for testing.</p>
|
32 |
+
<figure class="op-ad">
|
33 |
+
<iframe src="http://foo.com"></iframe>
|
34 |
+
</figure>
|
35 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
36 |
+
</article>
|
37 |
+
</body>
|
38 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-no-timezone.html
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head>
|
3 |
+
<link rel="canonical" href="http://foo.com/article.html"/>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
6 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
7 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
8 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
9 |
+
<meta property="op:markup_version" content="v1.0"/>
|
10 |
+
</head>
|
11 |
+
<body>
|
12 |
+
<article>
|
13 |
+
<header>
|
14 |
+
<figure>
|
15 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
16 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
17 |
+
</figure>
|
18 |
+
<h1>Big Top <b>Title</b></h1>
|
19 |
+
<h2>Smaller <b>SubTitle</b></h2>
|
20 |
+
<time class="op-published" datetime="1984-08-14T19:30:00">August 14th, 7:30pm</time>
|
21 |
+
<time class="op-modified" datetime="2016-02-10T10:00:00">February 10th, 10:00am</time>
|
22 |
+
<address><a href="#" title="Title of author">Author Name</a>
|
23 |
+
Author more detailed description
|
24 |
+
Even more
|
25 |
+
</address>
|
26 |
+
<address><a href="http://facebook.com/author" rel="facebook">Author in FB</a>
|
27 |
+
Author user in facebook
|
28 |
+
</address>
|
29 |
+
<address><a title="PHP Programmer">Developer</a>
|
30 |
+
</address>
|
31 |
+
<h3 class="op-kicker">Some kicker of this article</h3>
|
32 |
+
</header>
|
33 |
+
<p>Some text to be within a paragraph for testing.</p>
|
34 |
+
<figure data-feedback="fb:likes">
|
35 |
+
<img src="http://mydomain.com/path/to/img.jpg"/>
|
36 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
37 |
+
<source src="http://foo.com/mp3"/>
|
38 |
+
</audio>
|
39 |
+
</figure>
|
40 |
+
<figure data-feedback="fb:comments">
|
41 |
+
<img src="http://mydomain.com/path/to/img.jpg"/>
|
42 |
+
<script type="application/json" class="op-geotag">
|
43 |
+
{
|
44 |
+
"type": "Feature",
|
45 |
+
"geometry": {
|
46 |
+
"type": "Point",
|
47 |
+
"coordinates": [23.166667, 89.216667]
|
48 |
+
},
|
49 |
+
"properties": {
|
50 |
+
"title": "Jessore, Bangladesh",
|
51 |
+
"radius": 750000,
|
52 |
+
"pivot": true,
|
53 |
+
"style": "satellite",
|
54 |
+
}
|
55 |
+
}
|
56 |
+
</script>
|
57 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
58 |
+
<source src="http://foo.com/mp3"/>
|
59 |
+
</audio>
|
60 |
+
</figure>
|
61 |
+
<figure data-feedback="fb:likes,fb:comments">
|
62 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
63 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
64 |
+
</figure>
|
65 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
66 |
+
<figure class="op-slideshow">
|
67 |
+
<figure>
|
68 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
69 |
+
</figure>
|
70 |
+
<figure>
|
71 |
+
<img src="https://jpeg.org/images/jpegls-home2.jpg"/>
|
72 |
+
</figure>
|
73 |
+
<figure>
|
74 |
+
<img src="https://jpeg.org/images/jpegls-home3.jpg"/>
|
75 |
+
</figure>
|
76 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
77 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
78 |
+
<source src="http://foo.com/mp3"/>
|
79 |
+
</audio>
|
80 |
+
</figure>
|
81 |
+
<ol>
|
82 |
+
<li>First list item</li>
|
83 |
+
<li>One paragraph on the list</li>
|
84 |
+
<li>On the span</li>
|
85 |
+
<li>Text inside div?</li>
|
86 |
+
<li>Other <a href="#">paragraph</a> on the li</li>
|
87 |
+
<li>Last list item</li>
|
88 |
+
</ol>
|
89 |
+
<p>Some text to be within a paragraph for testing.</p>
|
90 |
+
<figure class="op-interactive">
|
91 |
+
<iframe src="http://example.com/custom-interactive" class="column-width" height="60">
|
92 |
+
<h1>Some custom code</h1>
|
93 |
+
<script>alert("test & more test");</script></iframe>
|
94 |
+
<figcaption>This graphic is awesome.</figcaption>
|
95 |
+
</figure>
|
96 |
+
<figure class="op-ad">
|
97 |
+
<iframe src="http://foo.com"></iframe>
|
98 |
+
</figure>
|
99 |
+
<blockquote>Some blockquotes creates <b>magic</b> in an article</blockquote>
|
100 |
+
<figure class="op-map">
|
101 |
+
<script type="application/json" class="op-geotag">
|
102 |
+
{
|
103 |
+
"type": "Feature",
|
104 |
+
"geometry":
|
105 |
+
{
|
106 |
+
"type": "Point",
|
107 |
+
"coordinates": [23.166667, 89.216667]
|
108 |
+
},
|
109 |
+
"properties":
|
110 |
+
{
|
111 |
+
"title": "Jessore, Bangladesh",
|
112 |
+
"radius": 750000,
|
113 |
+
"pivot": true,
|
114 |
+
"style": "satellite",
|
115 |
+
}
|
116 |
+
}
|
117 |
+
</script>
|
118 |
+
<figcaption class="op-vertical-above"><h1 class="op-vertical-above op-center">title for caption</h1><h2 class="op-vertical-below op-right">sub title for caption</h2>
|
119 |
+
|
120 |
+
|
121 |
+
<cite class="op-vertical-center op-left">credit within caption</cite></figcaption>
|
122 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
123 |
+
<source src="http://foo.com/mp3"/>
|
124 |
+
</audio>
|
125 |
+
</figure>
|
126 |
+
<aside>
|
127 |
+
We can be more efficient about where we grow, what we grow, and how we grow.
|
128 |
+
<cite>Fruit Store Company</cite></aside>
|
129 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
130 |
+
<figure class="op-tracker">
|
131 |
+
<iframe>
|
132 |
+
<h1>Some custom code</h1>
|
133 |
+
<script>alert("test & more test");</script></iframe>
|
134 |
+
</figure>
|
135 |
+
<figure class="op-tracker">
|
136 |
+
<iframe>
|
137 |
+
<h1>Tracker with enclosing on the script</h1>
|
138 |
+
<div><script>alert("test & more test");</script></div>
|
139 |
+
</iframe>
|
140 |
+
</figure>
|
141 |
+
<figure class="op-interactive">
|
142 |
+
<iframe class="no-margin">
|
143 |
+
<h1>Custom code for your social embed</h1>
|
144 |
+
<script>alert("test & more test");</script></iframe>
|
145 |
+
</figure>
|
146 |
+
<figure data-mode="fullscreen" data-feedback="fb:likes,fb:comments">
|
147 |
+
<video data-fb-disable-autoplay="data-fb-disable-autoplay" controls="controls">
|
148 |
+
<source src="http://mydomain.com/path/to/video.mp4" type="video/mp4"/>
|
149 |
+
</video>
|
150 |
+
<figcaption class="op-vertical-below"><h1>Video 1 Title</h1>
|
151 |
+
|
152 |
+
<cite>Attribution Source</cite></figcaption>
|
153 |
+
<script type="application/json" class="op-geotag">
|
154 |
+
{
|
155 |
+
"type": "Feature",
|
156 |
+
"geometry": {
|
157 |
+
"type": "Point",
|
158 |
+
"coordinates": [ [23.166667, 89.216667], [23.166667, 89.216667] ]
|
159 |
+
},
|
160 |
+
"properties": {
|
161 |
+
"title": "Jessore, Bangladesh",
|
162 |
+
"radius": 750000,
|
163 |
+
"pivot": true,
|
164 |
+
"style": "satellite",
|
165 |
+
}
|
166 |
+
}
|
167 |
+
</script>
|
168 |
+
</figure>
|
169 |
+
<ul class="op-related-articles" title="The related ones in the middle">
|
170 |
+
<li>
|
171 |
+
<a href="http://example.com/article.html"></a>
|
172 |
+
</li>
|
173 |
+
<li data-sponsored="true">
|
174 |
+
<a href="http://example.com/sponsored-article.html"></a>
|
175 |
+
</li>
|
176 |
+
<li>
|
177 |
+
<a href="http://example.com/another-article.html"></a>
|
178 |
+
</li>
|
179 |
+
</ul>
|
180 |
+
<footer>
|
181 |
+
<aside>
|
182 |
+
<p>Some plaintext credits to<a href="http://facebook.com/author" rel="facebook">Author</a></p>
|
183 |
+
<p>Paragraph text as credits</p>
|
184 |
+
</aside>
|
185 |
+
<ul class="op-related-articles">
|
186 |
+
<li>
|
187 |
+
<a href="http://example.com/article.html"></a>
|
188 |
+
</li>
|
189 |
+
<li data-sponsored="true">
|
190 |
+
<a href="http://example.com/sponsored-article.html"></a>
|
191 |
+
</li>
|
192 |
+
<li>
|
193 |
+
<a href="http://example.com/another-article.html"></a>
|
194 |
+
</li>
|
195 |
+
</ul>
|
196 |
+
</footer>
|
197 |
+
</article>
|
198 |
+
</body>
|
199 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-nyc-timezone.html
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head>
|
3 |
+
<link rel="canonical" href="http://foo.com/article.html"/>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
6 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
7 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
8 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
9 |
+
<meta property="op:markup_version" content="v1.0"/>
|
10 |
+
</head>
|
11 |
+
<body>
|
12 |
+
<article>
|
13 |
+
<header>
|
14 |
+
<figure>
|
15 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
16 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
17 |
+
</figure>
|
18 |
+
<h1>Big Top <b>Title</b></h1>
|
19 |
+
<h2>Smaller <b>SubTitle</b></h2>
|
20 |
+
<time class="op-published" datetime="1984-08-14T19:30:00-04:00">August 14th, 7:30pm</time>
|
21 |
+
<time class="op-modified" datetime="2016-02-10T10:00:00-05:00">February 10th, 10:00am</time>
|
22 |
+
<address><a href="#" title="Title of author">Author Name</a>
|
23 |
+
Author more detailed description
|
24 |
+
Even more
|
25 |
+
</address>
|
26 |
+
<address><a href="http://facebook.com/author" rel="facebook">Author in FB</a>
|
27 |
+
Author user in facebook
|
28 |
+
</address>
|
29 |
+
<address><a title="PHP Programmer">Developer</a>
|
30 |
+
</address>
|
31 |
+
<h3 class="op-kicker">Some kicker of this article</h3>
|
32 |
+
</header>
|
33 |
+
<p>Some text to be within a paragraph for testing.</p>
|
34 |
+
<figure data-feedback="fb:likes">
|
35 |
+
<img src="http://mydomain.com/path/to/img.jpg"/>
|
36 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
37 |
+
<source src="http://foo.com/mp3"/>
|
38 |
+
</audio>
|
39 |
+
</figure>
|
40 |
+
<figure data-feedback="fb:comments">
|
41 |
+
<img src="http://mydomain.com/path/to/img.jpg"/>
|
42 |
+
<script type="application/json" class="op-geotag">
|
43 |
+
{
|
44 |
+
"type": "Feature",
|
45 |
+
"geometry": {
|
46 |
+
"type": "Point",
|
47 |
+
"coordinates": [23.166667, 89.216667]
|
48 |
+
},
|
49 |
+
"properties": {
|
50 |
+
"title": "Jessore, Bangladesh",
|
51 |
+
"radius": 750000,
|
52 |
+
"pivot": true,
|
53 |
+
"style": "satellite",
|
54 |
+
}
|
55 |
+
}
|
56 |
+
</script>
|
57 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
58 |
+
<source src="http://foo.com/mp3"/>
|
59 |
+
</audio>
|
60 |
+
</figure>
|
61 |
+
<figure data-feedback="fb:likes,fb:comments">
|
62 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
63 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
64 |
+
</figure>
|
65 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
66 |
+
<figure class="op-slideshow">
|
67 |
+
<figure>
|
68 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
69 |
+
</figure>
|
70 |
+
<figure>
|
71 |
+
<img src="https://jpeg.org/images/jpegls-home2.jpg"/>
|
72 |
+
</figure>
|
73 |
+
<figure>
|
74 |
+
<img src="https://jpeg.org/images/jpegls-home3.jpg"/>
|
75 |
+
</figure>
|
76 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
77 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
78 |
+
<source src="http://foo.com/mp3"/>
|
79 |
+
</audio>
|
80 |
+
</figure>
|
81 |
+
<ol>
|
82 |
+
<li>First list item</li>
|
83 |
+
<li>One paragraph on the list</li>
|
84 |
+
<li>On the span</li>
|
85 |
+
<li>Text inside div?</li>
|
86 |
+
<li>Other <a href="#">paragraph</a> on the li</li>
|
87 |
+
<li>Last list item</li>
|
88 |
+
</ol>
|
89 |
+
<p>Some text to be within a paragraph for testing.</p>
|
90 |
+
<figure class="op-interactive">
|
91 |
+
<iframe src="http://example.com/custom-interactive" class="column-width" height="60">
|
92 |
+
<h1>Some custom code</h1>
|
93 |
+
<script>alert("test & more test");</script></iframe>
|
94 |
+
<figcaption>This graphic is awesome.</figcaption>
|
95 |
+
</figure>
|
96 |
+
<figure class="op-ad">
|
97 |
+
<iframe src="http://foo.com"></iframe>
|
98 |
+
</figure>
|
99 |
+
<blockquote>Some blockquotes creates <b>magic</b> in an article</blockquote>
|
100 |
+
<figure class="op-map">
|
101 |
+
<script type="application/json" class="op-geotag">
|
102 |
+
{
|
103 |
+
"type": "Feature",
|
104 |
+
"geometry":
|
105 |
+
{
|
106 |
+
"type": "Point",
|
107 |
+
"coordinates": [23.166667, 89.216667]
|
108 |
+
},
|
109 |
+
"properties":
|
110 |
+
{
|
111 |
+
"title": "Jessore, Bangladesh",
|
112 |
+
"radius": 750000,
|
113 |
+
"pivot": true,
|
114 |
+
"style": "satellite",
|
115 |
+
}
|
116 |
+
}
|
117 |
+
</script>
|
118 |
+
<figcaption class="op-vertical-above"><h1 class="op-vertical-above op-center">title for caption</h1><h2 class="op-vertical-below op-right">sub title for caption</h2>
|
119 |
+
|
120 |
+
|
121 |
+
<cite class="op-vertical-center op-left">credit within caption</cite></figcaption>
|
122 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
123 |
+
<source src="http://foo.com/mp3"/>
|
124 |
+
</audio>
|
125 |
+
</figure>
|
126 |
+
<aside>
|
127 |
+
We can be more efficient about where we grow, what we grow, and how we grow.
|
128 |
+
<cite>Fruit Store Company</cite></aside>
|
129 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
130 |
+
<figure class="op-tracker">
|
131 |
+
<iframe>
|
132 |
+
<h1>Some custom code</h1>
|
133 |
+
<script>alert("test & more test");</script></iframe>
|
134 |
+
</figure>
|
135 |
+
<figure class="op-tracker">
|
136 |
+
<iframe>
|
137 |
+
<h1>Tracker with enclosing on the script</h1>
|
138 |
+
<div><script>alert("test & more test");</script></div>
|
139 |
+
</iframe>
|
140 |
+
</figure>
|
141 |
+
<figure class="op-interactive">
|
142 |
+
<iframe class="no-margin">
|
143 |
+
<h1>Custom code for your social embed</h1>
|
144 |
+
<script>alert("test & more test");</script></iframe>
|
145 |
+
</figure>
|
146 |
+
<figure data-mode="fullscreen" data-feedback="fb:likes,fb:comments">
|
147 |
+
<video data-fb-disable-autoplay="data-fb-disable-autoplay" controls="controls">
|
148 |
+
<source src="http://mydomain.com/path/to/video.mp4" type="video/mp4"/>
|
149 |
+
</video>
|
150 |
+
<figcaption class="op-vertical-below"><h1>Video 1 Title</h1>
|
151 |
+
|
152 |
+
<cite>Attribution Source</cite></figcaption>
|
153 |
+
<script type="application/json" class="op-geotag">
|
154 |
+
{
|
155 |
+
"type": "Feature",
|
156 |
+
"geometry": {
|
157 |
+
"type": "Point",
|
158 |
+
"coordinates": [ [23.166667, 89.216667], [23.166667, 89.216667] ]
|
159 |
+
},
|
160 |
+
"properties": {
|
161 |
+
"title": "Jessore, Bangladesh",
|
162 |
+
"radius": 750000,
|
163 |
+
"pivot": true,
|
164 |
+
"style": "satellite",
|
165 |
+
}
|
166 |
+
}
|
167 |
+
</script>
|
168 |
+
</figure>
|
169 |
+
<ul class="op-related-articles" title="The related ones in the middle">
|
170 |
+
<li>
|
171 |
+
<a href="http://example.com/article.html"></a>
|
172 |
+
</li>
|
173 |
+
<li data-sponsored="true">
|
174 |
+
<a href="http://example.com/sponsored-article.html"></a>
|
175 |
+
</li>
|
176 |
+
<li>
|
177 |
+
<a href="http://example.com/another-article.html"></a>
|
178 |
+
</li>
|
179 |
+
</ul>
|
180 |
+
<footer>
|
181 |
+
<aside>
|
182 |
+
<p>Some plaintext credits to<a href="http://facebook.com/author" rel="facebook">Author</a></p>
|
183 |
+
<p>Paragraph text as credits</p>
|
184 |
+
</aside>
|
185 |
+
<ul class="op-related-articles">
|
186 |
+
<li>
|
187 |
+
<a href="http://example.com/article.html"></a>
|
188 |
+
</li>
|
189 |
+
<li data-sponsored="true">
|
190 |
+
<a href="http://example.com/sponsored-article.html"></a>
|
191 |
+
</li>
|
192 |
+
<li>
|
193 |
+
<a href="http://example.com/another-article.html"></a>
|
194 |
+
</li>
|
195 |
+
</ul>
|
196 |
+
</footer>
|
197 |
+
</article>
|
198 |
+
</body>
|
199 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example-standard-timezone.html
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head>
|
3 |
+
<link rel="canonical" href="http://foo.com/article.html"/>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<meta property="op:generator" content="facebook-instant-articles-sdk-php"/>
|
6 |
+
<meta property="op:generator:version" content="1.0.0"/>
|
7 |
+
<meta property="op:generator:transformer" content="facebook-instant-articles-sdk-php"/>
|
8 |
+
<meta property="op:generator:transformer:version" content="1.0.0"/>
|
9 |
+
<meta property="op:markup_version" content="v1.0"/>
|
10 |
+
</head>
|
11 |
+
<body>
|
12 |
+
<article>
|
13 |
+
<header>
|
14 |
+
<figure>
|
15 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
16 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
17 |
+
</figure>
|
18 |
+
<h1>Big Top <b>Title</b></h1>
|
19 |
+
<h2>Smaller <b>SubTitle</b></h2>
|
20 |
+
<time class="op-published" datetime="1984-08-14T19:30:00-07:00">August 14th, 7:30pm</time>
|
21 |
+
<time class="op-modified" datetime="2016-02-10T10:00:00-08:00">February 10th, 10:00am</time>
|
22 |
+
<address><a href="#" title="Title of author">Author Name</a>
|
23 |
+
Author more detailed description
|
24 |
+
Even more
|
25 |
+
</address>
|
26 |
+
<address><a href="http://facebook.com/author" rel="facebook">Author in FB</a>
|
27 |
+
Author user in facebook
|
28 |
+
</address>
|
29 |
+
<address><a title="PHP Programmer">Developer</a>
|
30 |
+
</address>
|
31 |
+
<h3 class="op-kicker">Some kicker of this article</h3>
|
32 |
+
</header>
|
33 |
+
<p>Some text to be within a paragraph for testing.</p>
|
34 |
+
<figure data-feedback="fb:likes">
|
35 |
+
<img src="http://mydomain.com/path/to/img.jpg"/>
|
36 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
37 |
+
<source src="http://foo.com/mp3"/>
|
38 |
+
</audio>
|
39 |
+
</figure>
|
40 |
+
<figure data-feedback="fb:comments">
|
41 |
+
<img src="http://mydomain.com/path/to/img.jpg"/>
|
42 |
+
<script type="application/json" class="op-geotag">
|
43 |
+
{
|
44 |
+
"type": "Feature",
|
45 |
+
"geometry": {
|
46 |
+
"type": "Point",
|
47 |
+
"coordinates": [23.166667, 89.216667]
|
48 |
+
},
|
49 |
+
"properties": {
|
50 |
+
"title": "Jessore, Bangladesh",
|
51 |
+
"radius": 750000,
|
52 |
+
"pivot": true,
|
53 |
+
"style": "satellite",
|
54 |
+
}
|
55 |
+
}
|
56 |
+
</script>
|
57 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
58 |
+
<source src="http://foo.com/mp3"/>
|
59 |
+
</audio>
|
60 |
+
</figure>
|
61 |
+
<figure data-feedback="fb:likes,fb:comments">
|
62 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
63 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
64 |
+
</figure>
|
65 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
66 |
+
<figure class="op-slideshow">
|
67 |
+
<figure>
|
68 |
+
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
69 |
+
</figure>
|
70 |
+
<figure>
|
71 |
+
<img src="https://jpeg.org/images/jpegls-home2.jpg"/>
|
72 |
+
</figure>
|
73 |
+
<figure>
|
74 |
+
<img src="https://jpeg.org/images/jpegls-home3.jpg"/>
|
75 |
+
</figure>
|
76 |
+
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
77 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
78 |
+
<source src="http://foo.com/mp3"/>
|
79 |
+
</audio>
|
80 |
+
</figure>
|
81 |
+
<ol>
|
82 |
+
<li>First list item</li>
|
83 |
+
<li>One paragraph on the list</li>
|
84 |
+
<li>On the span</li>
|
85 |
+
<li>Text inside div?</li>
|
86 |
+
<li>Other <a href="#">paragraph</a> on the li</li>
|
87 |
+
<li>Last list item</li>
|
88 |
+
</ol>
|
89 |
+
<p>Some text to be within a paragraph for testing.</p>
|
90 |
+
<figure class="op-interactive">
|
91 |
+
<iframe src="http://example.com/custom-interactive" class="column-width" height="60">
|
92 |
+
<h1>Some custom code</h1>
|
93 |
+
<script>alert("test & more test");</script></iframe>
|
94 |
+
<figcaption>This graphic is awesome.</figcaption>
|
95 |
+
</figure>
|
96 |
+
<figure class="op-ad">
|
97 |
+
<iframe src="http://foo.com"></iframe>
|
98 |
+
</figure>
|
99 |
+
<blockquote>Some blockquotes creates <b>magic</b> in an article</blockquote>
|
100 |
+
<figure class="op-map">
|
101 |
+
<script type="application/json" class="op-geotag">
|
102 |
+
{
|
103 |
+
"type": "Feature",
|
104 |
+
"geometry":
|
105 |
+
{
|
106 |
+
"type": "Point",
|
107 |
+
"coordinates": [23.166667, 89.216667]
|
108 |
+
},
|
109 |
+
"properties":
|
110 |
+
{
|
111 |
+
"title": "Jessore, Bangladesh",
|
112 |
+
"radius": 750000,
|
113 |
+
"pivot": true,
|
114 |
+
"style": "satellite",
|
115 |
+
}
|
116 |
+
}
|
117 |
+
</script>
|
118 |
+
<figcaption class="op-vertical-above"><h1 class="op-vertical-above op-center">title for caption</h1><h2 class="op-vertical-below op-right">sub title for caption</h2>
|
119 |
+
|
120 |
+
|
121 |
+
<cite class="op-vertical-center op-left">credit within caption</cite></figcaption>
|
122 |
+
<audio title="audio title" autoplay="autoplay" muted="muted">
|
123 |
+
<source src="http://foo.com/mp3"/>
|
124 |
+
</audio>
|
125 |
+
</figure>
|
126 |
+
<aside>
|
127 |
+
We can be more efficient about where we grow, what we grow, and how we grow.
|
128 |
+
<cite>Fruit Store Company</cite></aside>
|
129 |
+
<p>Other text to be within a second paragraph for testing.</p>
|
130 |
+
<figure class="op-tracker">
|
131 |
+
<iframe>
|
132 |
+
<h1>Some custom code</h1>
|
133 |
+
<script>alert("test & more test");</script></iframe>
|
134 |
+
</figure>
|
135 |
+
<figure class="op-tracker">
|
136 |
+
<iframe>
|
137 |
+
<h1>Tracker with enclosing on the script</h1>
|
138 |
+
<div><script>alert("test & more test");</script></div>
|
139 |
+
</iframe>
|
140 |
+
</figure>
|
141 |
+
<figure class="op-interactive">
|
142 |
+
<iframe class="no-margin">
|
143 |
+
<h1>Custom code for your social embed</h1>
|
144 |
+
<script>alert("test & more test");</script></iframe>
|
145 |
+
</figure>
|
146 |
+
<figure data-mode="fullscreen" data-feedback="fb:likes,fb:comments">
|
147 |
+
<video data-fb-disable-autoplay="data-fb-disable-autoplay" controls="controls">
|
148 |
+
<source src="http://mydomain.com/path/to/video.mp4" type="video/mp4"/>
|
149 |
+
</video>
|
150 |
+
<figcaption class="op-vertical-below"><h1>Video 1 Title</h1>
|
151 |
+
|
152 |
+
<cite>Attribution Source</cite></figcaption>
|
153 |
+
<script type="application/json" class="op-geotag">
|
154 |
+
{
|
155 |
+
"type": "Feature",
|
156 |
+
"geometry": {
|
157 |
+
"type": "Point",
|
158 |
+
"coordinates": [ [23.166667, 89.216667], [23.166667, 89.216667] ]
|
159 |
+
},
|
160 |
+
"properties": {
|
161 |
+
"title": "Jessore, Bangladesh",
|
162 |
+
"radius": 750000,
|
163 |
+
"pivot": true,
|
164 |
+
"style": "satellite",
|
165 |
+
}
|
166 |
+
}
|
167 |
+
</script>
|
168 |
+
</figure>
|
169 |
+
<ul class="op-related-articles" title="The related ones in the middle">
|
170 |
+
<li>
|
171 |
+
<a href="http://example.com/article.html"></a>
|
172 |
+
</li>
|
173 |
+
<li data-sponsored="true">
|
174 |
+
<a href="http://example.com/sponsored-article.html"></a>
|
175 |
+
</li>
|
176 |
+
<li>
|
177 |
+
<a href="http://example.com/another-article.html"></a>
|
178 |
+
</li>
|
179 |
+
</ul>
|
180 |
+
<footer>
|
181 |
+
<aside>
|
182 |
+
<p>Some plaintext credits to<a href="http://facebook.com/author" rel="facebook">Author</a></p>
|
183 |
+
<p>Paragraph text as credits</p>
|
184 |
+
</aside>
|
185 |
+
<ul class="op-related-articles">
|
186 |
+
<li>
|
187 |
+
<a href="http://example.com/article.html"></a>
|
188 |
+
</li>
|
189 |
+
<li data-sponsored="true">
|
190 |
+
<a href="http://example.com/sponsored-article.html"></a>
|
191 |
+
</li>
|
192 |
+
<li>
|
193 |
+
<a href="http://example.com/another-article.html"></a>
|
194 |
+
</li>
|
195 |
+
</ul>
|
196 |
+
</footer>
|
197 |
+
</article>
|
198 |
+
</body>
|
199 |
+
</html>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Parser/instant-article-example.html
CHANGED
@@ -63,7 +63,7 @@
|
|
63 |
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
64 |
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
65 |
</figure>
|
66 |
-
<p>Other text to be within a second paragraph for testing.</p>
|
67 |
<figure class="op-slideshow">
|
68 |
<figure>
|
69 |
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
63 |
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
64 |
<figcaption><h1>Image Name</h1>Some text on text node<cite>Some caption to the image</cite></figcaption>
|
65 |
</figure>
|
66 |
+
<p>Other text to be within a <em>second paragraph</em> for testing.</p>
|
67 |
<figure class="op-slideshow">
|
68 |
<figure>
|
69 |
<img src="https://jpeg.org/images/jpegls-home.jpg"/>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/CustomHTMLTransformerTest.php
CHANGED
@@ -73,6 +73,6 @@ class CustomHTMLTransformerTest extends \PHPUnit_Framework_TestCase
|
|
73 |
|
74 |
$this->assertEquals($expected, $result);
|
75 |
// there must be 3 warnings related to <img> inside <li> that is not supported by IA
|
76 |
-
$this->
|
77 |
}
|
78 |
}
|
73 |
|
74 |
$this->assertEquals($expected, $result);
|
75 |
// there must be 3 warnings related to <img> inside <li> that is not supported by IA
|
76 |
+
$this->assertCount(3, $transformer->getWarnings());
|
77 |
}
|
78 |
}
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/Example/simple-ia.html
CHANGED
@@ -11,56 +11,13 @@
|
|
11 |
<body>
|
12 |
<article>
|
13 |
<header>
|
14 |
-
<
|
15 |
-
<img src="http://domain.com/image-header.png"/>
|
16 |
-
<figcaption>Some amazing moment captured by Photographer</figcaption>
|
17 |
-
</figure>
|
18 |
-
<h1>The article <b>title</b></h1>
|
19 |
-
<h2>Sub <b>Title</b></h2>
|
20 |
-
<address><a>Author name</a></address>
|
21 |
</header>
|
22 |
-
<p>Lorem <b>ipsum</b> dolor sit amet
|
23 |
-
<p>Vivamus mattis, sem id consequat dapibus, odio urna fermentum risus, in blandit dolor justo vel ex. Curabitur a neque bibendum, hendrerit sem in, congue lectus.</p>
|
24 |
<figure>
|
25 |
<img src="http://domain.com/image-body.png"/>
|
26 |
<figcaption>Photographer</figcaption>
|
27 |
</figure>
|
28 |
-
<p>Curabitur vulputate odio eu justo <i>venenatis</i>, a pretium orci placerat. Nam sed neque quis eros vestibulum mattis. Donec vitae mi egestas, laoreet massa et, fringilla libero.</p>
|
29 |
-
<figure class="op-interactive">
|
30 |
-
<iframe>
|
31 |
-
<iframe width="620" height="349" src="https://www.youtube.com/embed/s1tN0ggNreA?feature=oembed" frameborder="0" allowfullscreen=""></iframe>
|
32 |
-
</iframe>
|
33 |
-
</figure>
|
34 |
-
<figure class="op-interactive">
|
35 |
-
<iframe>
|
36 |
-
<h1>Custom code for your social embed</h1>
|
37 |
-
<script>alert("test & more test");</script></iframe>
|
38 |
-
</figure>
|
39 |
-
<figure>
|
40 |
-
<img src="http://domain.com/image-header.png"/>
|
41 |
-
<figcaption>Some amazing moment captured by Photographer</figcaption>
|
42 |
-
</figure>
|
43 |
-
<figure>
|
44 |
-
<img src="http://domain.com/image-header.png?suffix=yes"/>
|
45 |
-
<figcaption>Some amazing moment captured by Photographer</figcaption>
|
46 |
-
</figure>
|
47 |
-
<figure>
|
48 |
-
<img src="http://domain.com/image-header.png?suffix=yes"/>
|
49 |
-
<figcaption>Some amazing moment captured by Photographer</figcaption>
|
50 |
-
</figure>
|
51 |
-
<footer>
|
52 |
-
<ul class="op-related-articles">
|
53 |
-
<li>
|
54 |
-
<a href="http://example.com/article.html"></a>
|
55 |
-
</li>
|
56 |
-
<li data-sponsored="true">
|
57 |
-
<a href="http://example.com/sponsored-article.html"></a>
|
58 |
-
</li>
|
59 |
-
<li>
|
60 |
-
<a href="http://example.com/another-article.html"></a>
|
61 |
-
</li>
|
62 |
-
</ul>
|
63 |
-
</footer>
|
64 |
</article>
|
65 |
</body>
|
66 |
</html>
|
11 |
<body>
|
12 |
<article>
|
13 |
<header>
|
14 |
+
<h1>The article title</h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
</header>
|
16 |
+
<p>Lorem <b>ipsum</b> dolor sit amet.</p>
|
|
|
17 |
<figure>
|
18 |
<img src="http://domain.com/image-body.png"/>
|
19 |
<figcaption>Photographer</figcaption>
|
20 |
</figure>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
</article>
|
22 |
</body>
|
23 |
</html>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/Example/simple.html
CHANGED
@@ -4,51 +4,11 @@
|
|
4 |
</head>
|
5 |
<body>
|
6 |
<div class="header">
|
7 |
-
<h1>The article
|
8 |
-
<h2>Sub <b>Title</b></h2>
|
9 |
-
<span class="author">Author name</span>
|
10 |
-
<div class="hero-image">
|
11 |
-
<img src="http://domain.com/image-header.png" />
|
12 |
-
<div class="image-caption">Some amazing moment captured by Photographer</div>
|
13 |
-
</div>
|
14 |
</div>
|
15 |
-
<p>Lorem <b>ipsum</b> dolor sit amet
|
16 |
-
<p>Vivamus mattis, sem id consequat dapibus, odio urna fermentum risus, in blandit dolor justo vel ex. Curabitur a neque bibendum, hendrerit sem in, congue lectus.</p>
|
17 |
<div class="image">
|
18 |
<img src="http://domain.com/image-body.png" alt="Photographer"/>
|
19 |
</div>
|
20 |
-
<p>Curabitur vulputate odio eu justo <i>venenatis</i>, a pretium orci placerat. Nam sed neque quis eros vestibulum mattis. Donec vitae mi egestas, laoreet massa et, fringilla libero.</p>
|
21 |
-
<div class="embed">
|
22 |
-
<iframe width="620" height="349" src="https://www.youtube.com/embed/s1tN0ggNreA?feature=oembed" frameborder="0" allowfullscreen></iframe>
|
23 |
-
</div>
|
24 |
-
<div class="embed">
|
25 |
-
<h1>Custom code for your social embed</h1>
|
26 |
-
<script>alert("test & more test");</script>
|
27 |
-
</div>
|
28 |
-
<div class="prefix">
|
29 |
-
<img src="//domain.com/image-header.png" />
|
30 |
-
<div class="image-caption">Some amazing moment captured by Photographer</div>
|
31 |
-
</div>
|
32 |
-
<div class="suffix">
|
33 |
-
<img src="http://domain.com/image-header.png" />
|
34 |
-
<div class="image-caption">Some amazing moment captured by Photographer</div>
|
35 |
-
</div>
|
36 |
-
<div class="prefixsuffix">
|
37 |
-
<img src="//domain.com/image-header.png" />
|
38 |
-
<div class="image-caption">Some amazing moment captured by Photographer</div>
|
39 |
-
</div>
|
40 |
-
<footer>
|
41 |
-
<ul class="op-related-articles">
|
42 |
-
<li>
|
43 |
-
<a href="http://example.com/article.html"></a>
|
44 |
-
</li>
|
45 |
-
<li data-sponsored="true">
|
46 |
-
<a href="http://example.com/sponsored-article.html"></a>
|
47 |
-
</li>
|
48 |
-
<li>
|
49 |
-
<a href="http://example.com/another-article.html"></a>
|
50 |
-
</li>
|
51 |
-
</ul>
|
52 |
-
</footer>
|
53 |
</body>
|
54 |
</html>
|
4 |
</head>
|
5 |
<body>
|
6 |
<div class="header">
|
7 |
+
<h1>The article title</h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
</div>
|
9 |
+
<p>Lorem <b>ipsum</b> dolor sit amet.</p>
|
|
|
10 |
<div class="image">
|
11 |
<img src="http://domain.com/image-body.png" alt="Photographer"/>
|
12 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
</body>
|
14 |
</html>
|
vendor/facebook/facebook-instant-articles-sdk-php/tests/Facebook/InstantArticles/Transformer/Rules/AuthorRuleTest.php
CHANGED
@@ -8,6 +8,8 @@
|
|
8 |
*/
|
9 |
namespace Facebook\InstantArticles\Transformer\Rules;
|
10 |
|
|
|
|
|
11 |
class AuthorRuleTest extends \PHPUnit_Framework_TestCase
|
12 |
{
|
13 |
public function testCreateFromProperties()
|
@@ -53,4 +55,38 @@ class AuthorRuleTest extends \PHPUnit_Framework_TestCase
|
|
53 |
);
|
54 |
$this->assertEquals(get_class($author_rule), AuthorRule::getClassName());
|
55 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
8 |
*/
|
9 |
namespace Facebook\InstantArticles\Transformer\Rules;
|
10 |
|
11 |
+
use Facebook\InstantArticles\Parser\Parser;
|
12 |
+
|
13 |
class AuthorRuleTest extends \PHPUnit_Framework_TestCase
|
14 |
{
|
15 |
public function testCreateFromProperties()
|
55 |
);
|
56 |
$this->assertEquals(get_class($author_rule), AuthorRule::getClassName());
|
57 |
}
|
58 |
+
|
59 |
+
public function testExpectedNameWithLink()
|
60 |
+
{
|
61 |
+
$expectedName = "The Author";
|
62 |
+
$html =
|
63 |
+
'<header>'.
|
64 |
+
'<h1>Article Title</h1>'.
|
65 |
+
// The name is inside an <a> element
|
66 |
+
"<address><a>$expectedName</a></address>".
|
67 |
+
'</header>';
|
68 |
+
|
69 |
+
$parser = new Parser();
|
70 |
+
$instantArticle = $parser->parse($html);
|
71 |
+
$author = $instantArticle->getHeader()->getAuthors()[0];
|
72 |
+
|
73 |
+
$this->assertEquals($expectedName, $author->getName());
|
74 |
+
}
|
75 |
+
|
76 |
+
public function testExpectedNameWithoutLink()
|
77 |
+
{
|
78 |
+
$expectedName = "The Other Author";
|
79 |
+
$html =
|
80 |
+
'<header>'.
|
81 |
+
'<h1>Article Title</h1>'.
|
82 |
+
// The name is inside the <address> element
|
83 |
+
"<address>$expectedName</address>".
|
84 |
+
'</header>';
|
85 |
+
|
86 |
+
$parser = new Parser();
|
87 |
+
$instantArticle = $parser->parse($html);
|
88 |
+
$author = $instantArticle->getHeader()->getAuthors()[0];
|
89 |
+
|
90 |
+
$this->assertEquals($expectedName, $author->getName());
|
91 |
+
}
|
92 |
}
|
vendor/squizlabs/php_codesniffer/.gitattributes
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/tests export-ignore
|
2 |
+
/CodeSniffer/Standards/Generic/Tests export-ignore
|
3 |
+
/CodeSniffer/Standards/MySource/Tests export-ignore
|
4 |
+
/CodeSniffer/Standards/PEAR/Tests export-ignore
|
5 |
+
/CodeSniffer/Standards/PSR1/Tests export-ignore
|
6 |
+
/CodeSniffer/Standards/PSR2/Tests export-ignore
|
7 |
+
/CodeSniffer/Standards/Squiz/Tests export-ignore
|
8 |
+
/CodeSniffer/Standards/Zend/Tests export-ignore
|
9 |
+
.travis.yml export-ignore
|
10 |
+
package.xml export-ignore
|
11 |
+
phpunit.xml.dist export-ignore
|
12 |
+
php5-testingConfig.ini export-ignore
|
13 |
+
php7-testingConfig.ini export-ignore
|
vendor/squizlabs/php_codesniffer/.gitignore
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/CodeSniffer.conf
|
2 |
+
/phpcs.xml
|
3 |
+
/phpunit.xml
|
4 |
+
.idea/*
|
5 |
+
/vendor/
|
6 |
+
composer.lock
|
vendor/squizlabs/php_codesniffer/CONTRIBUTING.md
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Contributing
|
2 |
+
-------------
|
3 |
+
|
4 |
+
Before you contribute code to PHP\_CodeSniffer, please make sure it conforms to the PHPCS coding standard and that the PHP\_CodeSniffer unit tests still pass. The easiest way to contribute is to work on a checkout of the repository, or your own fork, rather than an installed PEAR version. If you do this, you can run the following commands to check if everything is ready to submit:
|
5 |
+
|
6 |
+
cd PHP_CodeSniffer
|
7 |
+
php scripts/phpcs
|
8 |
+
|
9 |
+
Which should give you no output, indicating that there are no coding standard errors. And then:
|
10 |
+
|
11 |
+
phpunit
|
12 |
+
|
13 |
+
Which should give you no failures or errors. You can ignore any skipped tests as these are for external tools.
|
vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$phpCodeSnifferConfig = array (
|
3 |
+
'default_standard' => 'PSR2',
|
4 |
+
'report_format' => 'summary',
|
5 |
+
'show_warnings' => '0',
|
6 |
+
'show_progress' => '1',
|
7 |
+
'report_width' => '120',
|
8 |
+
)
|
9 |
+
?>
|
vendor/squizlabs/php_codesniffer/CodeSniffer.php
ADDED
@@ -0,0 +1,2578 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* PHP_CodeSniffer tokenizes PHP code and detects violations of a
|
4 |
+
* defined set of coding standards.
|
5 |
+
*
|
6 |
+
* PHP version 5
|
7 |
+
*
|
8 |
+
* @category PHP
|
9 |
+
* @package PHP_CodeSniffer
|
10 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
11 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
12 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
13 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
14 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
15 |
+
*/
|
16 |
+
|
17 |
+
spl_autoload_register(array('PHP_CodeSniffer', 'autoload'));
|
18 |
+
|
19 |
+
if (class_exists('PHP_CodeSniffer_Exception', true) === false) {
|
20 |
+
throw new Exception('Class PHP_CodeSniffer_Exception not found');
|
21 |
+
}
|
22 |
+
|
23 |
+
if (class_exists('PHP_CodeSniffer_File', true) === false) {
|
24 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_File not found');
|
25 |
+
}
|
26 |
+
|
27 |
+
if (class_exists('PHP_CodeSniffer_Fixer', true) === false) {
|
28 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Fixer not found');
|
29 |
+
}
|
30 |
+
|
31 |
+
if (class_exists('PHP_CodeSniffer_Tokens', true) === false) {
|
32 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Tokens not found');
|
33 |
+
}
|
34 |
+
|
35 |
+
if (class_exists('PHP_CodeSniffer_CLI', true) === false) {
|
36 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_CLI not found');
|
37 |
+
}
|
38 |
+
|
39 |
+
if (interface_exists('PHP_CodeSniffer_Sniff', true) === false) {
|
40 |
+
throw new PHP_CodeSniffer_Exception('Interface PHP_CodeSniffer_Sniff not found');
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* PHP_CodeSniffer tokenizes PHP code and detects violations of a
|
45 |
+
* defined set of coding standards.
|
46 |
+
*
|
47 |
+
* Standards are specified by classes that implement the PHP_CodeSniffer_Sniff
|
48 |
+
* interface. A sniff registers what token types it wishes to listen for, then
|
49 |
+
* PHP_CodeSniffer encounters that token, the sniff is invoked and passed
|
50 |
+
* information about where the token was found in the stack, and the token stack
|
51 |
+
* itself.
|
52 |
+
*
|
53 |
+
* Sniff files and their containing class must be prefixed with Sniff, and
|
54 |
+
* have an extension of .php.
|
55 |
+
*
|
56 |
+
* Multiple PHP_CodeSniffer operations can be performed by re-calling the
|
57 |
+
* process function with different parameters.
|
58 |
+
*
|
59 |
+
* @category PHP
|
60 |
+
* @package PHP_CodeSniffer
|
61 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
62 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
63 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
64 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
65 |
+
* @version Release: @package_version@
|
66 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
67 |
+
*/
|
68 |
+
class PHP_CodeSniffer
|
69 |
+
{
|
70 |
+
|
71 |
+
/**
|
72 |
+
* The current version.
|
73 |
+
*
|
74 |
+
* @var string
|
75 |
+
*/
|
76 |
+
const VERSION = '2.9.1';
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Package stability; either stable, beta or alpha.
|
80 |
+
*
|
81 |
+
* @var string
|
82 |
+
*/
|
83 |
+
const STABILITY = 'stable';
|
84 |
+
|
85 |
+
/**
|
86 |
+
* The file or directory that is currently being processed.
|
87 |
+
*
|
88 |
+
* @var string
|
89 |
+
*/
|
90 |
+
protected $file = '';
|
91 |
+
|
92 |
+
/**
|
93 |
+
* The directories that the processed rulesets are in.
|
94 |
+
*
|
95 |
+
* This is declared static because it is also used in the
|
96 |
+
* autoloader to look for sniffs outside the PHPCS install.
|
97 |
+
* This way, standards designed to be installed inside PHPCS can
|
98 |
+
* also be used from outside the PHPCS Standards directory.
|
99 |
+
*
|
100 |
+
* @var string
|
101 |
+
*/
|
102 |
+
protected static $rulesetDirs = array();
|
103 |
+
|
104 |
+
/**
|
105 |
+
* The CLI object controlling the run.
|
106 |
+
*
|
107 |
+
* @var PHP_CodeSniffer_CLI
|
108 |
+
*/
|
109 |
+
public $cli = null;
|
110 |
+
|
111 |
+
/**
|
112 |
+
* The Reporting object controlling report generation.
|
113 |
+
*
|
114 |
+
* @var PHP_CodeSniffer_Reporting
|
115 |
+
*/
|
116 |
+
public $reporting = null;
|
117 |
+
|
118 |
+
/**
|
119 |
+
* An array of sniff objects that are being used to check files.
|
120 |
+
*
|
121 |
+
* @var array(PHP_CodeSniffer_Sniff)
|
122 |
+
*/
|
123 |
+
protected $listeners = array();
|
124 |
+
|
125 |
+
/**
|
126 |
+
* An array of sniffs that are being used to check files.
|
127 |
+
*
|
128 |
+
* @var array(string)
|
129 |
+
*/
|
130 |
+
protected $sniffs = array();
|
131 |
+
|
132 |
+
/**
|
133 |
+
* A mapping of sniff codes to fully qualified class names.
|
134 |
+
*
|
135 |
+
* The key is the sniff code and the value
|
136 |
+
* is the fully qualified name of the sniff class.
|
137 |
+
*
|
138 |
+
* @var array<string, string>
|
139 |
+
*/
|
140 |
+
public $sniffCodes = array();
|
141 |
+
|
142 |
+
/**
|
143 |
+
* The listeners array, indexed by token type.
|
144 |
+
*
|
145 |
+
* @var array
|
146 |
+
*/
|
147 |
+
private $_tokenListeners = array();
|
148 |
+
|
149 |
+
/**
|
150 |
+
* An array of rules from the ruleset.xml file.
|
151 |
+
*
|
152 |
+
* It may be empty, indicating that the ruleset does not override
|
153 |
+
* any of the default sniff settings.
|
154 |
+
*
|
155 |
+
* @var array
|
156 |
+
*/
|
157 |
+
protected $ruleset = array();
|
158 |
+
|
159 |
+
/**
|
160 |
+
* An array of patterns to use for skipping files.
|
161 |
+
*
|
162 |
+
* @var array
|
163 |
+
*/
|
164 |
+
protected $ignorePatterns = array();
|
165 |
+
|
166 |
+
/**
|
167 |
+
* An array of extensions for files we will check.
|
168 |
+
*
|
169 |
+
* @var array
|
170 |
+
*/
|
171 |
+
public $allowedFileExtensions = array();
|
172 |
+
|
173 |
+
/**
|
174 |
+
* An array of default extensions and associated tokenizers.
|
175 |
+
*
|
176 |
+
* If no extensions are set, these will be used as the defaults.
|
177 |
+
* If extensions are set, these will be used when the correct tokenizer
|
178 |
+
* can not be determined, such as when checking a passed filename instead
|
179 |
+
* of files in a directory.
|
180 |
+
*
|
181 |
+
* @var array
|
182 |
+
*/
|
183 |
+
public $defaultFileExtensions = array(
|
184 |
+
'php' => 'PHP',
|
185 |
+
'inc' => 'PHP',
|
186 |
+
'js' => 'JS',
|
187 |
+
'css' => 'CSS',
|
188 |
+
);
|
189 |
+
|
190 |
+
/**
|
191 |
+
* An array of variable types for param/var we will check.
|
192 |
+
*
|
193 |
+
* @var array(string)
|
194 |
+
*/
|
195 |
+
public static $allowedTypes = array(
|
196 |
+
'array',
|
197 |
+
'boolean',
|
198 |
+
'float',
|
199 |
+
'integer',
|
200 |
+
'mixed',
|
201 |
+
'object',
|
202 |
+
'string',
|
203 |
+
'resource',
|
204 |
+
'callable',
|
205 |
+
);
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Constructs a PHP_CodeSniffer object.
|
210 |
+
*
|
211 |
+
* @param int $verbosity The verbosity level.
|
212 |
+
* 1: Print progress information.
|
213 |
+
* 2: Print tokenizer debug information.
|
214 |
+
* 3: Print sniff debug information.
|
215 |
+
* @param int $tabWidth The number of spaces each tab represents.
|
216 |
+
* If greater than zero, tabs will be replaced
|
217 |
+
* by spaces before testing each file.
|
218 |
+
* @param string $encoding The charset of the sniffed files.
|
219 |
+
* This is important for some reports that output
|
220 |
+
* with utf-8 encoding as you don't want it double
|
221 |
+
* encoding messages.
|
222 |
+
* @param bool $interactive If TRUE, will stop after each file with errors
|
223 |
+
* and wait for user input.
|
224 |
+
*
|
225 |
+
* @see process()
|
226 |
+
*/
|
227 |
+
public function __construct(
|
228 |
+
$verbosity=0,
|
229 |
+
$tabWidth=0,
|
230 |
+
$encoding='iso-8859-1',
|
231 |
+
$interactive=false
|
232 |
+
) {
|
233 |
+
if ($verbosity !== null) {
|
234 |
+
$this->setVerbosity($verbosity);
|
235 |
+
}
|
236 |
+
|
237 |
+
if ($tabWidth !== null) {
|
238 |
+
$this->setTabWidth($tabWidth);
|
239 |
+
}
|
240 |
+
|
241 |
+
if ($encoding !== null) {
|
242 |
+
$this->setEncoding($encoding);
|
243 |
+
}
|
244 |
+
|
245 |
+
if ($interactive !== null) {
|
246 |
+
$this->setInteractive($interactive);
|
247 |
+
}
|
248 |
+
|
249 |
+
if (defined('PHPCS_DEFAULT_ERROR_SEV') === false) {
|
250 |
+
define('PHPCS_DEFAULT_ERROR_SEV', 5);
|
251 |
+
}
|
252 |
+
|
253 |
+
if (defined('PHPCS_DEFAULT_WARN_SEV') === false) {
|
254 |
+
define('PHPCS_DEFAULT_WARN_SEV', 5);
|
255 |
+
}
|
256 |
+
|
257 |
+
if (defined('PHP_CODESNIFFER_CBF') === false) {
|
258 |
+
define('PHP_CODESNIFFER_CBF', false);
|
259 |
+
}
|
260 |
+
|
261 |
+
// Set default CLI object in case someone is running us
|
262 |
+
// without using the command line script.
|
263 |
+
$this->cli = new PHP_CodeSniffer_CLI();
|
264 |
+
$this->cli->errorSeverity = PHPCS_DEFAULT_ERROR_SEV;
|
265 |
+
$this->cli->warningSeverity = PHPCS_DEFAULT_WARN_SEV;
|
266 |
+
$this->cli->dieOnUnknownArg = false;
|
267 |
+
|
268 |
+
$this->reporting = new PHP_CodeSniffer_Reporting();
|
269 |
+
|
270 |
+
}//end __construct()
|
271 |
+
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Autoload static method for loading classes and interfaces.
|
275 |
+
*
|
276 |
+
* @param string $className The name of the class or interface.
|
277 |
+
*
|
278 |
+
* @return void
|
279 |
+
*/
|
280 |
+
public static function autoload($className)
|
281 |
+
{
|
282 |
+
if (substr($className, 0, 4) === 'PHP_') {
|
283 |
+
$newClassName = substr($className, 4);
|
284 |
+
} else {
|
285 |
+
$newClassName = $className;
|
286 |
+
}
|
287 |
+
|
288 |
+
$path = str_replace(array('_', '\\'), DIRECTORY_SEPARATOR, $newClassName).'.php';
|
289 |
+
|
290 |
+
if (is_file(dirname(__FILE__).DIRECTORY_SEPARATOR.$path) === true) {
|
291 |
+
// Check standard file locations based on class name.
|
292 |
+
include dirname(__FILE__).DIRECTORY_SEPARATOR.$path;
|
293 |
+
return;
|
294 |
+
} else {
|
295 |
+
// Check for included sniffs.
|
296 |
+
$installedPaths = PHP_CodeSniffer::getInstalledStandardPaths();
|
297 |
+
foreach ($installedPaths as $installedPath) {
|
298 |
+
if (is_file($installedPath.DIRECTORY_SEPARATOR.$path) === true) {
|
299 |
+
include $installedPath.DIRECTORY_SEPARATOR.$path;
|
300 |
+
return;
|
301 |
+
}
|
302 |
+
}
|
303 |
+
|
304 |
+
// Check standard file locations based on the loaded rulesets.
|
305 |
+
foreach (self::$rulesetDirs as $rulesetDir) {
|
306 |
+
if (is_file(dirname($rulesetDir).DIRECTORY_SEPARATOR.$path) === true) {
|
307 |
+
include_once dirname($rulesetDir).DIRECTORY_SEPARATOR.$path;
|
308 |
+
return;
|
309 |
+
}
|
310 |
+
}
|
311 |
+
}//end if
|
312 |
+
|
313 |
+
// Everything else.
|
314 |
+
@include $path;
|
315 |
+
|
316 |
+
}//end autoload()
|
317 |
+
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Sets the verbosity level.
|
321 |
+
*
|
322 |
+
* @param int $verbosity The verbosity level.
|
323 |
+
* 1: Print progress information.
|
324 |
+
* 2: Print tokenizer debug information.
|
325 |
+
* 3: Print sniff debug information.
|
326 |
+
*
|
327 |
+
* @return void
|
328 |
+
*/
|
329 |
+
public function setVerbosity($verbosity)
|
330 |
+
{
|
331 |
+
if (defined('PHP_CODESNIFFER_VERBOSITY') === false) {
|
332 |
+
define('PHP_CODESNIFFER_VERBOSITY', $verbosity);
|
333 |
+
}
|
334 |
+
|
335 |
+
}//end setVerbosity()
|
336 |
+
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Sets the tab width.
|
340 |
+
*
|
341 |
+
* @param int $tabWidth The number of spaces each tab represents.
|
342 |
+
* If greater than zero, tabs will be replaced
|
343 |
+
* by spaces before testing each file.
|
344 |
+
*
|
345 |
+
* @return void
|
346 |
+
*/
|
347 |
+
public function setTabWidth($tabWidth)
|
348 |
+
{
|
349 |
+
if (defined('PHP_CODESNIFFER_TAB_WIDTH') === false) {
|
350 |
+
define('PHP_CODESNIFFER_TAB_WIDTH', $tabWidth);
|
351 |
+
}
|
352 |
+
|
353 |
+
}//end setTabWidth()
|
354 |
+
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Sets the encoding.
|
358 |
+
*
|
359 |
+
* @param string $encoding The charset of the sniffed files.
|
360 |
+
* This is important for some reports that output
|
361 |
+
* with utf-8 encoding as you don't want it double
|
362 |
+
* encoding messages.
|
363 |
+
*
|
364 |
+
* @return void
|
365 |
+
*/
|
366 |
+
public function setEncoding($encoding)
|
367 |
+
{
|
368 |
+
if (defined('PHP_CODESNIFFER_ENCODING') === false) {
|
369 |
+
define('PHP_CODESNIFFER_ENCODING', $encoding);
|
370 |
+
}
|
371 |
+
|
372 |
+
}//end setEncoding()
|
373 |
+
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Sets the interactive flag.
|
377 |
+
*
|
378 |
+
* @param bool $interactive If TRUE, will stop after each file with errors
|
379 |
+
* and wait for user input.
|
380 |
+
*
|
381 |
+
* @return void
|
382 |
+
*/
|
383 |
+
public function setInteractive($interactive)
|
384 |
+
{
|
385 |
+
if (defined('PHP_CODESNIFFER_INTERACTIVE') === false) {
|
386 |
+
define('PHP_CODESNIFFER_INTERACTIVE', $interactive);
|
387 |
+
}
|
388 |
+
|
389 |
+
}//end setInteractive()
|
390 |
+
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Sets an array of file extensions that we will allow checking of.
|
394 |
+
*
|
395 |
+
* If the extension is one of the defaults, a specific tokenizer
|
396 |
+
* will be used. Otherwise, the PHP tokenizer will be used for
|
397 |
+
* all extensions passed.
|
398 |
+
*
|
399 |
+
* @param array $extensions An array of file extensions.
|
400 |
+
*
|
401 |
+
* @return void
|
402 |
+
*/
|
403 |
+
public function setAllowedFileExtensions(array $extensions)
|
404 |
+
{
|
405 |
+
$newExtensions = array();
|
406 |
+
foreach ($extensions as $ext) {
|
407 |
+
$slash = strpos($ext, '/');
|
408 |
+
if ($slash !== false) {
|
409 |
+
// They specified the tokenizer too.
|
410 |
+
list($ext, $tokenizer) = explode('/', $ext);
|
411 |
+
$newExtensions[$ext] = strtoupper($tokenizer);
|
412 |
+
continue;
|
413 |
+
}
|
414 |
+
|
415 |
+
if (isset($this->allowedFileExtensions[$ext]) === true) {
|
416 |
+
$newExtensions[$ext] = $this->allowedFileExtensions[$ext];
|
417 |
+
} else if (isset($this->defaultFileExtensions[$ext]) === true) {
|
418 |
+
$newExtensions[$ext] = $this->defaultFileExtensions[$ext];
|
419 |
+
} else {
|
420 |
+
$newExtensions[$ext] = 'PHP';
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
$this->allowedFileExtensions = $newExtensions;
|
425 |
+
|
426 |
+
}//end setAllowedFileExtensions()
|
427 |
+
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Sets an array of ignore patterns that we use to skip files and folders.
|
431 |
+
*
|
432 |
+
* Patterns are not case sensitive.
|
433 |
+
*
|
434 |
+
* @param array $patterns An array of ignore patterns. The pattern is the key
|
435 |
+
* and the value is either "absolute" or "relative",
|
436 |
+
* depending on how the pattern should be applied to a
|
437 |
+
* file path.
|
438 |
+
*
|
439 |
+
* @return void
|
440 |
+
*/
|
441 |
+
public function setIgnorePatterns(array $patterns)
|
442 |
+
{
|
443 |
+
$this->ignorePatterns = $patterns;
|
444 |
+
|
445 |
+
}//end setIgnorePatterns()
|
446 |
+
|
447 |
+
|
448 |
+
/**
|
449 |
+
* Gets the array of ignore patterns.
|
450 |
+
*
|
451 |
+
* Optionally takes a listener to get ignore patterns specified
|
452 |
+
* for that sniff only.
|
453 |
+
*
|
454 |
+
* @param string $listener The listener to get patterns for. If NULL, all
|
455 |
+
* patterns are returned.
|
456 |
+
*
|
457 |
+
* @return array
|
458 |
+
*/
|
459 |
+
public function getIgnorePatterns($listener=null)
|
460 |
+
{
|
461 |
+
if ($listener === null) {
|
462 |
+
return $this->ignorePatterns;
|
463 |
+
}
|
464 |
+
|
465 |
+
if (isset($this->ignorePatterns[$listener]) === true) {
|
466 |
+
return $this->ignorePatterns[$listener];
|
467 |
+
}
|
468 |
+
|
469 |
+
return array();
|
470 |
+
|
471 |
+
}//end getIgnorePatterns()
|
472 |
+
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Sets the internal CLI object.
|
476 |
+
*
|
477 |
+
* @param object $cli The CLI object controlling the run.
|
478 |
+
*
|
479 |
+
* @return void
|
480 |
+
*/
|
481 |
+
public function setCli($cli)
|
482 |
+
{
|
483 |
+
$this->cli = $cli;
|
484 |
+
|
485 |
+
}//end setCli()
|
486 |
+
|
487 |
+
|
488 |
+
/**
|
489 |
+
* Start a PHP_CodeSniffer run.
|
490 |
+
*
|
491 |
+
* @param string|array $files The files and directories to process. For
|
492 |
+
* directories, each sub directory will also
|
493 |
+
* be traversed for source files.
|
494 |
+
* @param string|array $standards The set of code sniffs we are testing
|
495 |
+
* against.
|
496 |
+
* @param array $restrictions The sniff codes to restrict the
|
497 |
+
* violations to.
|
498 |
+
* @param boolean $local If true, don't recurse into directories.
|
499 |
+
*
|
500 |
+
* @return void
|
501 |
+
*/
|
502 |
+
public function process($files, $standards, array $restrictions=array(), $local=false)
|
503 |
+
{
|
504 |
+
$files = (array) $files;
|
505 |
+
$this->initStandard($standards, $restrictions);
|
506 |
+
$this->processFiles($files, $local);
|
507 |
+
|
508 |
+
}//end process()
|
509 |
+
|
510 |
+
|
511 |
+
/**
|
512 |
+
* Initialise the standard that the run will use.
|
513 |
+
*
|
514 |
+
* @param string|array $standards The set of code sniffs we are testing
|
515 |
+
* against.
|
516 |
+
* @param array $restrictions The sniff codes to restrict the testing to.
|
517 |
+
* @param array $exclusions The sniff codes to exclude from testing.
|
518 |
+
*
|
519 |
+
* @return void
|
520 |
+
*/
|
521 |
+
public function initStandard($standards, array $restrictions=array(), array $exclusions=array())
|
522 |
+
{
|
523 |
+
$standards = (array) $standards;
|
524 |
+
|
525 |
+
// Reset the members.
|
526 |
+
$this->listeners = array();
|
527 |
+
$this->sniffs = array();
|
528 |
+
$this->ruleset = array();
|
529 |
+
$this->_tokenListeners = array();
|
530 |
+
self::$rulesetDirs = array();
|
531 |
+
|
532 |
+
// Ensure this option is enabled or else line endings will not always
|
533 |
+
// be detected properly for files created on a Mac with the /r line ending.
|
534 |
+
ini_set('auto_detect_line_endings', true);
|
535 |
+
|
536 |
+
if (defined('PHP_CODESNIFFER_IN_TESTS') === true && empty($restrictions) === false) {
|
537 |
+
// Should be one standard and one sniff being tested at a time.
|
538 |
+
$installed = $this->getInstalledStandardPath($standards[0]);
|
539 |
+
if ($installed !== null) {
|
540 |
+
$standard = $installed;
|
541 |
+
} else {
|
542 |
+
$standard = self::realpath($standards[0]);
|
543 |
+
if (is_dir($standard) === true
|
544 |
+
&& is_file(self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml')) === true
|
545 |
+
) {
|
546 |
+
$standard = self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml');
|
547 |
+
}
|
548 |
+
}
|
549 |
+
|
550 |
+
$sniffs = $this->_expandRulesetReference($restrictions[0], dirname($standard));
|
551 |
+
} else {
|
552 |
+
$sniffs = array();
|
553 |
+
foreach ($standards as $standard) {
|
554 |
+
$installed = $this->getInstalledStandardPath($standard);
|
555 |
+
if ($installed !== null) {
|
556 |
+
$standard = $installed;
|
557 |
+
} else {
|
558 |
+
$standard = self::realpath($standard);
|
559 |
+
if (is_dir($standard) === true
|
560 |
+
&& is_file(self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml')) === true
|
561 |
+
) {
|
562 |
+
$standard = self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml');
|
563 |
+
}
|
564 |
+
}
|
565 |
+
|
566 |
+
if (PHP_CODESNIFFER_VERBOSITY === 1) {
|
567 |
+
$ruleset = simplexml_load_string(file_get_contents($standard));
|
568 |
+
if ($ruleset !== false) {
|
569 |
+
$standardName = (string) $ruleset['name'];
|
570 |
+
}
|
571 |
+
|
572 |
+
echo "Registering sniffs in the $standardName standard... ";
|
573 |
+
if (count($standards) > 1 || PHP_CODESNIFFER_VERBOSITY > 2) {
|
574 |
+
echo PHP_EOL;
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
$sniffs = array_merge($sniffs, $this->processRuleset($standard));
|
579 |
+
}//end foreach
|
580 |
+
}//end if
|
581 |
+
|
582 |
+
$sniffRestrictions = array();
|
583 |
+
foreach ($restrictions as $sniffCode) {
|
584 |
+
$parts = explode('.', strtolower($sniffCode));
|
585 |
+
$sniffRestrictions[] = $parts[0].'_sniffs_'.$parts[1].'_'.$parts[2].'sniff';
|
586 |
+
}
|
587 |
+
|
588 |
+
$sniffExclusions = array();
|
589 |
+
foreach ($exclusions as $sniffCode) {
|
590 |
+
$parts = explode('.', strtolower($sniffCode));
|
591 |
+
$sniffExclusions[] = $parts[0].'_sniffs_'.$parts[1].'_'.$parts[2].'sniff';
|
592 |
+
}
|
593 |
+
|
594 |
+
$this->registerSniffs($sniffs, $sniffRestrictions, $sniffExclusions);
|
595 |
+
$this->populateTokenListeners();
|
596 |
+
|
597 |
+
if (PHP_CODESNIFFER_VERBOSITY === 1) {
|
598 |
+
$numSniffs = count($this->sniffs);
|
599 |
+
echo "DONE ($numSniffs sniffs registered)".PHP_EOL;
|
600 |
+
}
|
601 |
+
|
602 |
+
}//end initStandard()
|
603 |
+
|
604 |
+
|
605 |
+
/**
|
606 |
+
* Processes the files/directories that PHP_CodeSniffer was constructed with.
|
607 |
+
*
|
608 |
+
* @param string|array $files The files and directories to process. For
|
609 |
+
* directories, each sub directory will also
|
610 |
+
* be traversed for source files.
|
611 |
+
* @param boolean $local If true, don't recurse into directories.
|
612 |
+
*
|
613 |
+
* @return void
|
614 |
+
* @throws PHP_CodeSniffer_Exception If files are invalid.
|
615 |
+
*/
|
616 |
+
public function processFiles($files, $local=false)
|
617 |
+
{
|
618 |
+
$files = (array) $files;
|
619 |
+
$cliValues = $this->cli->getCommandLineValues();
|
620 |
+
$showProgress = $cliValues['showProgress'];
|
621 |
+
$useColors = $cliValues['colors'];
|
622 |
+
|
623 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0) {
|
624 |
+
echo 'Creating file list... ';
|
625 |
+
}
|
626 |
+
|
627 |
+
if (empty($this->allowedFileExtensions) === true) {
|
628 |
+
$this->allowedFileExtensions = $this->defaultFileExtensions;
|
629 |
+
}
|
630 |
+
|
631 |
+
$todo = $this->getFilesToProcess($files, $local);
|
632 |
+
$numFiles = count($todo);
|
633 |
+
|
634 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0) {
|
635 |
+
echo "DONE ($numFiles files in queue)".PHP_EOL;
|
636 |
+
}
|
637 |
+
|
638 |
+
$numProcessed = 0;
|
639 |
+
$dots = 0;
|
640 |
+
$maxLength = strlen($numFiles);
|
641 |
+
$lastDir = '';
|
642 |
+
foreach ($todo as $file) {
|
643 |
+
$this->file = $file;
|
644 |
+
$currDir = dirname($file);
|
645 |
+
if ($lastDir !== $currDir) {
|
646 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0 || PHP_CODESNIFFER_CBF === true) {
|
647 |
+
echo 'Changing into directory '.$currDir.PHP_EOL;
|
648 |
+
}
|
649 |
+
|
650 |
+
$lastDir = $currDir;
|
651 |
+
}
|
652 |
+
|
653 |
+
$phpcsFile = $this->processFile($file, null);
|
654 |
+
$numProcessed++;
|
655 |
+
|
656 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0
|
657 |
+
|| PHP_CODESNIFFER_INTERACTIVE === true
|
658 |
+
|| $showProgress === false
|
659 |
+
) {
|
660 |
+
continue;
|
661 |
+
}
|
662 |
+
|
663 |
+
// Show progress information.
|
664 |
+
if ($phpcsFile === null) {
|
665 |
+
echo 'S';
|
666 |
+
} else {
|
667 |
+
$errors = $phpcsFile->getErrorCount();
|
668 |
+
$warnings = $phpcsFile->getWarningCount();
|
669 |
+
if ($errors > 0) {
|
670 |
+
if ($useColors === true) {
|
671 |
+
echo "\033[31m";
|
672 |
+
}
|
673 |
+
|
674 |
+
echo 'E';
|
675 |
+
} else if ($warnings > 0) {
|
676 |
+
if ($useColors === true) {
|
677 |
+
echo "\033[33m";
|
678 |
+
}
|
679 |
+
|
680 |
+
echo 'W';
|
681 |
+
} else {
|
682 |
+
echo '.';
|
683 |
+
}
|
684 |
+
|
685 |
+
if ($useColors === true) {
|
686 |
+
echo "\033[0m";
|
687 |
+
}
|
688 |
+
}//end if
|
689 |
+
|
690 |
+
$dots++;
|
691 |
+
if ($dots === 60) {
|
692 |
+
$padding = ($maxLength - strlen($numProcessed));
|
693 |
+
echo str_repeat(' ', $padding);
|
694 |
+
$percent = round(($numProcessed / $numFiles) * 100);
|
695 |
+
echo " $numProcessed / $numFiles ($percent%)".PHP_EOL;
|
696 |
+
$dots = 0;
|
697 |
+
}
|
698 |
+
}//end foreach
|
699 |
+
|
700 |
+
if (PHP_CODESNIFFER_VERBOSITY === 0
|
701 |
+
&& PHP_CODESNIFFER_INTERACTIVE === false
|
702 |
+
&& $showProgress === true
|
703 |
+
) {
|
704 |
+
echo PHP_EOL.PHP_EOL;
|
705 |
+
}
|
706 |
+
|
707 |
+
}//end processFiles()
|
708 |
+
|
709 |
+
|
710 |
+
/**
|
711 |
+
* Processes a single ruleset and returns a list of the sniffs it represents.
|
712 |
+
*
|
713 |
+
* Rules founds within the ruleset are processed immediately, but sniff classes
|
714 |
+
* are not registered by this method.
|
715 |
+
*
|
716 |
+
* @param string $rulesetPath The path to a ruleset XML file.
|
717 |
+
* @param int $depth How many nested processing steps we are in. This
|
718 |
+
* is only used for debug output.
|
719 |
+
*
|
720 |
+
* @return array
|
721 |
+
* @throws PHP_CodeSniffer_Exception If the ruleset path is invalid.
|
722 |
+
*/
|
723 |
+
public function processRuleset($rulesetPath, $depth=0)
|
724 |
+
{
|
725 |
+
$rulesetPath = self::realpath($rulesetPath);
|
726 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
727 |
+
echo str_repeat("\t", $depth);
|
728 |
+
echo "Processing ruleset $rulesetPath".PHP_EOL;
|
729 |
+
}
|
730 |
+
|
731 |
+
$ruleset = simplexml_load_string(file_get_contents($rulesetPath));
|
732 |
+
if ($ruleset === false) {
|
733 |
+
throw new PHP_CodeSniffer_Exception("Ruleset $rulesetPath is not valid");
|
734 |
+
}
|
735 |
+
|
736 |
+
$ownSniffs = array();
|
737 |
+
$includedSniffs = array();
|
738 |
+
$excludedSniffs = array();
|
739 |
+
$cliValues = $this->cli->getCommandLineValues();
|
740 |
+
|
741 |
+
$rulesetDir = dirname($rulesetPath);
|
742 |
+
self::$rulesetDirs[] = $rulesetDir;
|
743 |
+
|
744 |
+
if (is_dir($rulesetDir.DIRECTORY_SEPARATOR.'Sniffs') === true) {
|
745 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
746 |
+
echo str_repeat("\t", $depth);
|
747 |
+
echo "\tAdding sniff files from \"/.../".basename($rulesetDir)."/Sniffs/\" directory".PHP_EOL;
|
748 |
+
}
|
749 |
+
|
750 |
+
$ownSniffs = $this->_expandSniffDirectory($rulesetDir.DIRECTORY_SEPARATOR.'Sniffs', $depth);
|
751 |
+
}
|
752 |
+
|
753 |
+
// Process custom sniff config settings.
|
754 |
+
foreach ($ruleset->{'config'} as $config) {
|
755 |
+
if ($this->_shouldProcessElement($config) === false) {
|
756 |
+
continue;
|
757 |
+
}
|
758 |
+
|
759 |
+
$this->setConfigData((string) $config['name'], (string) $config['value'], true);
|
760 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
761 |
+
echo str_repeat("\t", $depth);
|
762 |
+
echo "\t=> set config value ".(string) $config['name'].': '.(string) $config['value'].PHP_EOL;
|
763 |
+
}
|
764 |
+
}
|
765 |
+
|
766 |
+
foreach ($ruleset->rule as $rule) {
|
767 |
+
if (isset($rule['ref']) === false
|
768 |
+
|| $this->_shouldProcessElement($rule) === false
|
769 |
+
) {
|
770 |
+
continue;
|
771 |
+
}
|
772 |
+
|
773 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
774 |
+
echo str_repeat("\t", $depth);
|
775 |
+
echo "\tProcessing rule \"".$rule['ref'].'"'.PHP_EOL;
|
776 |
+
}
|
777 |
+
|
778 |
+
$includedSniffs = array_merge(
|
779 |
+
$includedSniffs,
|
780 |
+
$this->_expandRulesetReference($rule['ref'], $rulesetDir, $depth)
|
781 |
+
);
|
782 |
+
|
783 |
+
if (isset($rule->exclude) === true) {
|
784 |
+
foreach ($rule->exclude as $exclude) {
|
785 |
+
if ($this->_shouldProcessElement($exclude) === false) {
|
786 |
+
continue;
|
787 |
+
}
|
788 |
+
|
789 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
790 |
+
echo str_repeat("\t", $depth);
|
791 |
+
echo "\t\tExcluding rule \"".$exclude['name'].'"'.PHP_EOL;
|
792 |
+
}
|
793 |
+
|
794 |
+
// Check if a single code is being excluded, which is a shortcut
|
795 |
+
// for setting the severity of the message to 0.
|
796 |
+
$parts = explode('.', $exclude['name']);
|
797 |
+
if (count($parts) === 4) {
|
798 |
+
$this->ruleset[(string) $exclude['name']]['severity'] = 0;
|
799 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
800 |
+
echo str_repeat("\t", $depth);
|
801 |
+
echo "\t\t=> severity set to 0".PHP_EOL;
|
802 |
+
}
|
803 |
+
} else {
|
804 |
+
$excludedSniffs = array_merge(
|
805 |
+
$excludedSniffs,
|
806 |
+
$this->_expandRulesetReference($exclude['name'], $rulesetDir, ($depth + 1))
|
807 |
+
);
|
808 |
+
}
|
809 |
+
}//end foreach
|
810 |
+
}//end if
|
811 |
+
|
812 |
+
$this->_processRule($rule, $depth);
|
813 |
+
}//end foreach
|
814 |
+
|
815 |
+
// Process custom command line arguments.
|
816 |
+
$cliArgs = array();
|
817 |
+
foreach ($ruleset->{'arg'} as $arg) {
|
818 |
+
if ($this->_shouldProcessElement($arg) === false) {
|
819 |
+
continue;
|
820 |
+
}
|
821 |
+
|
822 |
+
if (isset($arg['name']) === true) {
|
823 |
+
$argString = '--'.(string) $arg['name'];
|
824 |
+
if (isset($arg['value']) === true) {
|
825 |
+
$argString .= '='.(string) $arg['value'];
|
826 |
+
}
|
827 |
+
} else {
|
828 |
+
$argString = '-'.(string) $arg['value'];
|
829 |
+
}
|
830 |
+
|
831 |
+
$cliArgs[] = $argString;
|
832 |
+
|
833 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
834 |
+
echo str_repeat("\t", $depth);
|
835 |
+
echo "\t=> set command line value $argString".PHP_EOL;
|
836 |
+
}
|
837 |
+
}//end foreach
|
838 |
+
|
839 |
+
// Set custom php ini values as CLI args.
|
840 |
+
foreach ($ruleset->{'ini'} as $arg) {
|
841 |
+
if ($this->_shouldProcessElement($arg) === false) {
|
842 |
+
continue;
|
843 |
+
}
|
844 |
+
|
845 |
+
if (isset($arg['name']) === false) {
|
846 |
+
continue;
|
847 |
+
}
|
848 |
+
|
849 |
+
$name = (string) $arg['name'];
|
850 |
+
$argString = $name;
|
851 |
+
if (isset($arg['value']) === true) {
|
852 |
+
$value = (string) $arg['value'];
|
853 |
+
$argString .= "=$value";
|
854 |
+
} else {
|
855 |
+
$value = 'true';
|
856 |
+
}
|
857 |
+
|
858 |
+
$cliArgs[] = '-d';
|
859 |
+
$cliArgs[] = $argString;
|
860 |
+
|
861 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
862 |
+
echo str_repeat("\t", $depth);
|
863 |
+
echo "\t=> set PHP ini value $name to $value".PHP_EOL;
|
864 |
+
}
|
865 |
+
}//end foreach
|
866 |
+
|
867 |
+
if (empty($cliValues['files']) === true && $cliValues['stdin'] === null) {
|
868 |
+
// Process hard-coded file paths.
|
869 |
+
foreach ($ruleset->{'file'} as $file) {
|
870 |
+
$file = (string) $file;
|
871 |
+
$cliArgs[] = $file;
|
872 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
873 |
+
echo str_repeat("\t", $depth);
|
874 |
+
echo "\t=> added \"$file\" to the file list".PHP_EOL;
|
875 |
+
}
|
876 |
+
}
|
877 |
+
}
|
878 |
+
|
879 |
+
if (empty($cliArgs) === false) {
|
880 |
+
// Change the directory so all relative paths are worked
|
881 |
+
// out based on the location of the ruleset instead of
|
882 |
+
// the location of the user.
|
883 |
+
$inPhar = self::isPharFile($rulesetDir);
|
884 |
+
if ($inPhar === false) {
|
885 |
+
$currentDir = getcwd();
|
886 |
+
chdir($rulesetDir);
|
887 |
+
}
|
888 |
+
|
889 |
+
$this->cli->setCommandLineValues($cliArgs);
|
890 |
+
|
891 |
+
if ($inPhar === false) {
|
892 |
+
chdir($currentDir);
|
893 |
+
}
|
894 |
+
}
|
895 |
+
|
896 |
+
// Process custom ignore pattern rules.
|
897 |
+
foreach ($ruleset->{'exclude-pattern'} as $pattern) {
|
898 |
+
if ($this->_shouldProcessElement($pattern) === false) {
|
899 |
+
continue;
|
900 |
+
}
|
901 |
+
|
902 |
+
if (isset($pattern['type']) === false) {
|
903 |
+
$pattern['type'] = 'absolute';
|
904 |
+
}
|
905 |
+
|
906 |
+
$this->ignorePatterns[(string) $pattern] = (string) $pattern['type'];
|
907 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
908 |
+
echo str_repeat("\t", $depth);
|
909 |
+
echo "\t=> added global ".(string) $pattern['type'].' ignore pattern: '.(string) $pattern.PHP_EOL;
|
910 |
+
}
|
911 |
+
}
|
912 |
+
|
913 |
+
$includedSniffs = array_unique(array_merge($ownSniffs, $includedSniffs));
|
914 |
+
$excludedSniffs = array_unique($excludedSniffs);
|
915 |
+
|
916 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
917 |
+
$included = count($includedSniffs);
|
918 |
+
$excluded = count($excludedSniffs);
|
919 |
+
echo str_repeat("\t", $depth);
|
920 |
+
echo "=> Ruleset processing complete; included $included sniffs and excluded $excluded".PHP_EOL;
|
921 |
+
}
|
922 |
+
|
923 |
+
// Merge our own sniff list with our externally included
|
924 |
+
// sniff list, but filter out any excluded sniffs.
|
925 |
+
$files = array();
|
926 |
+
foreach ($includedSniffs as $sniff) {
|
927 |
+
if (in_array($sniff, $excludedSniffs) === true) {
|
928 |
+
continue;
|
929 |
+
} else {
|
930 |
+
$files[] = self::realpath($sniff);
|
931 |
+
}
|
932 |
+
}
|
933 |
+
|
934 |
+
return $files;
|
935 |
+
|
936 |
+
}//end processRuleset()
|
937 |
+
|
938 |
+
|
939 |
+
/**
|
940 |
+
* Expands a directory into a list of sniff files within.
|
941 |
+
*
|
942 |
+
* @param string $directory The path to a directory.
|
943 |
+
* @param int $depth How many nested processing steps we are in. This
|
944 |
+
* is only used for debug output.
|
945 |
+
*
|
946 |
+
* @return array
|
947 |
+
*/
|
948 |
+
private function _expandSniffDirectory($directory, $depth=0)
|
949 |
+
{
|
950 |
+
$sniffs = array();
|
951 |
+
|
952 |
+
if (defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') === true) {
|
953 |
+
$rdi = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
|
954 |
+
} else {
|
955 |
+
$rdi = new RecursiveDirectoryIterator($directory);
|
956 |
+
}
|
957 |
+
|
958 |
+
$di = new RecursiveIteratorIterator($rdi, 0, RecursiveIteratorIterator::CATCH_GET_CHILD);
|
959 |
+
|
960 |
+
$dirLen = strlen($directory);
|
961 |
+
|
962 |
+
foreach ($di as $file) {
|
963 |
+
$filename = $file->getFilename();
|
964 |
+
|
965 |
+
// Skip hidden files.
|
966 |
+
if (substr($filename, 0, 1) === '.') {
|
967 |
+
continue;
|
968 |
+
}
|
969 |
+
|
970 |
+
// We are only interested in PHP and sniff files.
|
971 |
+
$fileParts = explode('.', $filename);
|
972 |
+
if (array_pop($fileParts) !== 'php') {
|
973 |
+
continue;
|
974 |
+
}
|
975 |
+
|
976 |
+
$basename = basename($filename, '.php');
|
977 |
+
if (substr($basename, -5) !== 'Sniff') {
|
978 |
+
continue;
|
979 |
+
}
|
980 |
+
|
981 |
+
$path = $file->getPathname();
|
982 |
+
|
983 |
+
// Skip files in hidden directories within the Sniffs directory of this
|
984 |
+
// standard. We use the offset with strpos() to allow hidden directories
|
985 |
+
// before, valid example:
|
986 |
+
// /home/foo/.composer/vendor/drupal/coder/coder_sniffer/Drupal/Sniffs/...
|
987 |
+
if (strpos($path, DIRECTORY_SEPARATOR.'.', $dirLen) !== false) {
|
988 |
+
continue;
|
989 |
+
}
|
990 |
+
|
991 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
992 |
+
echo str_repeat("\t", $depth);
|
993 |
+
echo "\t\t=> $path".PHP_EOL;
|
994 |
+
}
|
995 |
+
|
996 |
+
$sniffs[] = $path;
|
997 |
+
}//end foreach
|
998 |
+
|
999 |
+
return $sniffs;
|
1000 |
+
|
1001 |
+
}//end _expandSniffDirectory()
|
1002 |
+
|
1003 |
+
|
1004 |
+
/**
|
1005 |
+
* Expands a ruleset reference into a list of sniff files.
|
1006 |
+
*
|
1007 |
+
* @param string $ref The reference from the ruleset XML file.
|
1008 |
+
* @param string $rulesetDir The directory of the ruleset XML file, used to
|
1009 |
+
* evaluate relative paths.
|
1010 |
+
* @param int $depth How many nested processing steps we are in. This
|
1011 |
+
* is only used for debug output.
|
1012 |
+
*
|
1013 |
+
* @return array
|
1014 |
+
* @throws PHP_CodeSniffer_Exception If the reference is invalid.
|
1015 |
+
*/
|
1016 |
+
private function _expandRulesetReference($ref, $rulesetDir, $depth=0)
|
1017 |
+
{
|
1018 |
+
// Ignore internal sniffs codes as they are used to only
|
1019 |
+
// hide and change internal messages.
|
1020 |
+
if (substr($ref, 0, 9) === 'Internal.') {
|
1021 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1022 |
+
echo str_repeat("\t", $depth);
|
1023 |
+
echo "\t\t* ignoring internal sniff code *".PHP_EOL;
|
1024 |
+
}
|
1025 |
+
|
1026 |
+
return array();
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
// As sniffs can't begin with a full stop, assume references in
|
1030 |
+
// this format are relative paths and attempt to convert them
|
1031 |
+
// to absolute paths. If this fails, let the reference run through
|
1032 |
+
// the normal checks and have it fail as normal.
|
1033 |
+
if (substr($ref, 0, 1) === '.') {
|
1034 |
+
$realpath = self::realpath($rulesetDir.'/'.$ref);
|
1035 |
+
if ($realpath !== false) {
|
1036 |
+
$ref = $realpath;
|
1037 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1038 |
+
echo str_repeat("\t", $depth);
|
1039 |
+
echo "\t\t=> $ref".PHP_EOL;
|
1040 |
+
}
|
1041 |
+
}
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
// As sniffs can't begin with a tilde, assume references in
|
1045 |
+
// this format at relative to the user's home directory.
|
1046 |
+
if (substr($ref, 0, 2) === '~/') {
|
1047 |
+
$realpath = self::realpath($ref);
|
1048 |
+
if ($realpath !== false) {
|
1049 |
+
$ref = $realpath;
|
1050 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1051 |
+
echo str_repeat("\t", $depth);
|
1052 |
+
echo "\t\t=> $ref".PHP_EOL;
|
1053 |
+
}
|
1054 |
+
}
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
if (is_file($ref) === true) {
|
1058 |
+
if (substr($ref, -9) === 'Sniff.php') {
|
1059 |
+
// A single external sniff.
|
1060 |
+
self::$rulesetDirs[] = dirname(dirname(dirname($ref)));
|
1061 |
+
return array($ref);
|
1062 |
+
}
|
1063 |
+
} else {
|
1064 |
+
// See if this is a whole standard being referenced.
|
1065 |
+
$path = $this->getInstalledStandardPath($ref);
|
1066 |
+
if (self::isPharFile($path) === true && strpos($path, 'ruleset.xml') === false) {
|
1067 |
+
// If the ruleset exists inside the phar file, use it.
|
1068 |
+
if (file_exists($path.DIRECTORY_SEPARATOR.'ruleset.xml') === true) {
|
1069 |
+
$path = $path.DIRECTORY_SEPARATOR.'ruleset.xml';
|
1070 |
+
} else {
|
1071 |
+
$path = null;
|
1072 |
+
}
|
1073 |
+
}
|
1074 |
+
|
1075 |
+
if ($path !== null) {
|
1076 |
+
$ref = $path;
|
1077 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1078 |
+
echo str_repeat("\t", $depth);
|
1079 |
+
echo "\t\t=> $ref".PHP_EOL;
|
1080 |
+
}
|
1081 |
+
} else if (is_dir($ref) === false) {
|
1082 |
+
// Work out the sniff path.
|
1083 |
+
$sepPos = strpos($ref, DIRECTORY_SEPARATOR);
|
1084 |
+
if ($sepPos !== false) {
|
1085 |
+
$stdName = substr($ref, 0, $sepPos);
|
1086 |
+
$path = substr($ref, $sepPos);
|
1087 |
+
} else {
|
1088 |
+
$parts = explode('.', $ref);
|
1089 |
+
$stdName = $parts[0];
|
1090 |
+
if (count($parts) === 1) {
|
1091 |
+
// A whole standard?
|
1092 |
+
$path = '';
|
1093 |
+
} else if (count($parts) === 2) {
|
1094 |
+
// A directory of sniffs?
|
1095 |
+
$path = DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR.$parts[1];
|
1096 |
+
} else {
|
1097 |
+
// A single sniff?
|
1098 |
+
$path = DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR.$parts[1].DIRECTORY_SEPARATOR.$parts[2].'Sniff.php';
|
1099 |
+
}
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
$newRef = false;
|
1103 |
+
$stdPath = $this->getInstalledStandardPath($stdName);
|
1104 |
+
if ($stdPath !== null && $path !== '') {
|
1105 |
+
if (self::isPharFile($stdPath) === true
|
1106 |
+
&& strpos($stdPath, 'ruleset.xml') === false
|
1107 |
+
) {
|
1108 |
+
// Phar files can only return the directory,
|
1109 |
+
// since ruleset can be omitted if building one standard.
|
1110 |
+
$newRef = self::realpath($stdPath.$path);
|
1111 |
+
} else {
|
1112 |
+
$newRef = self::realpath(dirname($stdPath).$path);
|
1113 |
+
}
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
if ($newRef === false) {
|
1117 |
+
// The sniff is not locally installed, so check if it is being
|
1118 |
+
// referenced as a remote sniff outside the install. We do this
|
1119 |
+
// by looking through all directories where we have found ruleset
|
1120 |
+
// files before, looking for ones for this particular standard,
|
1121 |
+
// and seeing if it is in there.
|
1122 |
+
foreach (self::$rulesetDirs as $dir) {
|
1123 |
+
if (strtolower(basename($dir)) !== strtolower($stdName)) {
|
1124 |
+
continue;
|
1125 |
+
}
|
1126 |
+
|
1127 |
+
$newRef = self::realpath($dir.$path);
|
1128 |
+
|
1129 |
+
if ($newRef !== false) {
|
1130 |
+
$ref = $newRef;
|
1131 |
+
}
|
1132 |
+
}
|
1133 |
+
} else {
|
1134 |
+
$ref = $newRef;
|
1135 |
+
}
|
1136 |
+
|
1137 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1138 |
+
echo str_repeat("\t", $depth);
|
1139 |
+
echo "\t\t=> $ref".PHP_EOL;
|
1140 |
+
}
|
1141 |
+
}//end if
|
1142 |
+
}//end if
|
1143 |
+
|
1144 |
+
if (is_dir($ref) === true) {
|
1145 |
+
if (is_file($ref.DIRECTORY_SEPARATOR.'ruleset.xml') === true) {
|
1146 |
+
// We are referencing an external coding standard.
|
1147 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1148 |
+
echo str_repeat("\t", $depth);
|
1149 |
+
echo "\t\t* rule is referencing a standard using directory name; processing *".PHP_EOL;
|
1150 |
+
}
|
1151 |
+
|
1152 |
+
return $this->processRuleset($ref.DIRECTORY_SEPARATOR.'ruleset.xml', ($depth + 2));
|
1153 |
+
} else {
|
1154 |
+
// We are referencing a whole directory of sniffs.
|
1155 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1156 |
+
echo str_repeat("\t", $depth);
|
1157 |
+
echo "\t\t* rule is referencing a directory of sniffs *".PHP_EOL;
|
1158 |
+
echo str_repeat("\t", $depth);
|
1159 |
+
echo "\t\tAdding sniff files from directory".PHP_EOL;
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
return $this->_expandSniffDirectory($ref, ($depth + 1));
|
1163 |
+
}
|
1164 |
+
} else {
|
1165 |
+
if (is_file($ref) === false) {
|
1166 |
+
$error = "Referenced sniff \"$ref\" does not exist";
|
1167 |
+
throw new PHP_CodeSniffer_Exception($error);
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
if (substr($ref, -9) === 'Sniff.php') {
|
1171 |
+
// A single sniff.
|
1172 |
+
return array($ref);
|
1173 |
+
} else {
|
1174 |
+
// Assume an external ruleset.xml file.
|
1175 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1176 |
+
echo str_repeat("\t", $depth);
|
1177 |
+
echo "\t\t* rule is referencing a standard using ruleset path; processing *".PHP_EOL;
|
1178 |
+
}
|
1179 |
+
|
1180 |
+
return $this->processRuleset($ref, ($depth + 2));
|
1181 |
+
}
|
1182 |
+
}//end if
|
1183 |
+
|
1184 |
+
}//end _expandRulesetReference()
|
1185 |
+
|
1186 |
+
|
1187 |
+
/**
|
1188 |
+
* Processes a rule from a ruleset XML file, overriding built-in defaults.
|
1189 |
+
*
|
1190 |
+
* @param SimpleXMLElement $rule The rule object from a ruleset XML file.
|
1191 |
+
* @param int $depth How many nested processing steps we are in.
|
1192 |
+
* This is only used for debug output.
|
1193 |
+
*
|
1194 |
+
* @return void
|
1195 |
+
*/
|
1196 |
+
private function _processRule($rule, $depth=0)
|
1197 |
+
{
|
1198 |
+
$code = (string) $rule['ref'];
|
1199 |
+
|
1200 |
+
// Custom severity.
|
1201 |
+
if (isset($rule->severity) === true
|
1202 |
+
&& $this->_shouldProcessElement($rule->severity) === true
|
1203 |
+
) {
|
1204 |
+
if (isset($this->ruleset[$code]) === false) {
|
1205 |
+
$this->ruleset[$code] = array();
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
$this->ruleset[$code]['severity'] = (int) $rule->severity;
|
1209 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1210 |
+
echo str_repeat("\t", $depth);
|
1211 |
+
echo "\t\t=> severity set to ".(int) $rule->severity.PHP_EOL;
|
1212 |
+
}
|
1213 |
+
}
|
1214 |
+
|
1215 |
+
// Custom message type.
|
1216 |
+
if (isset($rule->type) === true
|
1217 |
+
&& $this->_shouldProcessElement($rule->type) === true
|
1218 |
+
) {
|
1219 |
+
if (isset($this->ruleset[$code]) === false) {
|
1220 |
+
$this->ruleset[$code] = array();
|
1221 |
+
}
|
1222 |
+
|
1223 |
+
$this->ruleset[$code]['type'] = (string) $rule->type;
|
1224 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1225 |
+
echo str_repeat("\t", $depth);
|
1226 |
+
echo "\t\t=> message type set to ".(string) $rule->type.PHP_EOL;
|
1227 |
+
}
|
1228 |
+
}
|
1229 |
+
|
1230 |
+
// Custom message.
|
1231 |
+
if (isset($rule->message) === true
|
1232 |
+
&& $this->_shouldProcessElement($rule->message) === true
|
1233 |
+
) {
|
1234 |
+
if (isset($this->ruleset[$code]) === false) {
|
1235 |
+
$this->ruleset[$code] = array();
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
$this->ruleset[$code]['message'] = (string) $rule->message;
|
1239 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1240 |
+
echo str_repeat("\t", $depth);
|
1241 |
+
echo "\t\t=> message set to ".(string) $rule->message.PHP_EOL;
|
1242 |
+
}
|
1243 |
+
}
|
1244 |
+
|
1245 |
+
// Custom properties.
|
1246 |
+
if (isset($rule->properties) === true
|
1247 |
+
&& $this->_shouldProcessElement($rule->properties) === true
|
1248 |
+
) {
|
1249 |
+
foreach ($rule->properties->property as $prop) {
|
1250 |
+
if ($this->_shouldProcessElement($prop) === false) {
|
1251 |
+
continue;
|
1252 |
+
}
|
1253 |
+
|
1254 |
+
if (isset($this->ruleset[$code]) === false) {
|
1255 |
+
$this->ruleset[$code] = array(
|
1256 |
+
'properties' => array(),
|
1257 |
+
);
|
1258 |
+
} else if (isset($this->ruleset[$code]['properties']) === false) {
|
1259 |
+
$this->ruleset[$code]['properties'] = array();
|
1260 |
+
}
|
1261 |
+
|
1262 |
+
$name = (string) $prop['name'];
|
1263 |
+
if (isset($prop['type']) === true
|
1264 |
+
&& (string) $prop['type'] === 'array'
|
1265 |
+
) {
|
1266 |
+
$value = (string) $prop['value'];
|
1267 |
+
$values = array();
|
1268 |
+
foreach (explode(',', $value) as $val) {
|
1269 |
+
$v = '';
|
1270 |
+
|
1271 |
+
list($k,$v) = explode('=>', $val.'=>');
|
1272 |
+
if ($v !== '') {
|
1273 |
+
$values[$k] = $v;
|
1274 |
+
} else {
|
1275 |
+
$values[] = $k;
|
1276 |
+
}
|
1277 |
+
}
|
1278 |
+
|
1279 |
+
$this->ruleset[$code]['properties'][$name] = $values;
|
1280 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1281 |
+
echo str_repeat("\t", $depth);
|
1282 |
+
echo "\t\t=> array property \"$name\" set to \"$value\"".PHP_EOL;
|
1283 |
+
}
|
1284 |
+
} else {
|
1285 |
+
$this->ruleset[$code]['properties'][$name] = (string) $prop['value'];
|
1286 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1287 |
+
echo str_repeat("\t", $depth);
|
1288 |
+
echo "\t\t=> property \"$name\" set to \"".(string) $prop['value'].'"'.PHP_EOL;
|
1289 |
+
}
|
1290 |
+
}//end if
|
1291 |
+
}//end foreach
|
1292 |
+
}//end if
|
1293 |
+
|
1294 |
+
// Ignore patterns.
|
1295 |
+
foreach ($rule->{'exclude-pattern'} as $pattern) {
|
1296 |
+
if ($this->_shouldProcessElement($pattern) === false) {
|
1297 |
+
continue;
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
if (isset($this->ignorePatterns[$code]) === false) {
|
1301 |
+
$this->ignorePatterns[$code] = array();
|
1302 |
+
}
|
1303 |
+
|
1304 |
+
if (isset($pattern['type']) === false) {
|
1305 |
+
$pattern['type'] = 'absolute';
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
$this->ignorePatterns[$code][(string) $pattern] = (string) $pattern['type'];
|
1309 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1310 |
+
echo str_repeat("\t", $depth);
|
1311 |
+
echo "\t\t=> added sniff-specific ".(string) $pattern['type'].' ignore pattern: '.(string) $pattern.PHP_EOL;
|
1312 |
+
}
|
1313 |
+
}
|
1314 |
+
|
1315 |
+
}//end _processRule()
|
1316 |
+
|
1317 |
+
|
1318 |
+
/**
|
1319 |
+
* Determine if an element should be processed or ignored.
|
1320 |
+
*
|
1321 |
+
* @param SimpleXMLElement $element An object from a ruleset XML file.
|
1322 |
+
* @param int $depth How many nested processing steps we are in.
|
1323 |
+
* This is only used for debug output.
|
1324 |
+
*
|
1325 |
+
* @return bool
|
1326 |
+
*/
|
1327 |
+
private function _shouldProcessElement($element, $depth=0)
|
1328 |
+
{
|
1329 |
+
if (isset($element['phpcbf-only']) === false
|
1330 |
+
&& isset($element['phpcs-only']) === false
|
1331 |
+
) {
|
1332 |
+
// No exceptions are being made.
|
1333 |
+
return true;
|
1334 |
+
}
|
1335 |
+
|
1336 |
+
if (PHP_CODESNIFFER_CBF === true
|
1337 |
+
&& isset($element['phpcbf-only']) === true
|
1338 |
+
&& (string) $element['phpcbf-only'] === 'true'
|
1339 |
+
) {
|
1340 |
+
return true;
|
1341 |
+
}
|
1342 |
+
|
1343 |
+
if (PHP_CODESNIFFER_CBF === false
|
1344 |
+
&& isset($element['phpcs-only']) === true
|
1345 |
+
&& (string) $element['phpcs-only'] === 'true'
|
1346 |
+
) {
|
1347 |
+
return true;
|
1348 |
+
}
|
1349 |
+
|
1350 |
+
return false;
|
1351 |
+
|
1352 |
+
}//end _shouldProcessElement()
|
1353 |
+
|
1354 |
+
|
1355 |
+
/**
|
1356 |
+
* Loads and stores sniffs objects used for sniffing files.
|
1357 |
+
*
|
1358 |
+
* @param array $files Paths to the sniff files to register.
|
1359 |
+
* @param array $restrictions The sniff class names to restrict the allowed
|
1360 |
+
* listeners to.
|
1361 |
+
* @param array $exclusions The sniff class names to exclude from the
|
1362 |
+
* listeners list.
|
1363 |
+
*
|
1364 |
+
* @return void
|
1365 |
+
* @throws PHP_CodeSniffer_Exception If a sniff file path is invalid.
|
1366 |
+
*/
|
1367 |
+
public function registerSniffs($files, $restrictions, $exclusions)
|
1368 |
+
{
|
1369 |
+
$listeners = array();
|
1370 |
+
|
1371 |
+
foreach ($files as $file) {
|
1372 |
+
// Work out where the position of /StandardName/Sniffs/... is
|
1373 |
+
// so we can determine what the class will be called.
|
1374 |
+
$sniffPos = strrpos($file, DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR);
|
1375 |
+
if ($sniffPos === false) {
|
1376 |
+
continue;
|
1377 |
+
}
|
1378 |
+
|
1379 |
+
$slashPos = strrpos(substr($file, 0, $sniffPos), DIRECTORY_SEPARATOR);
|
1380 |
+
if ($slashPos === false) {
|
1381 |
+
continue;
|
1382 |
+
}
|
1383 |
+
|
1384 |
+
$className = substr($file, ($slashPos + 1));
|
1385 |
+
|
1386 |
+
if (substr_count($className, DIRECTORY_SEPARATOR) !== 3) {
|
1387 |
+
throw new PHP_CodeSniffer_Exception("Sniff file $className is not valid; sniff files must be located in a .../StandardName/Sniffs/CategoryName/ directory");
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
$className = substr($className, 0, -4);
|
1391 |
+
$className = str_replace(DIRECTORY_SEPARATOR, '_', $className);
|
1392 |
+
|
1393 |
+
// If they have specified a list of sniffs to restrict to, check
|
1394 |
+
// to see if this sniff is allowed.
|
1395 |
+
if (empty($restrictions) === false
|
1396 |
+
&& in_array(strtolower($className), $restrictions) === false
|
1397 |
+
) {
|
1398 |
+
continue;
|
1399 |
+
}
|
1400 |
+
|
1401 |
+
// If they have specified a list of sniffs to exclude, check
|
1402 |
+
// to see if this sniff is allowed.
|
1403 |
+
if (empty($exclusions) === false
|
1404 |
+
&& in_array(strtolower($className), $exclusions) === true
|
1405 |
+
) {
|
1406 |
+
continue;
|
1407 |
+
}
|
1408 |
+
|
1409 |
+
include_once $file;
|
1410 |
+
|
1411 |
+
// Support the use of PHP namespaces. If the class name we included
|
1412 |
+
// contains namespace separators instead of underscores, use this as the
|
1413 |
+
// class name from now on.
|
1414 |
+
$classNameNS = str_replace('_', '\\', $className);
|
1415 |
+
if (class_exists($classNameNS, false) === true) {
|
1416 |
+
$className = $classNameNS;
|
1417 |
+
}
|
1418 |
+
|
1419 |
+
// Skip abstract classes.
|
1420 |
+
$reflection = new ReflectionClass($className);
|
1421 |
+
if ($reflection->isAbstract() === true) {
|
1422 |
+
continue;
|
1423 |
+
}
|
1424 |
+
|
1425 |
+
$listeners[$className] = $className;
|
1426 |
+
|
1427 |
+
if (PHP_CODESNIFFER_VERBOSITY > 2) {
|
1428 |
+
echo "Registered $className".PHP_EOL;
|
1429 |
+
}
|
1430 |
+
}//end foreach
|
1431 |
+
|
1432 |
+
$this->sniffs = $listeners;
|
1433 |
+
|
1434 |
+
}//end registerSniffs()
|
1435 |
+
|
1436 |
+
|
1437 |
+
/**
|
1438 |
+
* Populates the array of PHP_CodeSniffer_Sniff's for this file.
|
1439 |
+
*
|
1440 |
+
* @return void
|
1441 |
+
* @throws PHP_CodeSniffer_Exception If sniff registration fails.
|
1442 |
+
*/
|
1443 |
+
public function populateTokenListeners()
|
1444 |
+
{
|
1445 |
+
// Construct a list of listeners indexed by token being listened for.
|
1446 |
+
$this->_tokenListeners = array();
|
1447 |
+
|
1448 |
+
foreach ($this->sniffs as $listenerClass) {
|
1449 |
+
// Work out the internal code for this sniff. Detect usage of namespace
|
1450 |
+
// separators instead of underscores to support PHP namespaces.
|
1451 |
+
if (strstr($listenerClass, '\\') === false) {
|
1452 |
+
$parts = explode('_', $listenerClass);
|
1453 |
+
} else {
|
1454 |
+
$parts = explode('\\', $listenerClass);
|
1455 |
+
}
|
1456 |
+
|
1457 |
+
$code = $parts[0].'.'.$parts[2].'.'.$parts[3];
|
1458 |
+
$code = substr($code, 0, -5);
|
1459 |
+
|
1460 |
+
$this->listeners[$listenerClass] = new $listenerClass();
|
1461 |
+
$this->sniffCodes[$code] = $listenerClass;
|
1462 |
+
|
1463 |
+
// Set custom properties.
|
1464 |
+
if (isset($this->ruleset[$code]['properties']) === true) {
|
1465 |
+
foreach ($this->ruleset[$code]['properties'] as $name => $value) {
|
1466 |
+
$this->setSniffProperty($listenerClass, $name, $value);
|
1467 |
+
}
|
1468 |
+
}
|
1469 |
+
|
1470 |
+
$tokenizers = array();
|
1471 |
+
$vars = get_class_vars($listenerClass);
|
1472 |
+
if (isset($vars['supportedTokenizers']) === true) {
|
1473 |
+
foreach ($vars['supportedTokenizers'] as $tokenizer) {
|
1474 |
+
$tokenizers[$tokenizer] = $tokenizer;
|
1475 |
+
}
|
1476 |
+
} else {
|
1477 |
+
$tokenizers = array('PHP' => 'PHP');
|
1478 |
+
}
|
1479 |
+
|
1480 |
+
$tokens = $this->listeners[$listenerClass]->register();
|
1481 |
+
if (is_array($tokens) === false) {
|
1482 |
+
$msg = "Sniff $listenerClass register() method must return an array";
|
1483 |
+
throw new PHP_CodeSniffer_Exception($msg);
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
$parts = explode('_', str_replace('\\', '_', $listenerClass));
|
1487 |
+
$listenerSource = $parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5);
|
1488 |
+
$ignorePatterns = array();
|
1489 |
+
$patterns = $this->getIgnorePatterns($listenerSource);
|
1490 |
+
foreach ($patterns as $pattern => $type) {
|
1491 |
+
// While there is support for a type of each pattern
|
1492 |
+
// (absolute or relative) we don't actually support it here.
|
1493 |
+
$replacements = array(
|
1494 |
+
'\\,' => ',',
|
1495 |
+
'*' => '.*',
|
1496 |
+
);
|
1497 |
+
|
1498 |
+
$ignorePatterns[] = strtr($pattern, $replacements);
|
1499 |
+
}
|
1500 |
+
|
1501 |
+
foreach ($tokens as $token) {
|
1502 |
+
if (isset($this->_tokenListeners[$token]) === false) {
|
1503 |
+
$this->_tokenListeners[$token] = array();
|
1504 |
+
}
|
1505 |
+
|
1506 |
+
if (isset($this->_tokenListeners[$token][$listenerClass]) === false) {
|
1507 |
+
$this->_tokenListeners[$token][$listenerClass] = array(
|
1508 |
+
'class' => $listenerClass,
|
1509 |
+
'source' => $listenerSource,
|
1510 |
+
'tokenizers' => $tokenizers,
|
1511 |
+
'ignore' => $ignorePatterns,
|
1512 |
+
);
|
1513 |
+
}
|
1514 |
+
}
|
1515 |
+
}//end foreach
|
1516 |
+
|
1517 |
+
}//end populateTokenListeners()
|
1518 |
+
|
1519 |
+
|
1520 |
+
/**
|
1521 |
+
* Set a single property for a sniff.
|
1522 |
+
*
|
1523 |
+
* @param string $listenerClass The class name of the sniff.
|
1524 |
+
* @param string $name The name of the property to change.
|
1525 |
+
* @param string $value The new value of the property.
|
1526 |
+
*
|
1527 |
+
* @return void
|
1528 |
+
*/
|
1529 |
+
public function setSniffProperty($listenerClass, $name, $value)
|
1530 |
+
{
|
1531 |
+
// Setting a property for a sniff we are not using.
|
1532 |
+
if (isset($this->listeners[$listenerClass]) === false) {
|
1533 |
+
return;
|
1534 |
+
}
|
1535 |
+
|
1536 |
+
$name = trim($name);
|
1537 |
+
if (is_string($value) === true) {
|
1538 |
+
$value = trim($value);
|
1539 |
+
}
|
1540 |
+
|
1541 |
+
// Special case for booleans.
|
1542 |
+
if ($value === 'true') {
|
1543 |
+
$value = true;
|
1544 |
+
} else if ($value === 'false') {
|
1545 |
+
$value = false;
|
1546 |
+
}
|
1547 |
+
|
1548 |
+
$this->listeners[$listenerClass]->$name = $value;
|
1549 |
+
|
1550 |
+
}//end setSniffProperty()
|
1551 |
+
|
1552 |
+
|
1553 |
+
/**
|
1554 |
+
* Get a list of files that will be processed.
|
1555 |
+
*
|
1556 |
+
* If passed directories, this method will find all files within them.
|
1557 |
+
* The method will also perform file extension and ignore pattern filtering.
|
1558 |
+
*
|
1559 |
+
* @param string $paths A list of file or directory paths to process.
|
1560 |
+
* @param boolean $local If true, only process 1 level of files in directories
|
1561 |
+
*
|
1562 |
+
* @return array
|
1563 |
+
* @throws Exception If there was an error opening a directory.
|
1564 |
+
* @see shouldProcessFile()
|
1565 |
+
*/
|
1566 |
+
public function getFilesToProcess($paths, $local=false)
|
1567 |
+
{
|
1568 |
+
$files = array();
|
1569 |
+
|
1570 |
+
foreach ($paths as $path) {
|
1571 |
+
if (is_dir($path) === true || self::isPharFile($path) === true) {
|
1572 |
+
if (self::isPharFile($path) === true) {
|
1573 |
+
$path = 'phar://'.$path;
|
1574 |
+
}
|
1575 |
+
|
1576 |
+
if ($local === true) {
|
1577 |
+
$di = new DirectoryIterator($path);
|
1578 |
+
} else {
|
1579 |
+
$di = new RecursiveIteratorIterator(
|
1580 |
+
new RecursiveDirectoryIterator($path),
|
1581 |
+
0,
|
1582 |
+
RecursiveIteratorIterator::CATCH_GET_CHILD
|
1583 |
+
);
|
1584 |
+
}
|
1585 |
+
|
1586 |
+
foreach ($di as $file) {
|
1587 |
+
// Check if the file exists after all symlinks are resolved.
|
1588 |
+
$filePath = self::realpath($file->getPathname());
|
1589 |
+
if ($filePath === false) {
|
1590 |
+
continue;
|
1591 |
+
}
|
1592 |
+
|
1593 |
+
if (is_dir($filePath) === true) {
|
1594 |
+
continue;
|
1595 |
+
}
|
1596 |
+
|
1597 |
+
if ($this->shouldProcessFile($file->getPathname(), $path) === false) {
|
1598 |
+
continue;
|
1599 |
+
}
|
1600 |
+
|
1601 |
+
$files[] = $file->getPathname();
|
1602 |
+
}//end foreach
|
1603 |
+
} else {
|
1604 |
+
if ($this->shouldIgnoreFile($path, dirname($path)) === true) {
|
1605 |
+
continue;
|
1606 |
+
}
|
1607 |
+
|
1608 |
+
$files[] = $path;
|
1609 |
+
}//end if
|
1610 |
+
}//end foreach
|
1611 |
+
|
1612 |
+
return $files;
|
1613 |
+
|
1614 |
+
}//end getFilesToProcess()
|
1615 |
+
|
1616 |
+
|
1617 |
+
/**
|
1618 |
+
* Checks filtering rules to see if a file should be checked.
|
1619 |
+
*
|
1620 |
+
* Checks both file extension filters and path ignore filters.
|
1621 |
+
*
|
1622 |
+
* @param string $path The path to the file being checked.
|
1623 |
+
* @param string $basedir The directory to use for relative path checks.
|
1624 |
+
*
|
1625 |
+
* @return bool
|
1626 |
+
*/
|
1627 |
+
public function shouldProcessFile($path, $basedir)
|
1628 |
+
{
|
1629 |
+
// Check that the file's extension is one we are checking.
|
1630 |
+
// We are strict about checking the extension and we don't
|
1631 |
+
// let files through with no extension or that start with a dot.
|
1632 |
+
$fileName = basename($path);
|
1633 |
+
$fileParts = explode('.', $fileName);
|
1634 |
+
if ($fileParts[0] === $fileName || $fileParts[0] === '') {
|
1635 |
+
return false;
|
1636 |
+
}
|
1637 |
+
|
1638 |
+
// Checking multi-part file extensions, so need to create a
|
1639 |
+
// complete extension list and make sure one is allowed.
|
1640 |
+
$extensions = array();
|
1641 |
+
array_shift($fileParts);
|
1642 |
+
foreach ($fileParts as $part) {
|
1643 |
+
$extensions[implode('.', $fileParts)] = 1;
|
1644 |
+
array_shift($fileParts);
|
1645 |
+
}
|
1646 |
+
|
1647 |
+
$matches = array_intersect_key($extensions, $this->allowedFileExtensions);
|
1648 |
+
if (empty($matches) === true) {
|
1649 |
+
return false;
|
1650 |
+
}
|
1651 |
+
|
1652 |
+
// If the file's path matches one of our ignore patterns, skip it.
|
1653 |
+
if ($this->shouldIgnoreFile($path, $basedir) === true) {
|
1654 |
+
return false;
|
1655 |
+
}
|
1656 |
+
|
1657 |
+
return true;
|
1658 |
+
|
1659 |
+
}//end shouldProcessFile()
|
1660 |
+
|
1661 |
+
|
1662 |
+
/**
|
1663 |
+
* Checks filtering rules to see if a file should be ignored.
|
1664 |
+
*
|
1665 |
+
* @param string $path The path to the file being checked.
|
1666 |
+
* @param string $basedir The directory to use for relative path checks.
|
1667 |
+
*
|
1668 |
+
* @return bool
|
1669 |
+
*/
|
1670 |
+
public function shouldIgnoreFile($path, $basedir)
|
1671 |
+
{
|
1672 |
+
$relativePath = $path;
|
1673 |
+
if (strpos($path, $basedir) === 0) {
|
1674 |
+
// The +1 cuts off the directory separator as well.
|
1675 |
+
$relativePath = substr($path, (strlen($basedir) + 1));
|
1676 |
+
}
|
1677 |
+
|
1678 |
+
foreach ($this->ignorePatterns as $pattern => $type) {
|
1679 |
+
if (is_array($type) === true) {
|
1680 |
+
// A sniff specific ignore pattern.
|
1681 |
+
continue;
|
1682 |
+
}
|
1683 |
+
|
1684 |
+
// Maintains backwards compatibility in case the ignore pattern does
|
1685 |
+
// not have a relative/absolute value.
|
1686 |
+
if (is_int($pattern) === true) {
|
1687 |
+
$pattern = $type;
|
1688 |
+
$type = 'absolute';
|
1689 |
+
}
|
1690 |
+
|
1691 |
+
$replacements = array(
|
1692 |
+
'\\,' => ',',
|
1693 |
+
'*' => '.*',
|
1694 |
+
);
|
1695 |
+
|
1696 |
+
// We assume a / directory separator, as do the exclude rules
|
1697 |
+
// most developers write, so we need a special case for any system
|
1698 |
+
// that is different.
|
1699 |
+
if (DIRECTORY_SEPARATOR === '\\') {
|
1700 |
+
$replacements['/'] = '\\\\';
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
$pattern = strtr($pattern, $replacements);
|
1704 |
+
|
1705 |
+
if ($type === 'relative') {
|
1706 |
+
$testPath = $relativePath;
|
1707 |
+
} else {
|
1708 |
+
$testPath = $path;
|
1709 |
+
}
|
1710 |
+
|
1711 |
+
$pattern = '`'.$pattern.'`i';
|
1712 |
+
if (preg_match($pattern, $testPath) === 1) {
|
1713 |
+
return true;
|
1714 |
+
}
|
1715 |
+
}//end foreach
|
1716 |
+
|
1717 |
+
return false;
|
1718 |
+
|
1719 |
+
}//end shouldIgnoreFile()
|
1720 |
+
|
1721 |
+
|
1722 |
+
/**
|
1723 |
+
* Run the code sniffs over a single given file.
|
1724 |
+
*
|
1725 |
+
* Processes the file and runs the PHP_CodeSniffer sniffs to verify that it
|
1726 |
+
* conforms with the standard. Returns the processed file object, or NULL
|
1727 |
+
* if no file was processed due to error.
|
1728 |
+
*
|
1729 |
+
* @param string $file The file to process.
|
1730 |
+
* @param string $contents The contents to parse. If NULL, the content
|
1731 |
+
* is taken from the file system.
|
1732 |
+
*
|
1733 |
+
* @return PHP_CodeSniffer_File
|
1734 |
+
* @throws PHP_CodeSniffer_Exception If the file could not be processed.
|
1735 |
+
* @see _processFile()
|
1736 |
+
*/
|
1737 |
+
public function processFile($file, $contents=null)
|
1738 |
+
{
|
1739 |
+
if ($contents === null && file_exists($file) === false) {
|
1740 |
+
throw new PHP_CodeSniffer_Exception("Source file $file does not exist");
|
1741 |
+
}
|
1742 |
+
|
1743 |
+
$filePath = self::realpath($file);
|
1744 |
+
if ($filePath === false) {
|
1745 |
+
$filePath = $file;
|
1746 |
+
}
|
1747 |
+
|
1748 |
+
// Before we go and spend time tokenizing this file, just check
|
1749 |
+
// to see if there is a tag up top to indicate that the whole
|
1750 |
+
// file should be ignored. It must be on one of the first two lines.
|
1751 |
+
$firstContent = $contents;
|
1752 |
+
if ($contents === null && is_readable($filePath) === true) {
|
1753 |
+
$handle = fopen($filePath, 'r');
|
1754 |
+
stream_set_blocking($handle, true);
|
1755 |
+
if ($handle !== false) {
|
1756 |
+
$firstContent = fgets($handle);
|
1757 |
+
$firstContent .= fgets($handle);
|
1758 |
+
fclose($handle);
|
1759 |
+
|
1760 |
+
if (strpos($firstContent, '@codingStandardsIgnoreFile') !== false) {
|
1761 |
+
// We are ignoring the whole file.
|
1762 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0) {
|
1763 |
+
echo 'Ignoring '.basename($filePath).PHP_EOL;
|
1764 |
+
}
|
1765 |
+
|
1766 |
+
return null;
|
1767 |
+
}
|
1768 |
+
}
|
1769 |
+
}//end if
|
1770 |
+
|
1771 |
+
try {
|
1772 |
+
$phpcsFile = $this->_processFile($file, $contents);
|
1773 |
+
} catch (Exception $e) {
|
1774 |
+
$trace = $e->getTrace();
|
1775 |
+
|
1776 |
+
$filename = $trace[0]['args'][0];
|
1777 |
+
if (is_object($filename) === true
|
1778 |
+
&& get_class($filename) === 'PHP_CodeSniffer_File'
|
1779 |
+
) {
|
1780 |
+
$filename = $filename->getFilename();
|
1781 |
+
} else if (is_numeric($filename) === true) {
|
1782 |
+
// See if we can find the PHP_CodeSniffer_File object.
|
1783 |
+
foreach ($trace as $data) {
|
1784 |
+
if (isset($data['args'][0]) === true
|
1785 |
+
&& ($data['args'][0] instanceof PHP_CodeSniffer_File) === true
|
1786 |
+
) {
|
1787 |
+
$filename = $data['args'][0]->getFilename();
|
1788 |
+
}
|
1789 |
+
}
|
1790 |
+
} else if (is_string($filename) === false) {
|
1791 |
+
$filename = (string) $filename;
|
1792 |
+
}
|
1793 |
+
|
1794 |
+
$errorMessage = '"'.$e->getMessage().'" at '.$e->getFile().':'.$e->getLine();
|
1795 |
+
$error = "An error occurred during processing; checking has been aborted. The error message was: $errorMessage";
|
1796 |
+
|
1797 |
+
$phpcsFile = new PHP_CodeSniffer_File(
|
1798 |
+
$filename,
|
1799 |
+
$this->_tokenListeners,
|
1800 |
+
$this->ruleset,
|
1801 |
+
$this
|
1802 |
+
);
|
1803 |
+
|
1804 |
+
$phpcsFile->addError($error, null, 'Internal.Exception');
|
1805 |
+
}//end try
|
1806 |
+
|
1807 |
+
$cliValues = $this->cli->getCommandLineValues();
|
1808 |
+
|
1809 |
+
if (PHP_CODESNIFFER_INTERACTIVE === false) {
|
1810 |
+
// Cache the report data for this file so we can unset it to save memory.
|
1811 |
+
$this->reporting->cacheFileReport($phpcsFile, $cliValues);
|
1812 |
+
$phpcsFile->cleanUp();
|
1813 |
+
return $phpcsFile;
|
1814 |
+
}
|
1815 |
+
|
1816 |
+
/*
|
1817 |
+
Running interactively.
|
1818 |
+
Print the error report for the current file and then wait for user input.
|
1819 |
+
*/
|
1820 |
+
|
1821 |
+
// Get current violations and then clear the list to make sure
|
1822 |
+
// we only print violations for a single file each time.
|
1823 |
+
$numErrors = null;
|
1824 |
+
while ($numErrors !== 0) {
|
1825 |
+
$numErrors = ($phpcsFile->getErrorCount() + $phpcsFile->getWarningCount());
|
1826 |
+
if ($numErrors === 0) {
|
1827 |
+
continue;
|
1828 |
+
}
|
1829 |
+
|
1830 |
+
$reportClass = $this->reporting->factory('full');
|
1831 |
+
$reportData = $this->reporting->prepareFileReport($phpcsFile);
|
1832 |
+
$reportClass->generateFileReport($reportData, $phpcsFile, $cliValues['showSources'], $cliValues['reportWidth']);
|
1833 |
+
|
1834 |
+
echo '<ENTER> to recheck, [s] to skip or [q] to quit : ';
|
1835 |
+
$input = fgets(STDIN);
|
1836 |
+
$input = trim($input);
|
1837 |
+
|
1838 |
+
switch ($input) {
|
1839 |
+
case 's':
|
1840 |
+
break(2);
|
1841 |
+
case 'q':
|
1842 |
+
exit(0);
|
1843 |
+
break;
|
1844 |
+
default:
|
1845 |
+
// Repopulate the sniffs because some of them save their state
|
1846 |
+
// and only clear it when the file changes, but we are rechecking
|
1847 |
+
// the same file.
|
1848 |
+
$this->populateTokenListeners();
|
1849 |
+
$phpcsFile = $this->_processFile($file, $contents);
|
1850 |
+
break;
|
1851 |
+
}
|
1852 |
+
}//end while
|
1853 |
+
|
1854 |
+
return $phpcsFile;
|
1855 |
+
|
1856 |
+
}//end processFile()
|
1857 |
+
|
1858 |
+
|
1859 |
+
/**
|
1860 |
+
* Process the sniffs for a single file.
|
1861 |
+
*
|
1862 |
+
* Does raw processing only. No interactive support or error checking.
|
1863 |
+
*
|
1864 |
+
* @param string $file The file to process.
|
1865 |
+
* @param string $contents The contents to parse. If NULL, the content
|
1866 |
+
* is taken from the file system.
|
1867 |
+
*
|
1868 |
+
* @return PHP_CodeSniffer_File
|
1869 |
+
* @see processFile()
|
1870 |
+
*/
|
1871 |
+
private function _processFile($file, $contents)
|
1872 |
+
{
|
1873 |
+
$stdin = false;
|
1874 |
+
$cliValues = $this->cli->getCommandLineValues();
|
1875 |
+
if (empty($cliValues['files']) === true) {
|
1876 |
+
$stdin = true;
|
1877 |
+
}
|
1878 |
+
|
1879 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
|
1880 |
+
$startTime = microtime(true);
|
1881 |
+
echo 'Processing '.basename($file).' ';
|
1882 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
1883 |
+
echo PHP_EOL;
|
1884 |
+
}
|
1885 |
+
}
|
1886 |
+
|
1887 |
+
$phpcsFile = new PHP_CodeSniffer_File(
|
1888 |
+
$file,
|
1889 |
+
$this->_tokenListeners,
|
1890 |
+
$this->ruleset,
|
1891 |
+
$this
|
1892 |
+
);
|
1893 |
+
|
1894 |
+
$phpcsFile->start($contents);
|
1895 |
+
|
1896 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
|
1897 |
+
$timeTaken = ((microtime(true) - $startTime) * 1000);
|
1898 |
+
if ($timeTaken < 1000) {
|
1899 |
+
$timeTaken = round($timeTaken);
|
1900 |
+
echo "DONE in {$timeTaken}ms";
|
1901 |
+
} else {
|
1902 |
+
$timeTaken = round(($timeTaken / 1000), 2);
|
1903 |
+
echo "DONE in $timeTaken secs";
|
1904 |
+
}
|
1905 |
+
|
1906 |
+
if (PHP_CODESNIFFER_CBF === true) {
|
1907 |
+
$errors = $phpcsFile->getFixableCount();
|
1908 |
+
echo " ($errors fixable violations)".PHP_EOL;
|
1909 |
+
} else {
|
1910 |
+
$errors = $phpcsFile->getErrorCount();
|
1911 |
+
$warnings = $phpcsFile->getWarningCount();
|
1912 |
+
echo " ($errors errors, $warnings warnings)".PHP_EOL;
|
1913 |
+
}
|
1914 |
+
}
|
1915 |
+
|
1916 |
+
return $phpcsFile;
|
1917 |
+
|
1918 |
+
}//end _processFile()
|
1919 |
+
|
1920 |
+
|
1921 |
+
/**
|
1922 |
+
* Generates documentation for a coding standard.
|
1923 |
+
*
|
1924 |
+
* @param string $standard The standard to generate docs for
|
1925 |
+
* @param array $sniffs A list of sniffs to limit the docs to.
|
1926 |
+
* @param string $generator The name of the generator class to use.
|
1927 |
+
*
|
1928 |
+
* @return void
|
1929 |
+
*/
|
1930 |
+
public function generateDocs($standard, array $sniffs=array(), $generator='Text')
|
1931 |
+
{
|
1932 |
+
if (class_exists('PHP_CodeSniffer_DocGenerators_'.$generator, true) === false) {
|
1933 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_'.$generator.' not found');
|
1934 |
+
}
|
1935 |
+
|
1936 |
+
$class = "PHP_CodeSniffer_DocGenerators_$generator";
|
1937 |
+
$generator = new $class($standard, $sniffs);
|
1938 |
+
|
1939 |
+
$generator->generate();
|
1940 |
+
|
1941 |
+
}//end generateDocs()
|
1942 |
+
|
1943 |
+
|
1944 |
+
/**
|
1945 |
+
* Gets the array of PHP_CodeSniffer_Sniff's.
|
1946 |
+
*
|
1947 |
+
* @return PHP_CodeSniffer_Sniff[]
|
1948 |
+
*/
|
1949 |
+
public function getSniffs()
|
1950 |
+
{
|
1951 |
+
return $this->listeners;
|
1952 |
+
|
1953 |
+
}//end getSniffs()
|
1954 |
+
|
1955 |
+
|
1956 |
+
/**
|
1957 |
+
* Gets the array of PHP_CodeSniffer_Sniff's indexed by token type.
|
1958 |
+
*
|
1959 |
+
* @return array
|
1960 |
+
*/
|
1961 |
+
public function getTokenSniffs()
|
1962 |
+
{
|
1963 |
+
return $this->_tokenListeners;
|
1964 |
+
|
1965 |
+
}//end getTokenSniffs()
|
1966 |
+
|
1967 |
+
|
1968 |
+
/**
|
1969 |
+
* Returns true if the specified string is in the camel caps format.
|
1970 |
+
*
|
1971 |
+
* @param string $string The string the verify.
|
1972 |
+
* @param boolean $classFormat If true, check to see if the string is in the
|
1973 |
+
* class format. Class format strings must start
|
1974 |
+
* with a capital letter and contain no
|
1975 |
+
* underscores.
|
1976 |
+
* @param boolean $public If true, the first character in the string
|
1977 |
+
* must be an a-z character. If false, the
|
1978 |
+
* character must be an underscore. This
|
1979 |
+
* argument is only applicable if $classFormat
|
1980 |
+
* is false.
|
1981 |
+
* @param boolean $strict If true, the string must not have two capital
|
1982 |
+
* letters next to each other. If false, a
|
1983 |
+
* relaxed camel caps policy is used to allow
|
1984 |
+
* for acronyms.
|
1985 |
+
*
|
1986 |
+
* @return boolean
|
1987 |
+
*/
|
1988 |
+
public static function isCamelCaps(
|
1989 |
+
$string,
|
1990 |
+
$classFormat=false,
|
1991 |
+
$public=true,
|
1992 |
+
$strict=true
|
1993 |
+
) {
|
1994 |
+
// Check the first character first.
|
1995 |
+
if ($classFormat === false) {
|
1996 |
+
$legalFirstChar = '';
|
1997 |
+
if ($public === false) {
|
1998 |
+
$legalFirstChar = '[_]';
|
1999 |
+
}
|
2000 |
+
|
2001 |
+
if ($strict === false) {
|
2002 |
+
// Can either start with a lowercase letter, or multiple uppercase
|
2003 |
+
// in a row, representing an acronym.
|
2004 |
+
$legalFirstChar .= '([A-Z]{2,}|[a-z])';
|
2005 |
+
} else {
|
2006 |
+
$legalFirstChar .= '[a-z]';
|
2007 |
+
}
|
2008 |
+
} else {
|
2009 |
+
$legalFirstChar = '[A-Z]';
|
2010 |
+
}
|
2011 |
+
|
2012 |
+
if (preg_match("/^$legalFirstChar/", $string) === 0) {
|
2013 |
+
return false;
|
2014 |
+
}
|
2015 |
+
|
2016 |
+
// Check that the name only contains legal characters.
|
2017 |
+
$legalChars = 'a-zA-Z0-9';
|
2018 |
+
if (preg_match("|[^$legalChars]|", substr($string, 1)) > 0) {
|
2019 |
+
return false;
|
2020 |
+
}
|
2021 |
+
|
2022 |
+
if ($strict === true) {
|
2023 |
+
// Check that there are not two capital letters next to each other.
|
2024 |
+
$length = strlen($string);
|
2025 |
+
$lastCharWasCaps = $classFormat;
|
2026 |
+
|
2027 |
+
for ($i = 1; $i < $length; $i++) {
|
2028 |
+
$ascii = ord($string{$i});
|
2029 |
+
if ($ascii >= 48 && $ascii <= 57) {
|
2030 |
+
// The character is a number, so it cant be a capital.
|
2031 |
+
$isCaps = false;
|
2032 |
+
} else {
|
2033 |
+
if (strtoupper($string{$i}) === $string{$i}) {
|
2034 |
+
$isCaps = true;
|
2035 |
+
} else {
|
2036 |
+
$isCaps = false;
|
2037 |
+
}
|
2038 |
+
}
|
2039 |
+
|
2040 |
+
if ($isCaps === true && $lastCharWasCaps === true) {
|
2041 |
+
return false;
|
2042 |
+
}
|
2043 |
+
|
2044 |
+
$lastCharWasCaps = $isCaps;
|
2045 |
+
}
|
2046 |
+
}//end if
|
2047 |
+
|
2048 |
+
return true;
|
2049 |
+
|
2050 |
+
}//end isCamelCaps()
|
2051 |
+
|
2052 |
+
|
2053 |
+
/**
|
2054 |
+
* Returns true if the specified string is in the underscore caps format.
|
2055 |
+
*
|
2056 |
+
* @param string $string The string to verify.
|
2057 |
+
*
|
2058 |
+
* @return boolean
|
2059 |
+
*/
|
2060 |
+
public static function isUnderscoreName($string)
|
2061 |
+
{
|
2062 |
+
// If there are space in the name, it can't be valid.
|
2063 |
+
if (strpos($string, ' ') !== false) {
|
2064 |
+
return false;
|
2065 |
+
}
|
2066 |
+
|
2067 |
+
$validName = true;
|
2068 |
+
$nameBits = explode('_', $string);
|
2069 |
+
|
2070 |
+
if (preg_match('|^[A-Z]|', $string) === 0) {
|
2071 |
+
// Name does not begin with a capital letter.
|
2072 |
+
$validName = false;
|
2073 |
+
} else {
|
2074 |
+
foreach ($nameBits as $bit) {
|
2075 |
+
if ($bit === '') {
|
2076 |
+
continue;
|
2077 |
+
}
|
2078 |
+
|
2079 |
+
if ($bit{0} !== strtoupper($bit{0})) {
|
2080 |
+
$validName = false;
|
2081 |
+
break;
|
2082 |
+
}
|
2083 |
+
}
|
2084 |
+
}
|
2085 |
+
|
2086 |
+
return $validName;
|
2087 |
+
|
2088 |
+
}//end isUnderscoreName()
|
2089 |
+
|
2090 |
+
|
2091 |
+
/**
|
2092 |
+
* Returns a valid variable type for param/var tag.
|
2093 |
+
*
|
2094 |
+
* If type is not one of the standard type, it must be a custom type.
|
2095 |
+
* Returns the correct type name suggestion if type name is invalid.
|
2096 |
+
*
|
2097 |
+
* @param string $varType The variable type to process.
|
2098 |
+
*
|
2099 |
+
* @return string
|
2100 |
+
*/
|
2101 |
+
public static function suggestType($varType)
|
2102 |
+
{
|
2103 |
+
if ($varType === '') {
|
2104 |
+
return '';
|
2105 |
+
}
|
2106 |
+
|
2107 |
+
if (in_array($varType, self::$allowedTypes) === true) {
|
2108 |
+
return $varType;
|
2109 |
+
} else {
|
2110 |
+
$lowerVarType = strtolower($varType);
|
2111 |
+
switch ($lowerVarType) {
|
2112 |
+
case 'bool':
|
2113 |
+
case 'boolean':
|
2114 |
+
return 'boolean';
|
2115 |
+
case 'double':
|
2116 |
+
case 'real':
|
2117 |
+
case 'float':
|
2118 |
+
return 'float';
|
2119 |
+
case 'int':
|
2120 |
+
case 'integer':
|
2121 |
+
return 'integer';
|
2122 |
+
case 'array()':
|
2123 |
+
case 'array':
|
2124 |
+
return 'array';
|
2125 |
+
}//end switch
|
2126 |
+
|
2127 |
+
if (strpos($lowerVarType, 'array(') !== false) {
|
2128 |
+
// Valid array declaration:
|
2129 |
+
// array, array(type), array(type1 => type2).
|
2130 |
+
$matches = array();
|
2131 |
+
$pattern = '/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i';
|
2132 |
+
if (preg_match($pattern, $varType, $matches) !== 0) {
|
2133 |
+
$type1 = '';
|
2134 |
+
if (isset($matches[1]) === true) {
|
2135 |
+
$type1 = $matches[1];
|
2136 |
+
}
|
2137 |
+
|
2138 |
+
$type2 = '';
|
2139 |
+
if (isset($matches[3]) === true) {
|
2140 |
+
$type2 = $matches[3];
|
2141 |
+
}
|
2142 |
+
|
2143 |
+
$type1 = self::suggestType($type1);
|
2144 |
+
$type2 = self::suggestType($type2);
|
2145 |
+
if ($type2 !== '') {
|
2146 |
+
$type2 = ' => '.$type2;
|
2147 |
+
}
|
2148 |
+
|
2149 |
+
return "array($type1$type2)";
|
2150 |
+
} else {
|
2151 |
+
return 'array';
|
2152 |
+
}//end if
|
2153 |
+
} else if (in_array($lowerVarType, self::$allowedTypes) === true) {
|
2154 |
+
// A valid type, but not lower cased.
|
2155 |
+
return $lowerVarType;
|
2156 |
+
} else {
|
2157 |
+
// Must be a custom type name.
|
2158 |
+
return $varType;
|
2159 |
+
}//end if
|
2160 |
+
}//end if
|
2161 |
+
|
2162 |
+
}//end suggestType()
|
2163 |
+
|
2164 |
+
|
2165 |
+
/**
|
2166 |
+
* Prepares token content for output to screen.
|
2167 |
+
*
|
2168 |
+
* Replaces invisible characters so they are visible. On non-Windows
|
2169 |
+
* OSes it will also colour the invisible characters.
|
2170 |
+
*
|
2171 |
+
* @param string $content The content to prepare.
|
2172 |
+
*
|
2173 |
+
* @return string
|
2174 |
+
*/
|
2175 |
+
public static function prepareForOutput($content)
|
2176 |
+
{
|
2177 |
+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
2178 |
+
$content = str_replace("\r", '\r', $content);
|
2179 |
+
$content = str_replace("\n", '\n', $content);
|
2180 |
+
$content = str_replace("\t", '\t', $content);
|
2181 |
+
} else {
|
2182 |
+
$content = str_replace("\r", "\033[30;1m\\r\033[0m", $content);
|
2183 |
+
$content = str_replace("\n", "\033[30;1m\\n\033[0m", $content);
|
2184 |
+
$content = str_replace("\t", "\033[30;1m\\t\033[0m", $content);
|
2185 |
+
$content = str_replace(' ', "\033[30;1m·\033[0m", $content);
|
2186 |
+
}
|
2187 |
+
|
2188 |
+
return $content;
|
2189 |
+
|
2190 |
+
}//end prepareForOutput()
|
2191 |
+
|
2192 |
+
|
2193 |
+
/**
|
2194 |
+
* Get a list paths where standards are installed.
|
2195 |
+
*
|
2196 |
+
* @return array
|
2197 |
+
*/
|
2198 |
+
public static function getInstalledStandardPaths()
|
2199 |
+
{
|
2200 |
+
$installedPaths = array(dirname(__FILE__).DIRECTORY_SEPARATOR.'CodeSniffer'.DIRECTORY_SEPARATOR.'Standards');
|
2201 |
+
$configPaths = PHP_CodeSniffer::getConfigData('installed_paths');
|
2202 |
+
if ($configPaths !== null) {
|
2203 |
+
$installedPaths = array_merge($installedPaths, explode(',', $configPaths));
|
2204 |
+
}
|
2205 |
+
|
2206 |
+
$resolvedInstalledPaths = array();
|
2207 |
+
foreach ($installedPaths as $installedPath) {
|
2208 |
+
if (substr($installedPath, 0, 1) === '.') {
|
2209 |
+
$installedPath = dirname(__FILE__).DIRECTORY_SEPARATOR.$installedPath;
|
2210 |
+
}
|
2211 |
+
|
2212 |
+
$resolvedInstalledPaths[] = $installedPath;
|
2213 |
+
}
|
2214 |
+
|
2215 |
+
return $resolvedInstalledPaths;
|
2216 |
+
|
2217 |
+
}//end getInstalledStandardPaths()
|
2218 |
+
|
2219 |
+
|
2220 |
+
/**
|
2221 |
+
* Get a list of all coding standards installed.
|
2222 |
+
*
|
2223 |
+
* Coding standards are directories located in the
|
2224 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
2225 |
+
* include a Sniffs subdirectory.
|
2226 |
+
*
|
2227 |
+
* @param boolean $includeGeneric If true, the special "Generic"
|
2228 |
+
* coding standard will be included
|
2229 |
+
* if installed.
|
2230 |
+
* @param string $standardsDir A specific directory to look for standards
|
2231 |
+
* in. If not specified, PHP_CodeSniffer will
|
2232 |
+
* look in its default locations.
|
2233 |
+
*
|
2234 |
+
* @return array
|
2235 |
+
* @see isInstalledStandard()
|
2236 |
+
*/
|
2237 |
+
public static function getInstalledStandards(
|
2238 |
+
$includeGeneric=false,
|
2239 |
+
$standardsDir=''
|
2240 |
+
) {
|
2241 |
+
$installedStandards = array();
|
2242 |
+
|
2243 |
+
if ($standardsDir === '') {
|
2244 |
+
$installedPaths = self::getInstalledStandardPaths();
|
2245 |
+
} else {
|
2246 |
+
$installedPaths = array($standardsDir);
|
2247 |
+
}
|
2248 |
+
|
2249 |
+
foreach ($installedPaths as $standardsDir) {
|
2250 |
+
$di = new DirectoryIterator($standardsDir);
|
2251 |
+
foreach ($di as $file) {
|
2252 |
+
if ($file->isDir() === true && $file->isDot() === false) {
|
2253 |
+
$filename = $file->getFilename();
|
2254 |
+
|
2255 |
+
// Ignore the special "Generic" standard.
|
2256 |
+
if ($includeGeneric === false && $filename === 'Generic') {
|
2257 |
+
continue;
|
2258 |
+
}
|
2259 |
+
|
2260 |
+
// Valid coding standard dirs include a ruleset.
|
2261 |
+
$csFile = $file->getPathname().'/ruleset.xml';
|
2262 |
+
if (is_file($csFile) === true) {
|
2263 |
+
$installedStandards[] = $filename;
|
2264 |
+
}
|
2265 |
+
}
|
2266 |
+
}
|
2267 |
+
}//end foreach
|
2268 |
+
|
2269 |
+
return $installedStandards;
|
2270 |
+
|
2271 |
+
}//end getInstalledStandards()
|
2272 |
+
|
2273 |
+
|
2274 |
+
/**
|
2275 |
+
* Determine if a standard is installed.
|
2276 |
+
*
|
2277 |
+
* Coding standards are directories located in the
|
2278 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
2279 |
+
* include a ruleset.xml file.
|
2280 |
+
*
|
2281 |
+
* @param string $standard The name of the coding standard.
|
2282 |
+
*
|
2283 |
+
* @return boolean
|
2284 |
+
* @see getInstalledStandards()
|
2285 |
+
*/
|
2286 |
+
public static function isInstalledStandard($standard)
|
2287 |
+
{
|
2288 |
+
$path = self::getInstalledStandardPath($standard);
|
2289 |
+
if ($path !== null && strpos($path, 'ruleset.xml') !== false) {
|
2290 |
+
return true;
|
2291 |
+
} else {
|
2292 |
+
// This could be a custom standard, installed outside our
|
2293 |
+
// standards directory.
|
2294 |
+
$standard = self::realPath($standard);
|
2295 |
+
|
2296 |
+
// Might be an actual ruleset file itself.
|
2297 |
+
// If it has an XML extension, let's at least try it.
|
2298 |
+
if (is_file($standard) === true
|
2299 |
+
&& (substr(strtolower($standard), -4) === '.xml'
|
2300 |
+
|| substr(strtolower($standard), -9) === '.xml.dist')
|
2301 |
+
) {
|
2302 |
+
return true;
|
2303 |
+
}
|
2304 |
+
|
2305 |
+
// If it is a directory with a ruleset.xml file in it,
|
2306 |
+
// it is a standard.
|
2307 |
+
$ruleset = rtrim($standard, ' /\\').DIRECTORY_SEPARATOR.'ruleset.xml';
|
2308 |
+
if (is_file($ruleset) === true) {
|
2309 |
+
return true;
|
2310 |
+
}
|
2311 |
+
}//end if
|
2312 |
+
|
2313 |
+
return false;
|
2314 |
+
|
2315 |
+
}//end isInstalledStandard()
|
2316 |
+
|
2317 |
+
|
2318 |
+
/**
|
2319 |
+
* Return the path of an installed coding standard.
|
2320 |
+
*
|
2321 |
+
* Coding standards are directories located in the
|
2322 |
+
* CodeSniffer/Standards directory. Valid coding standards
|
2323 |
+
* include a ruleset.xml file.
|
2324 |
+
*
|
2325 |
+
* @param string $standard The name of the coding standard.
|
2326 |
+
*
|
2327 |
+
* @return string|null
|
2328 |
+
*/
|
2329 |
+
public static function getInstalledStandardPath($standard)
|
2330 |
+
{
|
2331 |
+
$installedPaths = self::getInstalledStandardPaths();
|
2332 |
+
foreach ($installedPaths as $installedPath) {
|
2333 |
+
$standardPath = $installedPath.DIRECTORY_SEPARATOR.$standard;
|
2334 |
+
$path = self::realpath($standardPath.DIRECTORY_SEPARATOR.'ruleset.xml');
|
2335 |
+
if (is_file($path) === true) {
|
2336 |
+
return $path;
|
2337 |
+
} else if (self::isPharFile($standardPath) === true) {
|
2338 |
+
$path = self::realpath($standardPath);
|
2339 |
+
if ($path !== false) {
|
2340 |
+
return $path;
|
2341 |
+
}
|
2342 |
+
}
|
2343 |
+
}
|
2344 |
+
|
2345 |
+
return null;
|
2346 |
+
|
2347 |
+
}//end getInstalledStandardPath()
|
2348 |
+
|
2349 |
+
|
2350 |
+
/**
|
2351 |
+
* Get a single config value.
|
2352 |
+
*
|
2353 |
+
* Config data is stored in the data dir, in a file called
|
2354 |
+
* CodeSniffer.conf. It is a simple PHP array.
|
2355 |
+
*
|
2356 |
+
* @param string $key The name of the config value.
|
2357 |
+
*
|
2358 |
+
* @return string|null
|
2359 |
+
* @see setConfigData()
|
2360 |
+
* @see getAllConfigData()
|
2361 |
+
*/
|
2362 |
+
public static function getConfigData($key)
|
2363 |
+
{
|
2364 |
+
$phpCodeSnifferConfig = self::getAllConfigData();
|
2365 |
+
|
2366 |
+
if ($phpCodeSnifferConfig === null) {
|
2367 |
+
return null;
|
2368 |
+
}
|
2369 |
+
|
2370 |
+
if (isset($phpCodeSnifferConfig[$key]) === false) {
|
2371 |
+
return null;
|
2372 |
+
}
|
2373 |
+
|
2374 |
+
return $phpCodeSnifferConfig[$key];
|
2375 |
+
|
2376 |
+
}//end getConfigData()
|
2377 |
+
|
2378 |
+
|
2379 |
+
/**
|
2380 |
+
* Set a single config value.
|
2381 |
+
*
|
2382 |
+
* Config data is stored in the data dir, in a file called
|
2383 |
+
* CodeSniffer.conf. It is a simple PHP array.
|
2384 |
+
*
|
2385 |
+
* @param string $key The name of the config value.
|
2386 |
+
* @param string|null $value The value to set. If null, the config
|
2387 |
+
* entry is deleted, reverting it to the
|
2388 |
+
* default value.
|
2389 |
+
* @param boolean $temp Set this config data temporarily for this
|
2390 |
+
* script run. This will not write the config
|
2391 |
+
* data to the config file.
|
2392 |
+
*
|
2393 |
+
* @return boolean
|
2394 |
+
* @see getConfigData()
|
2395 |
+
* @throws PHP_CodeSniffer_Exception If the config file can not be written.
|
2396 |
+
*/
|
2397 |
+
public static function setConfigData($key, $value, $temp=false)
|
2398 |
+
{
|
2399 |
+
if ($temp === false) {
|
2400 |
+
$path = '';
|
2401 |
+
if (is_callable('Phar::running') === true) {
|
2402 |
+
$path = Phar::running(false);
|
2403 |
+
}
|
2404 |
+
|
2405 |
+
if ($path !== '') {
|
2406 |
+
$configFile = dirname($path).'/CodeSniffer.conf';
|
2407 |
+
} else {
|
2408 |
+
$configFile = dirname(__FILE__).'/CodeSniffer.conf';
|
2409 |
+
if (is_file($configFile) === false
|
2410 |
+
&& strpos('@data_dir@', '@data_dir') === false
|
2411 |
+
) {
|
2412 |
+
// If data_dir was replaced, this is a PEAR install and we can
|
2413 |
+
// use the PEAR data dir to store the conf file.
|
2414 |
+
$configFile = '@data_dir@/PHP_CodeSniffer/CodeSniffer.conf';
|
2415 |
+
}
|
2416 |
+
}
|
2417 |
+
|
2418 |
+
if (is_file($configFile) === true
|
2419 |
+
&& is_writable($configFile) === false
|
2420 |
+
) {
|
2421 |
+
$error = 'Config file '.$configFile.' is not writable';
|
2422 |
+
throw new PHP_CodeSniffer_Exception($error);
|
2423 |
+
}
|
2424 |
+
}//end if
|
2425 |
+
|
2426 |
+
$phpCodeSnifferConfig = self::getAllConfigData();
|
2427 |
+
|
2428 |
+
if ($value === null) {
|
2429 |
+
if (isset($phpCodeSnifferConfig[$key]) === true) {
|
2430 |
+
unset($phpCodeSnifferConfig[$key]);
|
2431 |
+
}
|
2432 |
+
} else {
|
2433 |
+
$phpCodeSnifferConfig[$key] = $value;
|
2434 |
+
}
|
2435 |
+
|
2436 |
+
if ($temp === false) {
|
2437 |
+
$output = '<'.'?php'."\n".' $phpCodeSnifferConfig = ';
|
2438 |
+
$output .= var_export($phpCodeSnifferConfig, true);
|
2439 |
+
$output .= "\n?".'>';
|
2440 |
+
|
2441 |
+
if (file_put_contents($configFile, $output) === false) {
|
2442 |
+
return false;
|
2443 |
+
}
|
2444 |
+
}
|
2445 |
+
|
2446 |
+
$GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = $phpCodeSnifferConfig;
|
2447 |
+
|
2448 |
+
return true;
|
2449 |
+
|
2450 |
+
}//end setConfigData()
|
2451 |
+
|
2452 |
+
|
2453 |
+
/**
|
2454 |
+
* Get all config data in an array.
|
2455 |
+
*
|
2456 |
+
* @return array<string, string>
|
2457 |
+
* @see getConfigData()
|
2458 |
+
*/
|
2459 |
+
public static function getAllConfigData()
|
2460 |
+
{
|
2461 |
+
if (isset($GLOBALS['PHP_CODESNIFFER_CONFIG_DATA']) === true) {
|
2462 |
+
return $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'];
|
2463 |
+
}
|
2464 |
+
|
2465 |
+
$path = '';
|
2466 |
+
if (is_callable('Phar::running') === true) {
|
2467 |
+
$path = Phar::running(false);
|
2468 |
+
}
|
2469 |
+
|
2470 |
+
if ($path !== '') {
|
2471 |
+
$configFile = dirname($path).'/CodeSniffer.conf';
|
2472 |
+
} else {
|
2473 |
+
$configFile = dirname(__FILE__).'/CodeSniffer.conf';
|
2474 |
+
if (is_file($configFile) === false) {
|
2475 |
+
$configFile = '@data_dir@/PHP_CodeSniffer/CodeSniffer.conf';
|
2476 |
+
}
|
2477 |
+
}
|
2478 |
+
|
2479 |
+
if (is_file($configFile) === false) {
|
2480 |
+
$GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = array();
|
2481 |
+
return array();
|
2482 |
+
}
|
2483 |
+
|
2484 |
+
include $configFile;
|
2485 |
+
$GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = $phpCodeSnifferConfig;
|
2486 |
+
return $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'];
|
2487 |
+
|
2488 |
+
}//end getAllConfigData()
|
2489 |
+
|
2490 |
+
|
2491 |
+
/**
|
2492 |
+
* Return TRUE, if the path is a phar file.
|
2493 |
+
*
|
2494 |
+
* @param string $path The path to use.
|
2495 |
+
*
|
2496 |
+
* @return mixed
|
2497 |
+
*/
|
2498 |
+
public static function isPharFile($path)
|
2499 |
+
{
|
2500 |
+
if (strpos($path, 'phar://') === 0) {
|
2501 |
+
return true;
|
2502 |
+
}
|
2503 |
+
|
2504 |
+
return false;
|
2505 |
+
|
2506 |
+
}//end isPharFile()
|
2507 |
+
|
2508 |
+
|
2509 |
+
/**
|
2510 |
+
* CodeSniffer alternative for realpath.
|
2511 |
+
*
|
2512 |
+
* Allows for phar support.
|
2513 |
+
*
|
2514 |
+
* @param string $path The path to use.
|
2515 |
+
*
|
2516 |
+
* @return mixed
|
2517 |
+
*/
|
2518 |
+
public static function realpath($path)
|
2519 |
+
{
|
2520 |
+
// Support the path replacement of ~ with the user's home directory.
|
2521 |
+
if (substr($path, 0, 2) === '~/') {
|
2522 |
+
$homeDir = getenv('HOME');
|
2523 |
+
if ($homeDir !== false) {
|
2524 |
+
$path = $homeDir.substr($path, 1);
|
2525 |
+
}
|
2526 |
+
}
|
2527 |
+
|
2528 |
+
// No extra work needed if this is not a phar file.
|
2529 |
+
if (self::isPharFile($path) === false) {
|
2530 |
+
return realpath($path);
|
2531 |
+
}
|
2532 |
+
|
2533 |
+
// Before trying to break down the file path,
|
2534 |
+
// check if it exists first because it will mostly not
|
2535 |
+
// change after running the below code.
|
2536 |
+
if (file_exists($path) === true) {
|
2537 |
+
return $path;
|
2538 |
+
}
|
2539 |
+
|
2540 |
+
$phar = Phar::running(false);
|
2541 |
+
$extra = str_replace('phar://'.$phar, '', $path);
|
2542 |
+
$path = realpath($phar);
|
2543 |
+
if ($path === false) {
|
2544 |
+
return false;
|
2545 |
+
}
|
2546 |
+
|
2547 |
+
$path = 'phar://'.$path.$extra;
|
2548 |
+
if (file_exists($path) === true) {
|
2549 |
+
return $path;
|
2550 |
+
}
|
2551 |
+
|
2552 |
+
return false;
|
2553 |
+
|
2554 |
+
}//end realpath()
|
2555 |
+
|
2556 |
+
|
2557 |
+
/**
|
2558 |
+
* CodeSniffer alternative for chdir().
|
2559 |
+
*
|
2560 |
+
* Allows for phar support.
|
2561 |
+
*
|
2562 |
+
* @param string $path The path to use.
|
2563 |
+
*
|
2564 |
+
* @return void
|
2565 |
+
*/
|
2566 |
+
public static function chdir($path)
|
2567 |
+
{
|
2568 |
+
if (self::isPharFile($path) === true) {
|
2569 |
+
$phar = Phar::running(false);
|
2570 |
+
chdir(dirname($phar));
|
2571 |
+
} else {
|
2572 |
+
chdir($path);
|
2573 |
+
}
|
2574 |
+
|
2575 |
+
}//end chdir()
|
2576 |
+
|
2577 |
+
|
2578 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php
ADDED
@@ -0,0 +1,1444 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A class to process command line phpcs scripts.
|
4 |
+
*
|
5 |
+
* PHP version 5
|
6 |
+
*
|
7 |
+
* @category PHP
|
8 |
+
* @package PHP_CodeSniffer
|
9 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
10 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
11 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
12 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
13 |
+
*/
|
14 |
+
|
15 |
+
error_reporting(E_ALL | E_STRICT);
|
16 |
+
|
17 |
+
// Make sure version id constant is available.
|
18 |
+
if (defined('PHP_VERSION_ID') === false) {
|
19 |
+
$version = explode('.', PHP_VERSION);
|
20 |
+
define('PHP_VERSION_ID', (int) (($version[0] * 10000) + ($version[1] * 100) + $version[2]));
|
21 |
+
unset($version);
|
22 |
+
}
|
23 |
+
|
24 |
+
// Make sure that we autoload all dependencies if running via Composer.
|
25 |
+
if (PHP_VERSION_ID >= 50302) {
|
26 |
+
if (file_exists($a = dirname(__FILE__).'/../../../autoload.php') === true) {
|
27 |
+
include_once $a;
|
28 |
+
} else if (file_exists($a = dirname(__FILE__).'/../vendor/autoload.php') === true) {
|
29 |
+
include_once $a;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
if (file_exists($a = dirname(__FILE__).'/../CodeSniffer.php') === true) {
|
34 |
+
// Running from a git clone.
|
35 |
+
include_once $a;
|
36 |
+
} else {
|
37 |
+
// PEAR installed.
|
38 |
+
include_once 'PHP/CodeSniffer.php';
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* A class to process command line phpcs scripts.
|
43 |
+
*
|
44 |
+
* @category PHP
|
45 |
+
* @package PHP_CodeSniffer
|
46 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
47 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
48 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
49 |
+
* @version Release: @package_version@
|
50 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
51 |
+
*/
|
52 |
+
class PHP_CodeSniffer_CLI
|
53 |
+
{
|
54 |
+
|
55 |
+
/**
|
56 |
+
* An array of all values specified on the command line.
|
57 |
+
*
|
58 |
+
* @var array
|
59 |
+
*/
|
60 |
+
protected $values = array();
|
61 |
+
|
62 |
+
/**
|
63 |
+
* The minimum severity level errors must have to be displayed.
|
64 |
+
*
|
65 |
+
* @var bool
|
66 |
+
*/
|
67 |
+
public $errorSeverity = 0;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* The minimum severity level warnings must have to be displayed.
|
71 |
+
*
|
72 |
+
* @var bool
|
73 |
+
*/
|
74 |
+
public $warningSeverity = 0;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Whether or not to kill the process when an unknown command line arg is found.
|
78 |
+
*
|
79 |
+
* If FALSE, arguments that are not command line options or file/directory paths
|
80 |
+
* will be ignored and execution will continue.
|
81 |
+
*
|
82 |
+
* @var bool
|
83 |
+
*/
|
84 |
+
public $dieOnUnknownArg = true;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* An array of the current command line arguments we are processing.
|
88 |
+
*
|
89 |
+
* @var array
|
90 |
+
*/
|
91 |
+
private $_cliArgs = array();
|
92 |
+
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Run the PHPCS script.
|
96 |
+
*
|
97 |
+
* @return array
|
98 |
+
*/
|
99 |
+
public function runphpcs()
|
100 |
+
{
|
101 |
+
if (defined('PHP_CODESNIFFER_CBF') === false) {
|
102 |
+
define('PHP_CODESNIFFER_CBF', false);
|
103 |
+
}
|
104 |
+
|
105 |
+
if (is_file(dirname(__FILE__).'/../CodeSniffer/Reporting.php') === true) {
|
106 |
+
include_once dirname(__FILE__).'/../CodeSniffer/Reporting.php';
|
107 |
+
} else {
|
108 |
+
include_once 'PHP/CodeSniffer/Reporting.php';
|
109 |
+
}
|
110 |
+
|
111 |
+
PHP_CodeSniffer_Reporting::startTiming();
|
112 |
+
$this->checkRequirements();
|
113 |
+
$numErrors = $this->process();
|
114 |
+
if ($numErrors === 0) {
|
115 |
+
exit(0);
|
116 |
+
} else {
|
117 |
+
exit(1);
|
118 |
+
}
|
119 |
+
|
120 |
+
}//end runphpcs()
|
121 |
+
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Run the PHPCBF script.
|
125 |
+
*
|
126 |
+
* @return array
|
127 |
+
*/
|
128 |
+
public function runphpcbf()
|
129 |
+
{
|
130 |
+
if (defined('PHP_CODESNIFFER_CBF') === false) {
|
131 |
+
define('PHP_CODESNIFFER_CBF', true);
|
132 |
+
}
|
133 |
+
|
134 |
+
if (is_file(dirname(__FILE__).'/../CodeSniffer/Reporting.php') === true) {
|
135 |
+
include_once dirname(__FILE__).'/../CodeSniffer/Reporting.php';
|
136 |
+
} else {
|
137 |
+
include_once 'PHP/CodeSniffer/Reporting.php';
|
138 |
+
}
|
139 |
+
|
140 |
+
PHP_CodeSniffer_Reporting::startTiming();
|
141 |
+
$this->checkRequirements();
|
142 |
+
|
143 |
+
$this->dieOnUnknownArg = false;
|
144 |
+
|
145 |
+
// Override some of the command line settings that might break the fixes.
|
146 |
+
$cliValues = $this->getCommandLineValues();
|
147 |
+
$cliValues['verbosity'] = 0;
|
148 |
+
$cliValues['showProgress'] = false;
|
149 |
+
$cliValues['generator'] = '';
|
150 |
+
$cliValues['explain'] = false;
|
151 |
+
$cliValues['interactive'] = false;
|
152 |
+
$cliValues['showSources'] = false;
|
153 |
+
$cliValues['reportFile'] = null;
|
154 |
+
$cliValues['reports'] = array();
|
155 |
+
|
156 |
+
$suffix = '';
|
157 |
+
if (isset($cliValues['suffix']) === true) {
|
158 |
+
$suffix = $cliValues['suffix'];
|
159 |
+
}
|
160 |
+
|
161 |
+
$allowPatch = true;
|
162 |
+
if (isset($cliValues['no-patch']) === true || empty($cliValues['files']) === true) {
|
163 |
+
// They either asked for this,
|
164 |
+
// or they are using STDIN, which can't use diff.
|
165 |
+
$allowPatch = false;
|
166 |
+
}
|
167 |
+
|
168 |
+
if ($suffix === '' && $allowPatch === true) {
|
169 |
+
// Using the diff/patch tools.
|
170 |
+
$diffFile = getcwd().'/phpcbf-fixed.diff';
|
171 |
+
$cliValues['reports'] = array('diff' => $diffFile);
|
172 |
+
if (file_exists($diffFile) === true) {
|
173 |
+
unlink($diffFile);
|
174 |
+
}
|
175 |
+
} else {
|
176 |
+
// Replace the file without the patch command
|
177 |
+
// or writing to a file with a new suffix.
|
178 |
+
$cliValues['reports'] = array('cbf' => null);
|
179 |
+
$cliValues['phpcbf-suffix'] = $suffix;
|
180 |
+
}
|
181 |
+
|
182 |
+
$numErrors = $this->process($cliValues);
|
183 |
+
|
184 |
+
if ($suffix === '' && $allowPatch === true) {
|
185 |
+
if (file_exists($diffFile) === false) {
|
186 |
+
// Nothing to fix.
|
187 |
+
if ($numErrors === 0) {
|
188 |
+
// And no errors reported.
|
189 |
+
$exit = 0;
|
190 |
+
} else {
|
191 |
+
// Errors we can't fix.
|
192 |
+
$exit = 2;
|
193 |
+
}
|
194 |
+
} else {
|
195 |
+
if (filesize($diffFile) < 10) {
|
196 |
+
// Empty or bad diff file.
|
197 |
+
if ($numErrors === 0) {
|
198 |
+
// And no errors reported.
|
199 |
+
$exit = 0;
|
200 |
+
} else {
|
201 |
+
// Errors we can't fix.
|
202 |
+
$exit = 2;
|
203 |
+
}
|
204 |
+
} else {
|
205 |
+
$cmd = "patch -p0 -ui \"$diffFile\"";
|
206 |
+
$output = array();
|
207 |
+
$retVal = null;
|
208 |
+
exec($cmd, $output, $retVal);
|
209 |
+
|
210 |
+
if ($retVal === 0) {
|
211 |
+
// Everything went well.
|
212 |
+
$filesPatched = count($output);
|
213 |
+
echo "Patched $filesPatched file";
|
214 |
+
if ($filesPatched > 1) {
|
215 |
+
echo 's';
|
216 |
+
}
|
217 |
+
|
218 |
+
echo PHP_EOL;
|
219 |
+
$exit = 1;
|
220 |
+
} else {
|
221 |
+
print_r($output);
|
222 |
+
echo "Returned: $retVal".PHP_EOL;
|
223 |
+
$exit = 3;
|
224 |
+
}
|
225 |
+
}//end if
|
226 |
+
|
227 |
+
unlink($diffFile);
|
228 |
+
}//end if
|
229 |
+
} else {
|
230 |
+
// File are being patched manually, so we can't tell
|
231 |
+
// how many errors were fixed.
|
232 |
+
$exit = 1;
|
233 |
+
}//end if
|
234 |
+
|
235 |
+
if ($exit === 0) {
|
236 |
+
echo 'No fixable errors were found'.PHP_EOL;
|
237 |
+
} else if ($exit === 2) {
|
238 |
+
echo 'PHPCBF could not fix all the errors found'.PHP_EOL;
|
239 |
+
}
|
240 |
+
|
241 |
+
PHP_CodeSniffer_Reporting::printRunTime();
|
242 |
+
exit($exit);
|
243 |
+
|
244 |
+
}//end runphpcbf()
|
245 |
+
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Exits if the minimum requirements of PHP_CodSniffer are not met.
|
249 |
+
*
|
250 |
+
* @return array
|
251 |
+
*/
|
252 |
+
public function checkRequirements()
|
253 |
+
{
|
254 |
+
// Check the PHP version.
|
255 |
+
if (PHP_VERSION_ID < 50102) {
|
256 |
+
echo 'ERROR: PHP_CodeSniffer requires PHP version 5.1.2 or greater.'.PHP_EOL;
|
257 |
+
exit(2);
|
258 |
+
}
|
259 |
+
|
260 |
+
if (extension_loaded('tokenizer') === false) {
|
261 |
+
echo 'ERROR: PHP_CodeSniffer requires the tokenizer extension to be enabled.'.PHP_EOL;
|
262 |
+
exit(2);
|
263 |
+
}
|
264 |
+
|
265 |
+
}//end checkRequirements()
|
266 |
+
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Get a list of default values for all possible command line arguments.
|
270 |
+
*
|
271 |
+
* @return array
|
272 |
+
*/
|
273 |
+
public function getDefaults()
|
274 |
+
{
|
275 |
+
if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
|
276 |
+
return array();
|
277 |
+
}
|
278 |
+
|
279 |
+
// The default values for config settings.
|
280 |
+
$defaults['files'] = array();
|
281 |
+
$defaults['standard'] = null;
|
282 |
+
$defaults['verbosity'] = 0;
|
283 |
+
$defaults['interactive'] = false;
|
284 |
+
$defaults['colors'] = false;
|
285 |
+
$defaults['explain'] = false;
|
286 |
+
$defaults['local'] = false;
|
287 |
+
$defaults['showSources'] = false;
|
288 |
+
$defaults['extensions'] = array();
|
289 |
+
$defaults['sniffs'] = array();
|
290 |
+
$defaults['exclude'] = array();
|
291 |
+
$defaults['ignored'] = array();
|
292 |
+
$defaults['reportFile'] = null;
|
293 |
+
$defaults['generator'] = '';
|
294 |
+
$defaults['reports'] = array();
|
295 |
+
$defaults['bootstrap'] = array();
|
296 |
+
$defaults['errorSeverity'] = null;
|
297 |
+
$defaults['warningSeverity'] = null;
|
298 |
+
$defaults['stdin'] = null;
|
299 |
+
$defaults['stdinPath'] = '';
|
300 |
+
|
301 |
+
$reportFormat = PHP_CodeSniffer::getConfigData('report_format');
|
302 |
+
if ($reportFormat !== null) {
|
303 |
+
$defaults['reports'][$reportFormat] = null;
|
304 |
+
}
|
305 |
+
|
306 |
+
$tabWidth = PHP_CodeSniffer::getConfigData('tab_width');
|
307 |
+
if ($tabWidth === null) {
|
308 |
+
$defaults['tabWidth'] = 0;
|
309 |
+
} else {
|
310 |
+
$defaults['tabWidth'] = (int) $tabWidth;
|
311 |
+
}
|
312 |
+
|
313 |
+
$encoding = PHP_CodeSniffer::getConfigData('encoding');
|
314 |
+
if ($encoding === null) {
|
315 |
+
$defaults['encoding'] = 'iso-8859-1';
|
316 |
+
} else {
|
317 |
+
$defaults['encoding'] = strtolower($encoding);
|
318 |
+
}
|
319 |
+
|
320 |
+
$severity = PHP_CodeSniffer::getConfigData('severity');
|
321 |
+
if ($severity !== null) {
|
322 |
+
$defaults['errorSeverity'] = (int) $severity;
|
323 |
+
$defaults['warningSeverity'] = (int) $severity;
|
324 |
+
}
|
325 |
+
|
326 |
+
$severity = PHP_CodeSniffer::getConfigData('error_severity');
|
327 |
+
if ($severity !== null) {
|
328 |
+
$defaults['errorSeverity'] = (int) $severity;
|
329 |
+
}
|
330 |
+
|
331 |
+
$severity = PHP_CodeSniffer::getConfigData('warning_severity');
|
332 |
+
if ($severity !== null) {
|
333 |
+
$defaults['warningSeverity'] = (int) $severity;
|
334 |
+
}
|
335 |
+
|
336 |
+
$showWarnings = PHP_CodeSniffer::getConfigData('show_warnings');
|
337 |
+
if ($showWarnings !== null) {
|
338 |
+
$showWarnings = (bool) $showWarnings;
|
339 |
+
if ($showWarnings === false) {
|
340 |
+
$defaults['warningSeverity'] = 0;
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
$reportWidth = PHP_CodeSniffer::getConfigData('report_width');
|
345 |
+
if ($reportWidth !== null) {
|
346 |
+
$defaults['reportWidth'] = $this->_validateReportWidth($reportWidth);
|
347 |
+
} else {
|
348 |
+
// Use function defaults.
|
349 |
+
$defaults['reportWidth'] = null;
|
350 |
+
}
|
351 |
+
|
352 |
+
$showProgress = PHP_CodeSniffer::getConfigData('show_progress');
|
353 |
+
if ($showProgress === null) {
|
354 |
+
$defaults['showProgress'] = false;
|
355 |
+
} else {
|
356 |
+
$defaults['showProgress'] = (bool) $showProgress;
|
357 |
+
}
|
358 |
+
|
359 |
+
$quiet = PHP_CodeSniffer::getConfigData('quiet');
|
360 |
+
if ($quiet === null) {
|
361 |
+
$defaults['quiet'] = false;
|
362 |
+
} else {
|
363 |
+
$defaults['quiet'] = (bool) $quiet;
|
364 |
+
}
|
365 |
+
|
366 |
+
$colors = PHP_CodeSniffer::getConfigData('colors');
|
367 |
+
if ($colors === null) {
|
368 |
+
$defaults['colors'] = false;
|
369 |
+
} else {
|
370 |
+
$defaults['colors'] = (bool) $colors;
|
371 |
+
}
|
372 |
+
|
373 |
+
if (PHP_CodeSniffer::isPharFile(dirname(dirname(__FILE__))) === true) {
|
374 |
+
// If this is a phar file, check for the standard in the config.
|
375 |
+
$standard = PHP_CodeSniffer::getConfigData('standard');
|
376 |
+
if ($standard !== null) {
|
377 |
+
$defaults['standard'] = $standard;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
return $defaults;
|
382 |
+
|
383 |
+
}//end getDefaults()
|
384 |
+
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Gets the processed command line values.
|
388 |
+
*
|
389 |
+
* If the values have not yet been set, the values will be sourced
|
390 |
+
* from the command line arguments.
|
391 |
+
*
|
392 |
+
* @return array
|
393 |
+
*/
|
394 |
+
public function getCommandLineValues()
|
395 |
+
{
|
396 |
+
if (empty($this->values) === false) {
|
397 |
+
return $this->values;
|
398 |
+
}
|
399 |
+
|
400 |
+
$args = $_SERVER['argv'];
|
401 |
+
array_shift($args);
|
402 |
+
|
403 |
+
$this->setCommandLineValues($args);
|
404 |
+
|
405 |
+
// Check for content on STDIN.
|
406 |
+
$handle = fopen('php://stdin', 'r');
|
407 |
+
if (stream_set_blocking($handle, false) === true) {
|
408 |
+
$fileContents = '';
|
409 |
+
while (($line = fgets($handle)) !== false) {
|
410 |
+
$fileContents .= $line;
|
411 |
+
usleep(10);
|
412 |
+
}
|
413 |
+
|
414 |
+
stream_set_blocking($handle, true);
|
415 |
+
fclose($handle);
|
416 |
+
if (trim($fileContents) !== '') {
|
417 |
+
$this->values['stdin'] = $fileContents;
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
return $this->values;
|
422 |
+
|
423 |
+
}//end getCommandLineValues()
|
424 |
+
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Set the command line values.
|
428 |
+
*
|
429 |
+
* @param array $args An array of command line arguments to process.
|
430 |
+
*
|
431 |
+
* @return void
|
432 |
+
*/
|
433 |
+
public function setCommandLineValues($args)
|
434 |
+
{
|
435 |
+
if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
|
436 |
+
$this->values = array(
|
437 |
+
'stdin' => null,
|
438 |
+
'quiet' => true,
|
439 |
+
);
|
440 |
+
} else if (empty($this->values) === true) {
|
441 |
+
$this->values = $this->getDefaults();
|
442 |
+
}
|
443 |
+
|
444 |
+
$this->_cliArgs = $args;
|
445 |
+
$numArgs = count($args);
|
446 |
+
|
447 |
+
for ($i = 0; $i < $numArgs; $i++) {
|
448 |
+
$arg = $this->_cliArgs[$i];
|
449 |
+
if ($arg === '') {
|
450 |
+
continue;
|
451 |
+
}
|
452 |
+
|
453 |
+
if ($arg{0} === '-') {
|
454 |
+
if ($arg === '-' || $arg === '--') {
|
455 |
+
// Empty argument, ignore it.
|
456 |
+
continue;
|
457 |
+
}
|
458 |
+
|
459 |
+
if ($arg{1} === '-') {
|
460 |
+
$this->processLongArgument(substr($arg, 2), $i);
|
461 |
+
} else {
|
462 |
+
$switches = str_split($arg);
|
463 |
+
foreach ($switches as $switch) {
|
464 |
+
if ($switch === '-') {
|
465 |
+
continue;
|
466 |
+
}
|
467 |
+
|
468 |
+
$this->processShortArgument($switch, $i);
|
469 |
+
}
|
470 |
+
}
|
471 |
+
} else {
|
472 |
+
$this->processUnknownArgument($arg, $i);
|
473 |
+
}//end if
|
474 |
+
}//end for
|
475 |
+
|
476 |
+
}//end setCommandLineValues()
|
477 |
+
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Processes a short (-e) command line argument.
|
481 |
+
*
|
482 |
+
* @param string $arg The command line argument.
|
483 |
+
* @param int $pos The position of the argument on the command line.
|
484 |
+
*
|
485 |
+
* @return void
|
486 |
+
*/
|
487 |
+
public function processShortArgument($arg, $pos)
|
488 |
+
{
|
489 |
+
switch ($arg) {
|
490 |
+
case 'h':
|
491 |
+
case '?':
|
492 |
+
$this->printUsage();
|
493 |
+
exit(0);
|
494 |
+
case 'i' :
|
495 |
+
$this->printInstalledStandards();
|
496 |
+
exit(0);
|
497 |
+
case 'v' :
|
498 |
+
if ($this->values['quiet'] === true) {
|
499 |
+
// Ignore when quiet mode is enabled.
|
500 |
+
break;
|
501 |
+
}
|
502 |
+
|
503 |
+
if (isset($this->values['verbosity']) === false) {
|
504 |
+
$this->values['verbosity'] = 1;
|
505 |
+
} else {
|
506 |
+
$this->values['verbosity']++;
|
507 |
+
}
|
508 |
+
break;
|
509 |
+
case 'l' :
|
510 |
+
$this->values['local'] = true;
|
511 |
+
break;
|
512 |
+
case 's' :
|
513 |
+
$this->values['showSources'] = true;
|
514 |
+
break;
|
515 |
+
case 'a' :
|
516 |
+
$this->values['interactive'] = true;
|
517 |
+
break;
|
518 |
+
case 'e':
|
519 |
+
$this->values['explain'] = true;
|
520 |
+
break;
|
521 |
+
case 'p' :
|
522 |
+
if ($this->values['quiet'] === true) {
|
523 |
+
// Ignore when quiet mode is enabled.
|
524 |
+
break;
|
525 |
+
}
|
526 |
+
|
527 |
+
$this->values['showProgress'] = true;
|
528 |
+
break;
|
529 |
+
case 'q' :
|
530 |
+
// Quiet mode disables a few other settings as well.
|
531 |
+
$this->values['quiet'] = true;
|
532 |
+
$this->values['showProgress'] = false;
|
533 |
+
$this->values['verbosity'] = 0;
|
534 |
+
break;
|
535 |
+
case 'd' :
|
536 |
+
$ini = explode('=', $this->_cliArgs[($pos + 1)]);
|
537 |
+
$this->_cliArgs[($pos + 1)] = '';
|
538 |
+
if (isset($ini[1]) === true) {
|
539 |
+
ini_set($ini[0], $ini[1]);
|
540 |
+
} else {
|
541 |
+
ini_set($ini[0], true);
|
542 |
+
}
|
543 |
+
break;
|
544 |
+
case 'n' :
|
545 |
+
$this->values['warningSeverity'] = 0;
|
546 |
+
break;
|
547 |
+
case 'w' :
|
548 |
+
$this->values['warningSeverity'] = null;
|
549 |
+
break;
|
550 |
+
default:
|
551 |
+
if ($this->dieOnUnknownArg === false) {
|
552 |
+
$this->values[$arg] = $arg;
|
553 |
+
} else {
|
554 |
+
$this->processUnknownArgument('-'.$arg, $pos);
|
555 |
+
}
|
556 |
+
}//end switch
|
557 |
+
|
558 |
+
}//end processShortArgument()
|
559 |
+
|
560 |
+
|
561 |
+
/**
|
562 |
+
* Processes a long (--example) command line argument.
|
563 |
+
*
|
564 |
+
* @param string $arg The command line argument.
|
565 |
+
* @param int $pos The position of the argument on the command line.
|
566 |
+
*
|
567 |
+
* @return void
|
568 |
+
*/
|
569 |
+
public function processLongArgument($arg, $pos)
|
570 |
+
{
|
571 |
+
switch ($arg) {
|
572 |
+
case 'help':
|
573 |
+
$this->printUsage();
|
574 |
+
exit(0);
|
575 |
+
case 'version':
|
576 |
+
echo 'PHP_CodeSniffer version '.PHP_CodeSniffer::VERSION.' ('.PHP_CodeSniffer::STABILITY.') ';
|
577 |
+
echo 'by Squiz (http://www.squiz.net)'.PHP_EOL;
|
578 |
+
exit(0);
|
579 |
+
case 'colors':
|
580 |
+
$this->values['colors'] = true;
|
581 |
+
break;
|
582 |
+
case 'no-colors':
|
583 |
+
$this->values['colors'] = false;
|
584 |
+
break;
|
585 |
+
case 'config-set':
|
586 |
+
if (isset($this->_cliArgs[($pos + 1)]) === false
|
587 |
+
|| isset($this->_cliArgs[($pos + 2)]) === false
|
588 |
+
) {
|
589 |
+
echo 'ERROR: Setting a config option requires a name and value'.PHP_EOL.PHP_EOL;
|
590 |
+
$this->printUsage();
|
591 |
+
exit(0);
|
592 |
+
}
|
593 |
+
|
594 |
+
$key = $this->_cliArgs[($pos + 1)];
|
595 |
+
$value = $this->_cliArgs[($pos + 2)];
|
596 |
+
$current = PHP_CodeSniffer::getConfigData($key);
|
597 |
+
|
598 |
+
try {
|
599 |
+
PHP_CodeSniffer::setConfigData($key, $value);
|
600 |
+
} catch (Exception $e) {
|
601 |
+
echo $e->getMessage().PHP_EOL;
|
602 |
+
exit(2);
|
603 |
+
}
|
604 |
+
|
605 |
+
if ($current === null) {
|
606 |
+
echo "Config value \"$key\" added successfully".PHP_EOL;
|
607 |
+
} else {
|
608 |
+
echo "Config value \"$key\" updated successfully; old value was \"$current\"".PHP_EOL;
|
609 |
+
}
|
610 |
+
exit(0);
|
611 |
+
case 'config-delete':
|
612 |
+
if (isset($this->_cliArgs[($pos + 1)]) === false) {
|
613 |
+
echo 'ERROR: Deleting a config option requires the name of the option'.PHP_EOL.PHP_EOL;
|
614 |
+
$this->printUsage();
|
615 |
+
exit(0);
|
616 |
+
}
|
617 |
+
|
618 |
+
$key = $this->_cliArgs[($pos + 1)];
|
619 |
+
$current = PHP_CodeSniffer::getConfigData($key);
|
620 |
+
if ($current === null) {
|
621 |
+
echo "Config value \"$key\" has not been set".PHP_EOL;
|
622 |
+
} else {
|
623 |
+
try {
|
624 |
+
PHP_CodeSniffer::setConfigData($key, null);
|
625 |
+
} catch (Exception $e) {
|
626 |
+
echo $e->getMessage().PHP_EOL;
|
627 |
+
exit(2);
|
628 |
+
}
|
629 |
+
|
630 |
+
echo "Config value \"$key\" removed successfully; old value was \"$current\"".PHP_EOL;
|
631 |
+
}
|
632 |
+
exit(0);
|
633 |
+
case 'config-show':
|
634 |
+
$data = PHP_CodeSniffer::getAllConfigData();
|
635 |
+
$this->printConfigData($data);
|
636 |
+
exit(0);
|
637 |
+
case 'runtime-set':
|
638 |
+
if (isset($this->_cliArgs[($pos + 1)]) === false
|
639 |
+
|| isset($this->_cliArgs[($pos + 2)]) === false
|
640 |
+
) {
|
641 |
+
echo 'ERROR: Setting a runtime config option requires a name and value'.PHP_EOL.PHP_EOL;
|
642 |
+
$this->printUsage();
|
643 |
+
exit(0);
|
644 |
+
}
|
645 |
+
|
646 |
+
$key = $this->_cliArgs[($pos + 1)];
|
647 |
+
$value = $this->_cliArgs[($pos + 2)];
|
648 |
+
$this->_cliArgs[($pos + 1)] = '';
|
649 |
+
$this->_cliArgs[($pos + 2)] = '';
|
650 |
+
PHP_CodeSniffer::setConfigData($key, $value, true);
|
651 |
+
break;
|
652 |
+
default:
|
653 |
+
if (substr($arg, 0, 7) === 'sniffs=') {
|
654 |
+
$sniffs = explode(',', substr($arg, 7));
|
655 |
+
foreach ($sniffs as $sniff) {
|
656 |
+
if (substr_count($sniff, '.') !== 2) {
|
657 |
+
echo 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
|
658 |
+
$this->printUsage();
|
659 |
+
exit(2);
|
660 |
+
}
|
661 |
+
}
|
662 |
+
|
663 |
+
$this->values['sniffs'] = $sniffs;
|
664 |
+
} else if (substr($arg, 0, 8) === 'exclude=') {
|
665 |
+
$sniffs = explode(',', substr($arg, 8));
|
666 |
+
foreach ($sniffs as $sniff) {
|
667 |
+
if (substr_count($sniff, '.') !== 2) {
|
668 |
+
echo 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
|
669 |
+
$this->printUsage();
|
670 |
+
exit(2);
|
671 |
+
}
|
672 |
+
}
|
673 |
+
|
674 |
+
$this->values['exclude'] = $sniffs;
|
675 |
+
} else if (substr($arg, 0, 10) === 'bootstrap=') {
|
676 |
+
$files = explode(',', substr($arg, 10));
|
677 |
+
foreach ($files as $file) {
|
678 |
+
$path = PHP_CodeSniffer::realpath($file);
|
679 |
+
if ($path === false) {
|
680 |
+
echo 'ERROR: The specified bootstrap file "'.$file.'" does not exist'.PHP_EOL.PHP_EOL;
|
681 |
+
$this->printUsage();
|
682 |
+
exit(2);
|
683 |
+
}
|
684 |
+
|
685 |
+
$this->values['bootstrap'][] = $path;
|
686 |
+
}
|
687 |
+
} else if (substr($arg, 0, 10) === 'file-list=') {
|
688 |
+
$fileList = substr($arg, 10);
|
689 |
+
$path = PHP_CodeSniffer::realpath($fileList);
|
690 |
+
if ($path === false) {
|
691 |
+
echo 'ERROR: The specified file list "'.$file.'" does not exist'.PHP_EOL.PHP_EOL;
|
692 |
+
$this->printUsage();
|
693 |
+
exit(2);
|
694 |
+
}
|
695 |
+
|
696 |
+
$files = file($path);
|
697 |
+
foreach ($files as $inputFile) {
|
698 |
+
$inputFile = trim($inputFile);
|
699 |
+
|
700 |
+
// Skip empty lines.
|
701 |
+
if ($inputFile === '') {
|
702 |
+
continue;
|
703 |
+
}
|
704 |
+
|
705 |
+
$realFile = PHP_CodeSniffer::realpath($inputFile);
|
706 |
+
if ($realFile === false) {
|
707 |
+
echo 'ERROR: The specified file "'.$inputFile.'" does not exist'.PHP_EOL.PHP_EOL;
|
708 |
+
$this->printUsage();
|
709 |
+
exit(2);
|
710 |
+
}
|
711 |
+
|
712 |
+
$this->values['files'][] = $realFile;
|
713 |
+
}
|
714 |
+
} else if (substr($arg, 0, 11) === 'stdin-path=') {
|
715 |
+
$this->values['stdinPath'] = PHP_CodeSniffer::realpath(substr($arg, 11));
|
716 |
+
|
717 |
+
// It may not exist and return false instead, so just use whatever they gave us.
|
718 |
+
if ($this->values['stdinPath'] === false) {
|
719 |
+
$this->values['stdinPath'] = trim(substr($arg, 11));
|
720 |
+
}
|
721 |
+
} else if (substr($arg, 0, 12) === 'report-file=') {
|
722 |
+
$this->values['reportFile'] = PHP_CodeSniffer::realpath(substr($arg, 12));
|
723 |
+
|
724 |
+
// It may not exist and return false instead.
|
725 |
+
if ($this->values['reportFile'] === false) {
|
726 |
+
$this->values['reportFile'] = substr($arg, 12);
|
727 |
+
|
728 |
+
$dir = dirname($this->values['reportFile']);
|
729 |
+
if (is_dir($dir) === false) {
|
730 |
+
echo 'ERROR: The specified report file path "'.$this->values['reportFile'].'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
|
731 |
+
$this->printUsage();
|
732 |
+
exit(2);
|
733 |
+
}
|
734 |
+
|
735 |
+
if ($dir === '.') {
|
736 |
+
// Passed report file is a file in the current directory.
|
737 |
+
$this->values['reportFile'] = getcwd().'/'.basename($this->values['reportFile']);
|
738 |
+
} else {
|
739 |
+
if ($dir{0} === '/') {
|
740 |
+
// An absolute path.
|
741 |
+
$dir = PHP_CodeSniffer::realpath($dir);
|
742 |
+
} else {
|
743 |
+
$dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
|
744 |
+
}
|
745 |
+
|
746 |
+
if ($dir !== false) {
|
747 |
+
// Report file path is relative.
|
748 |
+
$this->values['reportFile'] = $dir.'/'.basename($this->values['reportFile']);
|
749 |
+
}
|
750 |
+
}
|
751 |
+
}//end if
|
752 |
+
|
753 |
+
if (is_dir($this->values['reportFile']) === true) {
|
754 |
+
echo 'ERROR: The specified report file path "'.$this->values['reportFile'].'" is a directory'.PHP_EOL.PHP_EOL;
|
755 |
+
$this->printUsage();
|
756 |
+
exit(2);
|
757 |
+
}
|
758 |
+
} else if (substr($arg, 0, 13) === 'report-width=') {
|
759 |
+
$this->values['reportWidth'] = $this->_validateReportWidth(substr($arg, 13));
|
760 |
+
} else if (substr($arg, 0, 7) === 'report='
|
761 |
+
|| substr($arg, 0, 7) === 'report-'
|
762 |
+
) {
|
763 |
+
if ($arg[6] === '-') {
|
764 |
+
// This is a report with file output.
|
765 |
+
$split = strpos($arg, '=');
|
766 |
+
if ($split === false) {
|
767 |
+
$report = substr($arg, 7);
|
768 |
+
$output = null;
|
769 |
+
} else {
|
770 |
+
$report = substr($arg, 7, ($split - 7));
|
771 |
+
$output = substr($arg, ($split + 1));
|
772 |
+
if ($output === false) {
|
773 |
+
$output = null;
|
774 |
+
} else {
|
775 |
+
$dir = dirname($output);
|
776 |
+
if ($dir === '.') {
|
777 |
+
// Passed report file is a filename in the current directory.
|
778 |
+
$output = getcwd().'/'.basename($output);
|
779 |
+
} else {
|
780 |
+
if ($dir{0} === '/') {
|
781 |
+
// An absolute path.
|
782 |
+
$dir = PHP_CodeSniffer::realpath($dir);
|
783 |
+
} else {
|
784 |
+
$dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
|
785 |
+
}
|
786 |
+
|
787 |
+
if ($dir !== false) {
|
788 |
+
// Report file path is relative.
|
789 |
+
$output = $dir.'/'.basename($output);
|
790 |
+
}
|
791 |
+
}
|
792 |
+
}//end if
|
793 |
+
}//end if
|
794 |
+
} else {
|
795 |
+
// This is a single report.
|
796 |
+
$report = substr($arg, 7);
|
797 |
+
$output = null;
|
798 |
+
}//end if
|
799 |
+
|
800 |
+
$this->values['reports'][$report] = $output;
|
801 |
+
} else if (substr($arg, 0, 9) === 'standard=') {
|
802 |
+
$standards = trim(substr($arg, 9));
|
803 |
+
if ($standards !== '') {
|
804 |
+
$this->values['standard'] = explode(',', $standards);
|
805 |
+
}
|
806 |
+
} else if (substr($arg, 0, 11) === 'extensions=') {
|
807 |
+
if (isset($this->values['extensions']) === false) {
|
808 |
+
$this->values['extensions'] = array();
|
809 |
+
}
|
810 |
+
|
811 |
+
$this->values['extensions'] = array_merge($this->values['extensions'], explode(',', substr($arg, 11)));
|
812 |
+
} else if (substr($arg, 0, 9) === 'severity=') {
|
813 |
+
$this->values['errorSeverity'] = (int) substr($arg, 9);
|
814 |
+
$this->values['warningSeverity'] = $this->values['errorSeverity'];
|
815 |
+
} else if (substr($arg, 0, 15) === 'error-severity=') {
|
816 |
+
$this->values['errorSeverity'] = (int) substr($arg, 15);
|
817 |
+
} else if (substr($arg, 0, 17) === 'warning-severity=') {
|
818 |
+
$this->values['warningSeverity'] = (int) substr($arg, 17);
|
819 |
+
} else if (substr($arg, 0, 7) === 'ignore=') {
|
820 |
+
// Split the ignore string on commas, unless the comma is escaped
|
821 |
+
// using 1 or 3 slashes (\, or \\\,).
|
822 |
+
$ignored = preg_split(
|
823 |
+
'/(?<=(?<!\\\\)\\\\\\\\),|(?<!\\\\),/',
|
824 |
+
substr($arg, 7)
|
825 |
+
);
|
826 |
+
foreach ($ignored as $pattern) {
|
827 |
+
$pattern = trim($pattern);
|
828 |
+
if ($pattern === '') {
|
829 |
+
continue;
|
830 |
+
}
|
831 |
+
|
832 |
+
$this->values['ignored'][$pattern] = 'absolute';
|
833 |
+
}
|
834 |
+
} else if (substr($arg, 0, 10) === 'generator=') {
|
835 |
+
$this->values['generator'] = substr($arg, 10);
|
836 |
+
} else if (substr($arg, 0, 9) === 'encoding=') {
|
837 |
+
$this->values['encoding'] = strtolower(substr($arg, 9));
|
838 |
+
} else if (substr($arg, 0, 10) === 'tab-width=') {
|
839 |
+
$this->values['tabWidth'] = (int) substr($arg, 10);
|
840 |
+
} else {
|
841 |
+
if ($this->dieOnUnknownArg === false) {
|
842 |
+
$eqPos = strpos($arg, '=');
|
843 |
+
if ($eqPos === false) {
|
844 |
+
$this->values[$arg] = $arg;
|
845 |
+
} else {
|
846 |
+
$value = substr($arg, ($eqPos + 1));
|
847 |
+
$arg = substr($arg, 0, $eqPos);
|
848 |
+
$this->values[$arg] = $value;
|
849 |
+
}
|
850 |
+
} else {
|
851 |
+
$this->processUnknownArgument('--'.$arg, $pos);
|
852 |
+
}
|
853 |
+
}//end if
|
854 |
+
|
855 |
+
break;
|
856 |
+
}//end switch
|
857 |
+
|
858 |
+
}//end processLongArgument()
|
859 |
+
|
860 |
+
|
861 |
+
/**
|
862 |
+
* Processes an unknown command line argument.
|
863 |
+
*
|
864 |
+
* Assumes all unknown arguments are files and folders to check.
|
865 |
+
*
|
866 |
+
* @param string $arg The command line argument.
|
867 |
+
* @param int $pos The position of the argument on the command line.
|
868 |
+
*
|
869 |
+
* @return void
|
870 |
+
*/
|
871 |
+
public function processUnknownArgument($arg, $pos)
|
872 |
+
{
|
873 |
+
// We don't know about any additional switches; just files.
|
874 |
+
if ($arg{0} === '-') {
|
875 |
+
if ($this->dieOnUnknownArg === false) {
|
876 |
+
return;
|
877 |
+
}
|
878 |
+
|
879 |
+
echo 'ERROR: option "'.$arg.'" not known.'.PHP_EOL.PHP_EOL;
|
880 |
+
$this->printUsage();
|
881 |
+
exit(2);
|
882 |
+
}
|
883 |
+
|
884 |
+
$file = PHP_CodeSniffer::realpath($arg);
|
885 |
+
if (file_exists($file) === false) {
|
886 |
+
if ($this->dieOnUnknownArg === false) {
|
887 |
+
return;
|
888 |
+
}
|
889 |
+
|
890 |
+
echo 'ERROR: The file "'.$arg.'" does not exist.'.PHP_EOL.PHP_EOL;
|
891 |
+
$this->printUsage();
|
892 |
+
exit(2);
|
893 |
+
} else {
|
894 |
+
$this->values['files'][] = $file;
|
895 |
+
}
|
896 |
+
|
897 |
+
}//end processUnknownArgument()
|
898 |
+
|
899 |
+
|
900 |
+
/**
|
901 |
+
* Runs PHP_CodeSniffer over files and directories.
|
902 |
+
*
|
903 |
+
* @param array $values An array of values determined from CLI args.
|
904 |
+
*
|
905 |
+
* @return int The number of error and warning messages shown.
|
906 |
+
* @see getCommandLineValues()
|
907 |
+
*/
|
908 |
+
public function process($values=array())
|
909 |
+
{
|
910 |
+
if (empty($values) === true) {
|
911 |
+
$values = $this->getCommandLineValues();
|
912 |
+
} else {
|
913 |
+
$values = array_merge($this->getDefaults(), $values);
|
914 |
+
$this->values = $values;
|
915 |
+
}
|
916 |
+
|
917 |
+
if ($values['generator'] !== '') {
|
918 |
+
$phpcs = new PHP_CodeSniffer($values['verbosity']);
|
919 |
+
if ($values['standard'] === null) {
|
920 |
+
$values['standard'] = $this->validateStandard(null);
|
921 |
+
}
|
922 |
+
|
923 |
+
foreach ($values['standard'] as $standard) {
|
924 |
+
$phpcs->generateDocs(
|
925 |
+
$standard,
|
926 |
+
$values['sniffs'],
|
927 |
+
$values['generator']
|
928 |
+
);
|
929 |
+
}
|
930 |
+
|
931 |
+
exit(0);
|
932 |
+
}
|
933 |
+
|
934 |
+
// If no standard is supplied, get the default.
|
935 |
+
$values['standard'] = $this->validateStandard($values['standard']);
|
936 |
+
foreach ($values['standard'] as $standard) {
|
937 |
+
if (PHP_CodeSniffer::isInstalledStandard($standard) === false) {
|
938 |
+
// They didn't select a valid coding standard, so help them
|
939 |
+
// out by letting them know which standards are installed.
|
940 |
+
echo 'ERROR: the "'.$standard.'" coding standard is not installed. ';
|
941 |
+
$this->printInstalledStandards();
|
942 |
+
exit(2);
|
943 |
+
}
|
944 |
+
}
|
945 |
+
|
946 |
+
if ($values['explain'] === true) {
|
947 |
+
foreach ($values['standard'] as $standard) {
|
948 |
+
$this->explainStandard($standard);
|
949 |
+
}
|
950 |
+
|
951 |
+
exit(0);
|
952 |
+
}
|
953 |
+
|
954 |
+
$phpcs = new PHP_CodeSniffer($values['verbosity'], null, null, null);
|
955 |
+
$phpcs->setCli($this);
|
956 |
+
$phpcs->initStandard($values['standard'], $values['sniffs'], $values['exclude']);
|
957 |
+
$values = $this->values;
|
958 |
+
|
959 |
+
$phpcs->setTabWidth($values['tabWidth']);
|
960 |
+
$phpcs->setEncoding($values['encoding']);
|
961 |
+
$phpcs->setInteractive($values['interactive']);
|
962 |
+
|
963 |
+
// Set file extensions if they were specified. Otherwise,
|
964 |
+
// let PHP_CodeSniffer decide on the defaults.
|
965 |
+
if (empty($values['extensions']) === false) {
|
966 |
+
$phpcs->setAllowedFileExtensions($values['extensions']);
|
967 |
+
}
|
968 |
+
|
969 |
+
// Set ignore patterns if they were specified.
|
970 |
+
if (empty($values['ignored']) === false) {
|
971 |
+
$ignorePatterns = array_merge($phpcs->getIgnorePatterns(), $values['ignored']);
|
972 |
+
$phpcs->setIgnorePatterns($ignorePatterns);
|
973 |
+
}
|
974 |
+
|
975 |
+
// Set some convenience member vars.
|
976 |
+
if ($values['errorSeverity'] === null) {
|
977 |
+
$this->errorSeverity = PHPCS_DEFAULT_ERROR_SEV;
|
978 |
+
} else {
|
979 |
+
$this->errorSeverity = $values['errorSeverity'];
|
980 |
+
}
|
981 |
+
|
982 |
+
if ($values['warningSeverity'] === null) {
|
983 |
+
$this->warningSeverity = PHPCS_DEFAULT_WARN_SEV;
|
984 |
+
} else {
|
985 |
+
$this->warningSeverity = $values['warningSeverity'];
|
986 |
+
}
|
987 |
+
|
988 |
+
if (empty($values['reports']) === true) {
|
989 |
+
$values['reports']['full'] = $values['reportFile'];
|
990 |
+
$this->values['reports'] = $values['reports'];
|
991 |
+
}
|
992 |
+
|
993 |
+
// Include bootstrap files.
|
994 |
+
foreach ($values['bootstrap'] as $bootstrap) {
|
995 |
+
include $bootstrap;
|
996 |
+
}
|
997 |
+
|
998 |
+
$phpcs->processFiles($values['files'], $values['local']);
|
999 |
+
|
1000 |
+
if (empty($values['files']) === true || $values['stdin'] !== null) {
|
1001 |
+
$fileContents = $values['stdin'];
|
1002 |
+
if ($fileContents === null) {
|
1003 |
+
// Check if they are passing in the file contents.
|
1004 |
+
$handle = fopen('php://stdin', 'r');
|
1005 |
+
stream_set_blocking($handle, true);
|
1006 |
+
$fileContents = stream_get_contents($handle);
|
1007 |
+
fclose($handle);
|
1008 |
+
}
|
1009 |
+
|
1010 |
+
if ($fileContents === '') {
|
1011 |
+
// No files and no content passed in.
|
1012 |
+
echo 'ERROR: You must supply at least one file or directory to process.'.PHP_EOL.PHP_EOL;
|
1013 |
+
$this->printUsage();
|
1014 |
+
exit(2);
|
1015 |
+
} else {
|
1016 |
+
$this->values['stdin'] = $fileContents;
|
1017 |
+
$phpcs->processFile('STDIN', $fileContents);
|
1018 |
+
}
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
// Interactive runs don't require a final report and it doesn't really
|
1022 |
+
// matter what the retun value is because we know it isn't being read
|
1023 |
+
// by a script.
|
1024 |
+
if ($values['interactive'] === true) {
|
1025 |
+
return 0;
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
return $this->printErrorReport(
|
1029 |
+
$phpcs,
|
1030 |
+
$values['reports'],
|
1031 |
+
$values['showSources'],
|
1032 |
+
$values['reportFile'],
|
1033 |
+
$values['reportWidth']
|
1034 |
+
);
|
1035 |
+
|
1036 |
+
}//end process()
|
1037 |
+
|
1038 |
+
|
1039 |
+
/**
|
1040 |
+
* Prints the error report for the run.
|
1041 |
+
*
|
1042 |
+
* Note that this function may actually print multiple reports
|
1043 |
+
* as the user may have specified a number of output formats.
|
1044 |
+
*
|
1045 |
+
* @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing
|
1046 |
+
* the errors.
|
1047 |
+
* @param array $reports A list of reports to print.
|
1048 |
+
* @param bool $showSources TRUE if report should show error sources
|
1049 |
+
* (not used by all reports).
|
1050 |
+
* @param string $reportFile A default file to log report output to.
|
1051 |
+
* @param int $reportWidth How wide the screen reports should be.
|
1052 |
+
*
|
1053 |
+
* @return int The number of error and warning messages shown.
|
1054 |
+
*/
|
1055 |
+
public function printErrorReport(
|
1056 |
+
PHP_CodeSniffer $phpcs,
|
1057 |
+
$reports,
|
1058 |
+
$showSources,
|
1059 |
+
$reportFile,
|
1060 |
+
$reportWidth
|
1061 |
+
) {
|
1062 |
+
if (empty($reports) === true) {
|
1063 |
+
$reports['full'] = $reportFile;
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
$errors = 0;
|
1067 |
+
$warnings = 0;
|
1068 |
+
$toScreen = false;
|
1069 |
+
|
1070 |
+
foreach ($reports as $report => $output) {
|
1071 |
+
if ($output === null) {
|
1072 |
+
$output = $reportFile;
|
1073 |
+
}
|
1074 |
+
|
1075 |
+
if ($reportFile === null) {
|
1076 |
+
$toScreen = true;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
// We don't add errors here because the number of
|
1080 |
+
// errors reported by each report type will always be the
|
1081 |
+
// same, so we really just need 1 number.
|
1082 |
+
$result = $phpcs->reporting->printReport(
|
1083 |
+
$report,
|
1084 |
+
$showSources,
|
1085 |
+
$this->values,
|
1086 |
+
$output,
|
1087 |
+
$reportWidth
|
1088 |
+
);
|
1089 |
+
|
1090 |
+
$errors = $result['errors'];
|
1091 |
+
$warnings = $result['warnings'];
|
1092 |
+
}//end foreach
|
1093 |
+
|
1094 |
+
// Only print timer output if no reports were
|
1095 |
+
// printed to the screen so we don't put additional output
|
1096 |
+
// in something like an XML report. If we are printing to screen,
|
1097 |
+
// the report types would have already worked out who should
|
1098 |
+
// print the timer info.
|
1099 |
+
if (PHP_CODESNIFFER_INTERACTIVE === false
|
1100 |
+
&& ($toScreen === false
|
1101 |
+
|| (($errors + $warnings) === 0 && $this->values['showProgress'] === true))
|
1102 |
+
) {
|
1103 |
+
PHP_CodeSniffer_Reporting::printRunTime();
|
1104 |
+
}
|
1105 |
+
|
1106 |
+
// They should all return the same value, so it
|
1107 |
+
// doesn't matter which return value we end up using.
|
1108 |
+
$ignoreWarnings = PHP_CodeSniffer::getConfigData('ignore_warnings_on_exit');
|
1109 |
+
$ignoreErrors = PHP_CodeSniffer::getConfigData('ignore_errors_on_exit');
|
1110 |
+
|
1111 |
+
$return = ($errors + $warnings);
|
1112 |
+
if ($ignoreErrors !== null) {
|
1113 |
+
$ignoreErrors = (bool) $ignoreErrors;
|
1114 |
+
if ($ignoreErrors === true) {
|
1115 |
+
$return -= $errors;
|
1116 |
+
}
|
1117 |
+
}
|
1118 |
+
|
1119 |
+
if ($ignoreWarnings !== null) {
|
1120 |
+
$ignoreWarnings = (bool) $ignoreWarnings;
|
1121 |
+
if ($ignoreWarnings === true) {
|
1122 |
+
$return -= $warnings;
|
1123 |
+
}
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
return $return;
|
1127 |
+
|
1128 |
+
}//end printErrorReport()
|
1129 |
+
|
1130 |
+
|
1131 |
+
/**
|
1132 |
+
* Convert the passed standards into valid standards.
|
1133 |
+
*
|
1134 |
+
* Checks things like default values and case.
|
1135 |
+
*
|
1136 |
+
* @param array $standards The standards to validate.
|
1137 |
+
*
|
1138 |
+
* @return array
|
1139 |
+
*/
|
1140 |
+
public function validateStandard($standards)
|
1141 |
+
{
|
1142 |
+
if ($standards === null) {
|
1143 |
+
// They did not supply a standard to use.
|
1144 |
+
// Look for a default ruleset in the current directory or higher.
|
1145 |
+
$currentDir = getcwd();
|
1146 |
+
|
1147 |
+
do {
|
1148 |
+
$default = $currentDir.DIRECTORY_SEPARATOR.'phpcs.xml';
|
1149 |
+
if (is_file($default) === true) {
|
1150 |
+
return array($default);
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
$default = $currentDir.DIRECTORY_SEPARATOR.'phpcs.xml.dist';
|
1154 |
+
if (is_file($default) === true) {
|
1155 |
+
return array($default);
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
$lastDir = $currentDir;
|
1159 |
+
$currentDir = dirname($currentDir);
|
1160 |
+
} while ($currentDir !== '.' && $currentDir !== $lastDir);
|
1161 |
+
|
1162 |
+
// Try to get the default from the config system.
|
1163 |
+
$standard = PHP_CodeSniffer::getConfigData('default_standard');
|
1164 |
+
if ($standard === null) {
|
1165 |
+
// Product default standard.
|
1166 |
+
$standard = 'PEAR';
|
1167 |
+
}
|
1168 |
+
|
1169 |
+
return explode(',', $standard);
|
1170 |
+
}//end if
|
1171 |
+
|
1172 |
+
$cleaned = array();
|
1173 |
+
$standards = (array) $standards;
|
1174 |
+
|
1175 |
+
// Check if the standard name is valid, or if the case is invalid.
|
1176 |
+
$installedStandards = PHP_CodeSniffer::getInstalledStandards();
|
1177 |
+
foreach ($standards as $standard) {
|
1178 |
+
foreach ($installedStandards as $validStandard) {
|
1179 |
+
if (strtolower($standard) === strtolower($validStandard)) {
|
1180 |
+
$standard = $validStandard;
|
1181 |
+
break;
|
1182 |
+
}
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
$cleaned[] = $standard;
|
1186 |
+
}
|
1187 |
+
|
1188 |
+
return $cleaned;
|
1189 |
+
|
1190 |
+
}//end validateStandard()
|
1191 |
+
|
1192 |
+
|
1193 |
+
/**
|
1194 |
+
* Prints a report showing the sniffs contained in a standard.
|
1195 |
+
*
|
1196 |
+
* @param string $standard The standard to validate.
|
1197 |
+
*
|
1198 |
+
* @return void
|
1199 |
+
*/
|
1200 |
+
public function explainStandard($standard)
|
1201 |
+
{
|
1202 |
+
$phpcs = new PHP_CodeSniffer();
|
1203 |
+
$phpcs->process(array(), $standard);
|
1204 |
+
$sniffs = $phpcs->getSniffs();
|
1205 |
+
$sniffs = array_keys($sniffs);
|
1206 |
+
sort($sniffs);
|
1207 |
+
|
1208 |
+
ob_start();
|
1209 |
+
|
1210 |
+
$lastStandard = '';
|
1211 |
+
$lastCount = '';
|
1212 |
+
$sniffCount = count($sniffs);
|
1213 |
+
$sniffs[] = '___';
|
1214 |
+
|
1215 |
+
echo PHP_EOL."The $standard standard contains $sniffCount sniffs".PHP_EOL;
|
1216 |
+
|
1217 |
+
ob_start();
|
1218 |
+
|
1219 |
+
foreach ($sniffs as $sniff) {
|
1220 |
+
$parts = explode('_', str_replace('\\', '_', $sniff));
|
1221 |
+
if ($lastStandard === '') {
|
1222 |
+
$lastStandard = $parts[0];
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
if ($parts[0] !== $lastStandard) {
|
1226 |
+
$sniffList = ob_get_contents();
|
1227 |
+
ob_end_clean();
|
1228 |
+
|
1229 |
+
echo PHP_EOL.$lastStandard.' ('.$lastCount.' sniffs)'.PHP_EOL;
|
1230 |
+
echo str_repeat('-', (strlen($lastStandard.$lastCount) + 10));
|
1231 |
+
echo PHP_EOL;
|
1232 |
+
echo $sniffList;
|
1233 |
+
|
1234 |
+
$lastStandard = $parts[0];
|
1235 |
+
$lastCount = 0;
|
1236 |
+
|
1237 |
+
ob_start();
|
1238 |
+
}
|
1239 |
+
|
1240 |
+
echo ' '.$parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5).PHP_EOL;
|
1241 |
+
$lastCount++;
|
1242 |
+
}//end foreach
|
1243 |
+
|
1244 |
+
ob_end_clean();
|
1245 |
+
|
1246 |
+
}//end explainStandard()
|
1247 |
+
|
1248 |
+
|
1249 |
+
/**
|
1250 |
+
* Prints out the gathered config data.
|
1251 |
+
*
|
1252 |
+
* @param array $data The config data to print.
|
1253 |
+
*
|
1254 |
+
* @return void
|
1255 |
+
*/
|
1256 |
+
public function printConfigData($data)
|
1257 |
+
{
|
1258 |
+
$max = 0;
|
1259 |
+
$keys = array_keys($data);
|
1260 |
+
foreach ($keys as $key) {
|
1261 |
+
$len = strlen($key);
|
1262 |
+
if (strlen($key) > $max) {
|
1263 |
+
$max = $len;
|
1264 |
+
}
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
if ($max === 0) {
|
1268 |
+
return;
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
$max += 2;
|
1272 |
+
ksort($data);
|
1273 |
+
foreach ($data as $name => $value) {
|
1274 |
+
echo str_pad($name.': ', $max).$value.PHP_EOL;
|
1275 |
+
}
|
1276 |
+
|
1277 |
+
}//end printConfigData()
|
1278 |
+
|
1279 |
+
|
1280 |
+
/**
|
1281 |
+
* Prints out the usage information for this script.
|
1282 |
+
*
|
1283 |
+
* @return void
|
1284 |
+
*/
|
1285 |
+
public function printUsage()
|
1286 |
+
{
|
1287 |
+
if (PHP_CODESNIFFER_CBF === true) {
|
1288 |
+
$this->printPHPCBFUsage();
|
1289 |
+
} else {
|
1290 |
+
$this->printPHPCSUsage();
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
}//end printUsage()
|
1294 |
+
|
1295 |
+
|
1296 |
+
/**
|
1297 |
+
* Prints out the usage information for PHPCS.
|
1298 |
+
*
|
1299 |
+
* @return void
|
1300 |
+
*/
|
1301 |
+
public function printPHPCSUsage()
|
1302 |
+
{
|
1303 |
+
echo 'Usage: phpcs [-nwlsaepqvi] [-d key[=value]] [--colors] [--no-colors] [--stdin-path=<stdinPath>]'.PHP_EOL;
|
1304 |
+
echo ' [--report=<report>] [--report-file=<reportFile>] [--report-<report>=<reportFile>] ...'.PHP_EOL;
|
1305 |
+
echo ' [--report-width=<reportWidth>] [--generator=<generator>] [--tab-width=<tabWidth>]'.PHP_EOL;
|
1306 |
+
echo ' [--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]'.PHP_EOL;
|
1307 |
+
echo ' [--runtime-set key value] [--config-set key value] [--config-delete key] [--config-show]'.PHP_EOL;
|
1308 |
+
echo ' [--standard=<standard>] [--sniffs=<sniffs>] [--exclude=<sniffs>] [--encoding=<encoding>]'.PHP_EOL;
|
1309 |
+
echo ' [--extensions=<extensions>] [--ignore=<patterns>] [--bootstrap=<bootstrap>]'.PHP_EOL;
|
1310 |
+
echo ' [--file-list=<fileList>] <file> ...'.PHP_EOL;
|
1311 |
+
echo ' Set runtime value (see --config-set) '.PHP_EOL;
|
1312 |
+
echo ' -n Do not print warnings (shortcut for --warning-severity=0)'.PHP_EOL;
|
1313 |
+
echo ' -w Print both warnings and errors (this is the default)'.PHP_EOL;
|
1314 |
+
echo ' -l Local directory only, no recursion'.PHP_EOL;
|
1315 |
+
echo ' -s Show sniff codes in all reports'.PHP_EOL;
|
1316 |
+
echo ' -a Run interactively'.PHP_EOL;
|
1317 |
+
echo ' -e Explain a standard by showing the sniffs it includes'.PHP_EOL;
|
1318 |
+
echo ' -p Show progress of the run'.PHP_EOL;
|
1319 |
+
echo ' -q Quiet mode; disables progress and verbose output'.PHP_EOL;
|
1320 |
+
echo ' -v[v][v] Print verbose output'.PHP_EOL;
|
1321 |
+
echo ' -i Show a list of installed coding standards'.PHP_EOL;
|
1322 |
+
echo ' -d Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
|
1323 |
+
echo ' --help Print this help message'.PHP_EOL;
|
1324 |
+
echo ' --version Print version information'.PHP_EOL;
|
1325 |
+
echo ' --colors Use colors in output'.PHP_EOL;
|
1326 |
+
echo ' --no-colors Do not use colors in output (this is the default)'.PHP_EOL;
|
1327 |
+
echo ' <file> One or more files and/or directories to check'.PHP_EOL;
|
1328 |
+
echo ' <fileList> A file containing a list of files and/or directories to check (one per line)'.PHP_EOL;
|
1329 |
+
echo ' <stdinPath> If processing STDIN, the file path that STDIN will be processed as '.PHP_EOL;
|
1330 |
+
echo ' <bootstrap> A comma separated list of files to run before processing starts'.PHP_EOL;
|
1331 |
+
echo ' <encoding> The encoding of the files being checked (default is iso-8859-1)'.PHP_EOL;
|
1332 |
+
echo ' <extensions> A comma separated list of file extensions to check'.PHP_EOL;
|
1333 |
+
echo ' (extension filtering only valid when checking a directory)'.PHP_EOL;
|
1334 |
+
echo ' The type of the file can be specified using: ext/type'.PHP_EOL;
|
1335 |
+
echo ' e.g., module/php,es/js'.PHP_EOL;
|
1336 |
+
echo ' <generator> Uses either the "HTML", "Markdown" or "Text" generator'.PHP_EOL;
|
1337 |
+
echo ' (forces documentation generation instead of checking)'.PHP_EOL;
|
1338 |
+
echo ' <patterns> A comma separated list of patterns to ignore files and directories'.PHP_EOL;
|
1339 |
+
echo ' <report> Print either the "full", "xml", "checkstyle", "csv"'.PHP_EOL;
|
1340 |
+
echo ' "json", "emacs", "source", "summary", "diff", "junit"'.PHP_EOL;
|
1341 |
+
echo ' "svnblame", "gitblame", "hgblame" or "notifysend" report'.PHP_EOL;
|
1342 |
+
echo ' (the "full" report is printed by default)'.PHP_EOL;
|
1343 |
+
echo ' <reportFile> Write the report to the specified file path'.PHP_EOL;
|
1344 |
+
echo ' <reportWidth> How many columns wide screen reports should be printed'.PHP_EOL;
|
1345 |
+
echo ' or set to "auto" to use current screen width, where supported'.PHP_EOL;
|
1346 |
+
echo ' <sniffs> A comma separated list of sniff codes to include or exclude during checking'.PHP_EOL;
|
1347 |
+
echo ' (all sniffs must be part of the specified standard)'.PHP_EOL;
|
1348 |
+
echo ' <severity> The minimum severity required to display an error or warning'.PHP_EOL;
|
1349 |
+
echo ' <standard> The name or path of the coding standard to use'.PHP_EOL;
|
1350 |
+
echo ' <tabWidth> The number of spaces each tab represents'.PHP_EOL;
|
1351 |
+
|
1352 |
+
}//end printPHPCSUsage()
|
1353 |
+
|
1354 |
+
|
1355 |
+
/**
|
1356 |
+
* Prints out the usage information for PHPCBF.
|
1357 |
+
*
|
1358 |
+
* @return void
|
1359 |
+
*/
|
1360 |
+
public function printPHPCBFUsage()
|
1361 |
+
{
|
1362 |
+
echo 'Usage: phpcbf [-nwli] [-d key[=value]] [--stdin-path=<stdinPath>]'.PHP_EOL;
|
1363 |
+
echo ' [--standard=<standard>] [--sniffs=<sniffs>] [--exclude=<sniffs>] [--suffix=<suffix>]'.PHP_EOL;
|
1364 |
+
echo ' [--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]'.PHP_EOL;
|
1365 |
+
echo ' [--tab-width=<tabWidth>] [--encoding=<encoding>]'.PHP_EOL;
|
1366 |
+
echo ' [--extensions=<extensions>] [--ignore=<patterns>] [--bootstrap=<bootstrap>]'.PHP_EOL;
|
1367 |
+
echo ' [--file-list=<fileList>] <file> ...'.PHP_EOL;
|
1368 |
+
echo ' -n Do not fix warnings (shortcut for --warning-severity=0)'.PHP_EOL;
|
1369 |
+
echo ' -w Fix both warnings and errors (on by default)'.PHP_EOL;
|
1370 |
+
echo ' -l Local directory only, no recursion'.PHP_EOL;
|
1371 |
+
echo ' -i Show a list of installed coding standards'.PHP_EOL;
|
1372 |
+
echo ' -d Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
|
1373 |
+
echo ' --help Print this help message'.PHP_EOL;
|
1374 |
+
echo ' --version Print version information'.PHP_EOL;
|
1375 |
+
echo ' --no-patch Do not make use of the "diff" or "patch" programs'.PHP_EOL;
|
1376 |
+
echo ' <file> One or more files and/or directories to fix'.PHP_EOL;
|
1377 |
+
echo ' <fileList> A file containing a list of files and/or directories to fix (one per line)'.PHP_EOL;
|
1378 |
+
echo ' <stdinPath> If processing STDIN, the file path that STDIN will be processed as '.PHP_EOL;
|
1379 |
+
echo ' <bootstrap> A comma separated list of files to run before processing starts'.PHP_EOL;
|
1380 |
+
echo ' <encoding> The encoding of the files being fixed (default is iso-8859-1)'.PHP_EOL;
|
1381 |
+
echo ' <extensions> A comma separated list of file extensions to fix'.PHP_EOL;
|
1382 |
+
echo ' (extension filtering only valid when checking a directory)'.PHP_EOL;
|
1383 |
+
echo ' The type of the file can be specified using: ext/type'.PHP_EOL;
|
1384 |
+
echo ' e.g., module/php,es/js'.PHP_EOL;
|
1385 |
+
echo ' <patterns> A comma separated list of patterns to ignore files and directories'.PHP_EOL;
|
1386 |
+
echo ' <sniffs> A comma separated list of sniff codes to include or exclude during fixing'.PHP_EOL;
|
1387 |
+
echo ' (all sniffs must be part of the specified standard)'.PHP_EOL;
|
1388 |
+
echo ' <severity> The minimum severity required to fix an error or warning'.PHP_EOL;
|
1389 |
+
echo ' <standard> The name or path of the coding standard to use'.PHP_EOL;
|
1390 |
+
echo ' <suffix> Write modified files to a filename using this suffix'.PHP_EOL;
|
1391 |
+
echo ' ("diff" and "patch" are not used in this mode)'.PHP_EOL;
|
1392 |
+
echo ' <tabWidth> The number of spaces each tab represents'.PHP_EOL;
|
1393 |
+
|
1394 |
+
}//end printPHPCBFUsage()
|
1395 |
+
|
1396 |
+
|
1397 |
+
/**
|
1398 |
+
* Prints out a list of installed coding standards.
|
1399 |
+
*
|
1400 |
+
* @return void
|
1401 |
+
*/
|
1402 |
+
public function printInstalledStandards()
|
1403 |
+
{
|
1404 |
+
$installedStandards = PHP_CodeSniffer::getInstalledStandards();
|
1405 |
+
$numStandards = count($installedStandards);
|
1406 |
+
|
1407 |
+
if ($numStandards === 0) {
|
1408 |
+
echo 'No coding standards are installed.'.PHP_EOL;
|
1409 |
+
} else {
|
1410 |
+
$lastStandard = array_pop($installedStandards);
|
1411 |
+
if ($numStandards === 1) {
|
1412 |
+
echo "The only coding standard installed is $lastStandard".PHP_EOL;
|
1413 |
+
} else {
|
1414 |
+
$standardList = implode(', ', $installedStandards);
|
1415 |
+
$standardList .= ' and '.$lastStandard;
|
1416 |
+
echo 'The installed coding standards are '.$standardList.PHP_EOL;
|
1417 |
+
}
|
1418 |
+
}
|
1419 |
+
|
1420 |
+
}//end printInstalledStandards()
|
1421 |
+
|
1422 |
+
|
1423 |
+
/**
|
1424 |
+
* Set report width based on terminal width.
|
1425 |
+
*
|
1426 |
+
* @param int $width The width of the report. If "auto" then will
|
1427 |
+
* be replaced by the terminal width.
|
1428 |
+
*
|
1429 |
+
* @return int
|
1430 |
+
*/
|
1431 |
+
private function _validateReportWidth($width)
|
1432 |
+
{
|
1433 |
+
if ($width === 'auto'
|
1434 |
+
&& preg_match('|\d+ (\d+)|', shell_exec('stty size 2>&1'), $matches) === 1
|
1435 |
+
) {
|
1436 |
+
return (int) $matches[1];
|
1437 |
+
}
|
1438 |
+
|
1439 |
+
return (int) $width;
|
1440 |
+
|
1441 |
+
}//end _validateReportWidth()
|
1442 |
+
|
1443 |
+
|
1444 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The base class for all PHP_CodeSniffer documentation generators.
|
4 |
+
*
|
5 |
+
* PHP version 5
|
6 |
+
*
|
7 |
+
* @category PHP
|
8 |
+
* @package PHP_CodeSniffer
|
9 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
10 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
11 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
12 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
13 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
14 |
+
*/
|
15 |
+
|
16 |
+
/**
|
17 |
+
* The base class for all PHP_CodeSniffer documentation generators.
|
18 |
+
*
|
19 |
+
* Documentation generators are used to print documentation about code sniffs
|
20 |
+
* in a standard.
|
21 |
+
*
|
22 |
+
* @category PHP
|
23 |
+
* @package PHP_CodeSniffer
|
24 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
25 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
26 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
27 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
28 |
+
* @version Release: @package_version@
|
29 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
30 |
+
*/
|
31 |
+
abstract class PHP_CodeSniffer_DocGenerators_Generator
|
32 |
+
{
|
33 |
+
|
34 |
+
/**
|
35 |
+
* The name of the coding standard we are generating docs for.
|
36 |
+
*
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
private $_standard = '';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* An array of sniffs that we are limiting the generated docs to.
|
43 |
+
*
|
44 |
+
* If this array is empty, docs are generated for all sniffs in the
|
45 |
+
* supplied coding standard.
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
private $_sniffs = array();
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Constructs a PHP_CodeSniffer_DocGenerators_Generator object.
|
54 |
+
*
|
55 |
+
* @param string $standard The name of the coding standard to generate
|
56 |
+
* docs for.
|
57 |
+
* @param array $sniffs An array of sniffs that we are limiting the
|
58 |
+
* generated docs to.
|
59 |
+
*
|
60 |
+
* @see generate()
|
61 |
+
*/
|
62 |
+
public function __construct($standard, array $sniffs=array())
|
63 |
+
{
|
64 |
+
$this->_standard = $standard;
|
65 |
+
$this->_sniffs = $sniffs;
|
66 |
+
|
67 |
+
}//end __construct()
|
68 |
+
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Retrieves the title of the sniff from the DOMNode supplied.
|
72 |
+
*
|
73 |
+
* @param DOMNode $doc The DOMNode object for the sniff.
|
74 |
+
* It represents the "documentation" tag in the XML
|
75 |
+
* standard file.
|
76 |
+
*
|
77 |
+
* @return string
|
78 |
+
*/
|
79 |
+
protected function getTitle(DOMNode $doc)
|
80 |
+
{
|
81 |
+
return $doc->getAttribute('title');
|
82 |
+
|
83 |
+
}//end getTitle()
|
84 |
+
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Retrieves the name of the standard we are generating docs for.
|
88 |
+
*
|
89 |
+
* @return string
|
90 |
+
*/
|
91 |
+
protected function getStandard()
|
92 |
+
{
|
93 |
+
return $this->_standard;
|
94 |
+
|
95 |
+
}//end getStandard()
|
96 |
+
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Generates the documentation for a standard.
|
100 |
+
*
|
101 |
+
* It's probably wise for doc generators to override this method so they
|
102 |
+
* have control over how the docs are produced. Otherwise, the processSniff
|
103 |
+
* method should be overridden to output content for each sniff.
|
104 |
+
*
|
105 |
+
* @return void
|
106 |
+
* @see processSniff()
|
107 |
+
*/
|
108 |
+
public function generate()
|
109 |
+
{
|
110 |
+
$standardFiles = $this->getStandardFiles();
|
111 |
+
|
112 |
+
foreach ($standardFiles as $standard) {
|
113 |
+
$doc = new DOMDocument();
|
114 |
+
$doc->load($standard);
|
115 |
+
$documentation = $doc->getElementsByTagName('documentation')->item(0);
|
116 |
+
$this->processSniff($documentation);
|
117 |
+
}
|
118 |
+
|
119 |
+
}//end generate()
|
120 |
+
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Returns a list of paths to XML standard files for all sniffs in a standard.
|
124 |
+
*
|
125 |
+
* Any sniffs that do not have an XML standard file are obviously not included
|
126 |
+
* in the returned array. If documentation is only being generated for some
|
127 |
+
* sniffs (ie. $this->_sniffs is not empty) then all others sniffs will
|
128 |
+
* be filtered from the results as well.
|
129 |
+
*
|
130 |
+
* @return string[]
|
131 |
+
*/
|
132 |
+
protected function getStandardFiles()
|
133 |
+
{
|
134 |
+
$phpcs = new PHP_CodeSniffer();
|
135 |
+
$phpcs->process(array(), $this->_standard);
|
136 |
+
$sniffs = $phpcs->getSniffs();
|
137 |
+
|
138 |
+
$standardFiles = array();
|
139 |
+
foreach ($sniffs as $className => $sniffClass) {
|
140 |
+
$object = new ReflectionObject($sniffClass);
|
141 |
+
$sniff = $object->getFilename();
|
142 |
+
if (empty($this->_sniffs) === false) {
|
143 |
+
// We are limiting the docs to certain sniffs only, so filter
|
144 |
+
// out any unwanted sniffs.
|
145 |
+
$parts = explode('_', $className);
|
146 |
+
$sniffName = $parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5);
|
147 |
+
if (in_array($sniffName, $this->_sniffs) === false) {
|
148 |
+
continue;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
$standardFile = str_replace(
|
153 |
+
DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR,
|
154 |
+
DIRECTORY_SEPARATOR.'Docs'.DIRECTORY_SEPARATOR,
|
155 |
+
$sniff
|
156 |
+
);
|
157 |
+
$standardFile = str_replace('Sniff.php', 'Standard.xml', $standardFile);
|
158 |
+
|
159 |
+
if (is_file($standardFile) === true) {
|
160 |
+
$standardFiles[] = $standardFile;
|
161 |
+
}
|
162 |
+
}//end foreach
|
163 |
+
|
164 |
+
return $standardFiles;
|
165 |
+
|
166 |
+
}//end getStandardFiles()
|
167 |
+
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Process the documentation for a single sniff.
|
171 |
+
*
|
172 |
+
* Doc generators must implement this function to produce output.
|
173 |
+
*
|
174 |
+
* @param DOMNode $doc The DOMNode object for the sniff.
|
175 |
+
* It represents the "documentation" tag in the XML
|
176 |
+
* standard file.
|
177 |
+
*
|
178 |
+
* @return void
|
179 |
+
* @see generate()
|
180 |
+
*/
|
181 |
+
protected abstract function processSniff(DOMNode $doc);
|
182 |
+
|
183 |
+
|
184 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A doc generator that outputs documentation in one big HTML file.
|
4 |
+
*
|
5 |
+
* PHP version 5
|
6 |
+
*
|
7 |
+
* @category PHP
|
8 |
+
* @package PHP_CodeSniffer
|
9 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
10 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
11 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
12 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
13 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
14 |
+
*/
|
15 |
+
|
16 |
+
if (class_exists('PHP_CodeSniffer_DocGenerators_Generator', true) === false) {
|
17 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_Generator not found');
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* A doc generator that outputs documentation in one big HTML file.
|
22 |
+
*
|
23 |
+
* Output is in one large HTML file and is designed for you to style with
|
24 |
+
* your own stylesheet. It contains a table of contents at the top with anchors
|
25 |
+
* to each sniff.
|
26 |
+
*
|
27 |
+
* @category PHP
|
28 |
+
* @package PHP_CodeSniffer
|
29 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
30 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
31 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
32 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
33 |
+
* @version Release: @package_version@
|
34 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
35 |
+
*/
|
36 |
+
class PHP_CodeSniffer_DocGenerators_HTML extends PHP_CodeSniffer_DocGenerators_Generator
|
37 |
+
{
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Generates the documentation for a standard.
|
42 |
+
*
|
43 |
+
* @return void
|
44 |
+
* @see processSniff()
|
45 |
+
*/
|
46 |
+
public function generate()
|
47 |
+
{
|
48 |
+
ob_start();
|
49 |
+
$this->printHeader();
|
50 |
+
|
51 |
+
$standardFiles = $this->getStandardFiles();
|
52 |
+
$this->printToc($standardFiles);
|
53 |
+
|
54 |
+
foreach ($standardFiles as $standard) {
|
55 |
+
$doc = new DOMDocument();
|
56 |
+
$doc->load($standard);
|
57 |
+
$documentation = $doc->getElementsByTagName('documentation')->item(0);
|
58 |
+
$this->processSniff($documentation);
|
59 |
+
}
|
60 |
+
|
61 |
+
$this->printFooter();
|
62 |
+
|
63 |
+
$content = ob_get_contents();
|
64 |
+
ob_end_clean();
|
65 |
+
|
66 |
+
echo $content;
|
67 |
+
|
68 |
+
}//end generate()
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Print the header of the HTML page.
|
73 |
+
*
|
74 |
+
* @return void
|
75 |
+
*/
|
76 |
+
protected function printHeader()
|
77 |
+
{
|
78 |
+
$standard = $this->getStandard();
|
79 |
+
echo '<html>'.PHP_EOL;
|
80 |
+
echo ' <head>'.PHP_EOL;
|
81 |
+
echo " <title>$standard Coding Standards</title>".PHP_EOL;
|
82 |
+
echo ' <style>
|
83 |
+
body {
|
84 |
+
background-color: #FFFFFF;
|
85 |
+
font-size: 14px;
|
86 |
+
font-family: Arial, Helvetica, sans-serif;
|
87 |
+
color: #000000;
|
88 |
+
}
|
89 |
+
|
90 |
+
h1 {
|
91 |
+
color: #666666;
|
92 |
+
font-size: 20px;
|
93 |
+
font-weight: bold;
|
94 |
+
margin-top: 0px;
|
95 |
+
background-color: #E6E7E8;
|
96 |
+
padding: 20px;
|
97 |
+
border: 1px solid #BBBBBB;
|
98 |
+
}
|
99 |
+
|
100 |
+
h2 {
|
101 |
+
color: #00A5E3;
|
102 |
+
font-size: 16px;
|
103 |
+
font-weight: normal;
|
104 |
+
margin-top: 50px;
|
105 |
+
}
|
106 |
+
|
107 |
+
.code-comparison {
|
108 |
+
width: 100%;
|
109 |
+
}
|
110 |
+
|
111 |
+
.code-comparison td {
|
112 |
+
border: 1px solid #CCCCCC;
|
113 |
+
}
|
114 |
+
|
115 |
+
.code-comparison-title, .code-comparison-code {
|
116 |
+
font-family: Arial, Helvetica, sans-serif;
|
117 |
+
font-size: 12px;
|
118 |
+
color: #000000;
|
119 |
+
vertical-align: top;
|
120 |
+
padding: 4px;
|
121 |
+
width: 50%;
|
122 |
+
background-color: #F1F1F1;
|
123 |
+
line-height: 15px;
|
124 |
+
}
|
125 |
+
|
126 |
+
.code-comparison-code {
|
127 |
+
font-family: Courier;
|
128 |
+
background-color: #F9F9F9;
|
129 |
+
}
|
130 |
+
|
131 |
+
.code-comparison-highlight {
|
132 |
+
background-color: #DDF1F7;
|
133 |
+
border: 1px solid #00A5E3;
|
134 |
+
line-height: 15px;
|
135 |
+
}
|
136 |
+
|
137 |
+
.tag-line {
|
138 |
+
text-align: center;
|
139 |
+
width: 100%;
|
140 |
+
margin-top: 30px;
|
141 |
+
font-size: 12px;
|
142 |
+
}
|
143 |
+
|
144 |
+
.tag-line a {
|
145 |
+
color: #000000;
|
146 |
+
}
|
147 |
+
</style>'.PHP_EOL;
|
148 |
+
echo ' </head>'.PHP_EOL;
|
149 |
+
echo ' <body>'.PHP_EOL;
|
150 |
+
echo " <h1>$standard Coding Standards</h1>".PHP_EOL;
|
151 |
+
|
152 |
+
}//end printHeader()
|
153 |
+
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Print the table of contents for the standard.
|
157 |
+
*
|
158 |
+
* The TOC is just an unordered list of bookmarks to sniffs on the page.
|
159 |
+
*
|
160 |
+
* @param array $standardFiles An array of paths to the XML standard files.
|
161 |
+
*
|
162 |
+
* @return void
|
163 |
+
*/
|
164 |
+
protected function printToc($standardFiles)
|
165 |
+
{
|
166 |
+
echo ' <h2>Table of Contents</h2>'.PHP_EOL;
|
167 |
+
echo ' <ul class="toc">'.PHP_EOL;
|
168 |
+
|
169 |
+
foreach ($standardFiles as $standard) {
|
170 |
+
$doc = new DOMDocument();
|
171 |
+
$doc->load($standard);
|
172 |
+
$documentation = $doc->getElementsByTagName('documentation')->item(0);
|
173 |
+
$title = $this->getTitle($documentation);
|
174 |
+
echo ' <li><a href="#'.str_replace(' ', '-', $title)."\">$title</a></li>".PHP_EOL;
|
175 |
+
}
|
176 |
+
|
177 |
+
echo ' </ul>'.PHP_EOL;
|
178 |
+
|
179 |
+
}//end printToc()
|
180 |
+
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Print the footer of the HTML page.
|
184 |
+
*
|
185 |
+
* @return void
|
186 |
+
*/
|
187 |
+
protected function printFooter()
|
188 |
+
{
|
189 |
+
// Turn off errors so we don't get timezone warnings if people
|
190 |
+
// don't have their timezone set.
|
191 |
+
$errorLevel = error_reporting(0);
|
192 |
+
echo ' <div class="tag-line">';
|
193 |
+
echo 'Documentation generated on '.date('r');
|
194 |
+
echo ' by <a href="https://github.com/squizlabs/PHP_CodeSniffer">PHP_CodeSniffer '.PHP_CodeSniffer::VERSION.'</a>';
|
195 |
+
echo '</div>'.PHP_EOL;
|
196 |
+
error_reporting($errorLevel);
|
197 |
+
|
198 |
+
echo ' </body>'.PHP_EOL;
|
199 |
+
echo '</html>'.PHP_EOL;
|
200 |
+
|
201 |
+
}//end printFooter()
|
202 |
+
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Process the documentation for a single sniff.
|
206 |
+
*
|
207 |
+
* @param DOMNode $doc The DOMNode object for the sniff.
|
208 |
+
* It represents the "documentation" tag in the XML
|
209 |
+
* standard file.
|
210 |
+
*
|
211 |
+
* @return void
|
212 |
+
*/
|
213 |
+
public function processSniff(DOMNode $doc)
|
214 |
+
{
|
215 |
+
$title = $this->getTitle($doc);
|
216 |
+
echo ' <a name="'.str_replace(' ', '-', $title).'" />'.PHP_EOL;
|
217 |
+
echo " <h2>$title</h2>".PHP_EOL;
|
218 |
+
|
219 |
+
foreach ($doc->childNodes as $node) {
|
220 |
+
if ($node->nodeName === 'standard') {
|
221 |
+
$this->printTextBlock($node);
|
222 |
+
} else if ($node->nodeName === 'code_comparison') {
|
223 |
+
$this->printCodeComparisonBlock($node);
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
}//end processSniff()
|
228 |
+
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Print a text block found in a standard.
|
232 |
+
*
|
233 |
+
* @param DOMNode $node The DOMNode object for the text block.
|
234 |
+
*
|
235 |
+
* @return void
|
236 |
+
*/
|
237 |
+
protected function printTextBlock($node)
|
238 |
+
{
|
239 |
+
$content = trim($node->nodeValue);
|
240 |
+
$content = htmlspecialchars($content);
|
241 |
+
|
242 |
+
// Allow em tags only.
|
243 |
+
$content = str_replace('<em>', '<em>', $content);
|
244 |
+
$content = str_replace('</em>', '</em>', $content);
|
245 |
+
|
246 |
+
echo " <p class=\"text\">$content</p>".PHP_EOL;
|
247 |
+
|
248 |
+
}//end printTextBlock()
|
249 |
+
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Print a code comparison block found in a standard.
|
253 |
+
*
|
254 |
+
* @param DOMNode $node The DOMNode object for the code comparison block.
|
255 |
+
*
|
256 |
+
* @return void
|
257 |
+
*/
|
258 |
+
protected function printCodeComparisonBlock($node)
|
259 |
+
{
|
260 |
+
$codeBlocks = $node->getElementsByTagName('code');
|
261 |
+
|
262 |
+
$firstTitle = $codeBlocks->item(0)->getAttribute('title');
|
263 |
+
$first = trim($codeBlocks->item(0)->nodeValue);
|
264 |
+
$first = str_replace('<?php', '<?php', $first);
|
265 |
+
$first = str_replace("\n", '</br>', $first);
|
266 |
+
$first = str_replace(' ', ' ', $first);
|
267 |
+
$first = str_replace('<em>', '<span class="code-comparison-highlight">', $first);
|
268 |
+
$first = str_replace('</em>', '</span>', $first);
|
269 |
+
|
270 |
+
$secondTitle = $codeBlocks->item(1)->getAttribute('title');
|
271 |
+
$second = trim($codeBlocks->item(1)->nodeValue);
|
272 |
+
$second = str_replace('<?php', '<?php', $second);
|
273 |
+
$second = str_replace("\n", '</br>', $second);
|
274 |
+
$second = str_replace(' ', ' ', $second);
|
275 |
+
$second = str_replace('<em>', '<span class="code-comparison-highlight">', $second);
|
276 |
+
$second = str_replace('</em>', '</span>', $second);
|
277 |
+
|
278 |
+
echo ' <table class="code-comparison">'.PHP_EOL;
|
279 |
+
echo ' <tr>'.PHP_EOL;
|
280 |
+
echo " <td class=\"code-comparison-title\">$firstTitle</td>".PHP_EOL;
|
281 |
+
echo " <td class=\"code-comparison-title\">$secondTitle</td>".PHP_EOL;
|
282 |
+
echo ' </tr>'.PHP_EOL;
|
283 |
+
echo ' <tr>'.PHP_EOL;
|
284 |
+
echo " <td class=\"code-comparison-code\">$first</td>".PHP_EOL;
|
285 |
+
echo " <td class=\"code-comparison-code\">$second</td>".PHP_EOL;
|
286 |
+
echo ' </tr>'.PHP_EOL;
|
287 |
+
echo ' </table>'.PHP_EOL;
|
288 |
+
|
289 |
+
}//end printCodeComparisonBlock()
|
290 |
+
|
291 |
+
|
292 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A doc generator that outputs documentation in Markdown format.
|
4 |
+
*
|
5 |
+
* PHP version 5
|
6 |
+
*
|
7 |
+
* @category PHP
|
8 |
+
* @package PHP_CodeSniffer
|
9 |
+
* @author Stefano Kowalke <blueduck@gmx.net>
|
10 |
+
* @copyright 2014 Arroba IT
|
11 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
12 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
13 |
+
*/
|
14 |
+
|
15 |
+
if (class_exists('PHP_CodeSniffer_DocGenerators_Generator', true) === false) {
|
16 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_Generator not found');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* A doc generator that outputs documentation in Markdown format.
|
21 |
+
*
|
22 |
+
* @category PHP
|
23 |
+
* @package PHP_CodeSniffer
|
24 |
+
* @author Stefano Kowalke <blueduck@gmx.net>
|
25 |
+
* @copyright 2014 Arroba IT
|
26 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
27 |
+
* @version Release: @package_version@
|
28 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
29 |
+
*/
|
30 |
+
class PHP_CodeSniffer_DocGenerators_Markdown extends PHP_CodeSniffer_DocGenerators_Generator
|
31 |
+
{
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Generates the documentation for a standard.
|
36 |
+
*
|
37 |
+
* @return void
|
38 |
+
* @see processSniff()
|
39 |
+
*/
|
40 |
+
public function generate()
|
41 |
+
{
|
42 |
+
ob_start();
|
43 |
+
$this->printHeader();
|
44 |
+
|
45 |
+
$standardFiles = $this->getStandardFiles();
|
46 |
+
|
47 |
+
foreach ($standardFiles as $standard) {
|
48 |
+
$doc = new DOMDocument();
|
49 |
+
$doc->load($standard);
|
50 |
+
$documentation = $doc->getElementsByTagName('documentation')->item(0);
|
51 |
+
$this->processSniff($documentation);
|
52 |
+
}
|
53 |
+
|
54 |
+
$this->printFooter();
|
55 |
+
$content = ob_get_contents();
|
56 |
+
ob_end_clean();
|
57 |
+
|
58 |
+
echo $content;
|
59 |
+
|
60 |
+
}//end generate()
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Print the markdown header.
|
65 |
+
*
|
66 |
+
* @return void
|
67 |
+
*/
|
68 |
+
protected function printHeader()
|
69 |
+
{
|
70 |
+
$standard = $this->getStandard();
|
71 |
+
|
72 |
+
echo "# $standard Coding Standard".PHP_EOL;
|
73 |
+
|
74 |
+
}//end printHeader()
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Print the markdown footer.
|
79 |
+
*
|
80 |
+
* @return void
|
81 |
+
*/
|
82 |
+
protected function printFooter()
|
83 |
+
{
|
84 |
+
// Turn off errors so we don't get timezone warnings if people
|
85 |
+
// don't have their timezone set.
|
86 |
+
error_reporting(0);
|
87 |
+
echo 'Documentation generated on '.date('r');
|
88 |
+
echo ' by [PHP_CodeSniffer '.PHP_CodeSniffer::VERSION.'](https://github.com/squizlabs/PHP_CodeSniffer)';
|
89 |
+
|
90 |
+
}//end printFooter()
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Process the documentation for a single sniff.
|
95 |
+
*
|
96 |
+
* @param DOMNode $doc The DOMNode object for the sniff.
|
97 |
+
* It represents the "documentation" tag in the XML
|
98 |
+
* standard file.
|
99 |
+
*
|
100 |
+
* @return void
|
101 |
+
*/
|
102 |
+
protected function processSniff(DOMNode $doc)
|
103 |
+
{
|
104 |
+
$title = $this->getTitle($doc);
|
105 |
+
echo "## $title".PHP_EOL;
|
106 |
+
|
107 |
+
foreach ($doc->childNodes as $node) {
|
108 |
+
if ($node->nodeName === 'standard') {
|
109 |
+
$this->printTextBlock($node);
|
110 |
+
} else if ($node->nodeName === 'code_comparison') {
|
111 |
+
$this->printCodeComparisonBlock($node);
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
}//end processSniff()
|
116 |
+
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Print a text block found in a standard.
|
120 |
+
*
|
121 |
+
* @param DOMNode $node The DOMNode object for the text block.
|
122 |
+
*
|
123 |
+
* @return void
|
124 |
+
*/
|
125 |
+
protected function printTextBlock(DOMNode $node)
|
126 |
+
{
|
127 |
+
$content = trim($node->nodeValue);
|
128 |
+
$content = htmlspecialchars($content);
|
129 |
+
|
130 |
+
$content = str_replace('<em>', '*', $content);
|
131 |
+
$content = str_replace('</em>', '*', $content);
|
132 |
+
|
133 |
+
echo $content.PHP_EOL;
|
134 |
+
|
135 |
+
}//end printTextBlock()
|
136 |
+
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Print a code comparison block found in a standard.
|
140 |
+
*
|
141 |
+
* @param DOMNode $node The DOMNode object for the code comparison block.
|
142 |
+
*
|
143 |
+
* @return void
|
144 |
+
*/
|
145 |
+
protected function printCodeComparisonBlock(DOMNode $node)
|
146 |
+
{
|
147 |
+
$codeBlocks = $node->getElementsByTagName('code');
|
148 |
+
|
149 |
+
$firstTitle = $codeBlocks->item(0)->getAttribute('title');
|
150 |
+
$first = trim($codeBlocks->item(0)->nodeValue);
|
151 |
+
$first = str_replace("\n", "\n ", $first);
|
152 |
+
$first = str_replace('<em>', '', $first);
|
153 |
+
$first = str_replace('</em>', '', $first);
|
154 |
+
|
155 |
+
$secondTitle = $codeBlocks->item(1)->getAttribute('title');
|
156 |
+
$second = trim($codeBlocks->item(1)->nodeValue);
|
157 |
+
$second = str_replace("\n", "\n ", $second);
|
158 |
+
$second = str_replace('<em>', '', $second);
|
159 |
+
$second = str_replace('</em>', '', $second);
|
160 |
+
|
161 |
+
echo ' <table>'.PHP_EOL;
|
162 |
+
echo ' <tr>'.PHP_EOL;
|
163 |
+
echo " <th>$firstTitle</th>".PHP_EOL;
|
164 |
+
echo " <th>$secondTitle</th>".PHP_EOL;
|
165 |
+
echo ' </tr>'.PHP_EOL;
|
166 |
+
echo ' <tr>'.PHP_EOL;
|
167 |
+
echo '<td>'.PHP_EOL.PHP_EOL;
|
168 |
+
echo " $first".PHP_EOL.PHP_EOL;
|
169 |
+
echo '</td>'.PHP_EOL;
|
170 |
+
echo '<td>'.PHP_EOL.PHP_EOL;
|
171 |
+
echo " $second".PHP_EOL.PHP_EOL;
|
172 |
+
echo '</td>'.PHP_EOL;
|
173 |
+
echo ' </tr>'.PHP_EOL;
|
174 |
+
echo ' </table>'.PHP_EOL;
|
175 |
+
|
176 |
+
}//end printCodeComparisonBlock()
|
177 |
+
|
178 |
+
|
179 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php
ADDED
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A doc generator that outputs text-based documentation.
|
4 |
+
*
|
5 |
+
* PHP version 5
|
6 |
+
*
|
7 |
+
* @category PHP
|
8 |
+
* @package PHP_CodeSniffer
|
9 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
10 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
11 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
12 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
13 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
14 |
+
*/
|
15 |
+
|
16 |
+
if (class_exists('PHP_CodeSniffer_DocGenerators_Generator', true) === false) {
|
17 |
+
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_Generator not found');
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* A doc generator that outputs text-based documentation.
|
22 |
+
*
|
23 |
+
* Output is designed to be displayed in a terminal and is wrapped to 100 characters.
|
24 |
+
*
|
25 |
+
* @category PHP
|
26 |
+
* @package PHP_CodeSniffer
|
27 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
28 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
29 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
30 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
31 |
+
* @version Release: @package_version@
|
32 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
33 |
+
*/
|
34 |
+
class PHP_CodeSniffer_DocGenerators_Text extends PHP_CodeSniffer_DocGenerators_Generator
|
35 |
+
{
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Process the documentation for a single sniff.
|
40 |
+
*
|
41 |
+
* @param DOMNode $doc The DOMNode object for the sniff.
|
42 |
+
* It represents the "documentation" tag in the XML
|
43 |
+
* standard file.
|
44 |
+
*
|
45 |
+
* @return void
|
46 |
+
*/
|
47 |
+
public function processSniff(DOMNode $doc)
|
48 |
+
{
|
49 |
+
$this->printTitle($doc);
|
50 |
+
|
51 |
+
foreach ($doc->childNodes as $node) {
|
52 |
+
if ($node->nodeName === 'standard') {
|
53 |
+
$this->printTextBlock($node);
|
54 |
+
} else if ($node->nodeName === 'code_comparison') {
|
55 |
+
$this->printCodeComparisonBlock($node);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
}//end processSniff()
|
60 |
+
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Prints the title area for a single sniff.
|
64 |
+
*
|
65 |
+
* @param DOMNode $doc The DOMNode object for the sniff.
|
66 |
+
* It represents the "documentation" tag in the XML
|
67 |
+
* standard file.
|
68 |
+
*
|
69 |
+
* @return void
|
70 |
+
*/
|
71 |
+
protected function printTitle(DOMNode $doc)
|
72 |
+
{
|
73 |
+
$title = $this->getTitle($doc);
|
74 |
+
$standard = $this->getStandard();
|
75 |
+
|
76 |
+
echo PHP_EOL;
|
77 |
+
echo str_repeat('-', (strlen("$standard CODING STANDARD: $title") + 4));
|
78 |
+
echo strtoupper(PHP_EOL."| $standard CODING STANDARD: $title |".PHP_EOL);
|
79 |
+
echo str_repeat('-', (strlen("$standard CODING STANDARD: $title") + 4));
|
80 |
+
echo PHP_EOL.PHP_EOL;
|
81 |
+
|
82 |
+
}//end printTitle()
|
83 |
+
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Print a text block found in a standard.
|
87 |
+
*
|
88 |
+
* @param DOMNode $node The DOMNode object for the text block.
|
89 |
+
*
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
protected function printTextBlock($node)
|
93 |
+
{
|
94 |
+
$text = trim($node->nodeValue);
|
95 |
+
$text = str_replace('<em>', '*', $text);
|
96 |
+
$text = str_replace('</em>', '*', $text);
|
97 |
+
|
98 |
+
$lines = array();
|
99 |
+
$tempLine = '';
|
100 |
+
$words = explode(' ', $text);
|
101 |
+
|
102 |
+
foreach ($words as $word) {
|
103 |
+
if (strlen($tempLine.$word) >= 99) {
|
104 |
+
if (strlen($tempLine.$word) === 99) {
|
105 |
+
// Adding the extra space will push us to the edge
|
106 |
+
// so we are done.
|
107 |
+
$lines[] = $tempLine.$word;
|
108 |
+
$tempLine = '';
|
109 |
+
} else if (strlen($tempLine.$word) === 100) {
|
110 |
+
// We are already at the edge, so we are done.
|
111 |
+
$lines[] = $tempLine.$word;
|
112 |
+
$tempLine = '';
|
113 |
+
} else {
|
114 |
+
$lines[] = rtrim($tempLine);
|
115 |
+
$tempLine = $word.' ';
|
116 |
+
}
|
117 |
+
} else {
|
118 |
+
$tempLine .= $word.' ';
|
119 |
+
}
|
120 |
+
}//end foreach
|
121 |
+
|
122 |
+
if ($tempLine !== '') {
|
123 |
+
$lines[] = rtrim($tempLine);
|
124 |
+
}
|
125 |
+
|
126 |
+
echo implode(PHP_EOL, $lines).PHP_EOL.PHP_EOL;
|
127 |
+
|
128 |
+
}//end printTextBlock()
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Print a code comparison block found in a standard.
|
133 |
+
*
|
134 |
+
* @param DOMNode $node The DOMNode object for the code comparison block.
|
135 |
+
*
|
136 |
+
* @return void
|
137 |
+
*/
|
138 |
+
protected function printCodeComparisonBlock($node)
|
139 |
+
{
|
140 |
+
$codeBlocks = $node->getElementsByTagName('code');
|
141 |
+
$first = trim($codeBlocks->item(0)->nodeValue);
|
142 |
+
$firstTitle = $codeBlocks->item(0)->getAttribute('title');
|
143 |
+
|
144 |
+
$firstTitleLines = array();
|
145 |
+
$tempTitle = '';
|
146 |
+
$words = explode(' ', $firstTitle);
|
147 |
+
|
148 |
+
foreach ($words as $word) {
|
149 |
+
if (strlen($tempTitle.$word) >= 45) {
|
150 |
+
if (strlen($tempTitle.$word) === 45) {
|
151 |
+
// Adding the extra space will push us to the edge
|
152 |
+
// so we are done.
|
153 |
+
$firstTitleLines[] = $tempTitle.$word;
|
154 |
+
$tempTitle = '';
|
155 |
+
} else if (strlen($tempTitle.$word) === 46) {
|
156 |
+
// We are already at the edge, so we are done.
|
157 |
+
$firstTitleLines[] = $tempTitle.$word;
|
158 |
+
$tempTitle = '';
|
159 |
+
} else {
|
160 |
+
$firstTitleLines[] = $tempTitle;
|
161 |
+
$tempTitle = $word;
|
162 |
+
}
|
163 |
+
} else {
|
164 |
+
$tempTitle .= $word.' ';
|
165 |
+
}
|
166 |
+
}//end foreach
|
167 |
+
|
168 |
+
if ($tempTitle !== '') {
|
169 |
+
$firstTitleLines[] = $tempTitle;
|
170 |
+
}
|
171 |
+
|
172 |
+
$first = str_replace('<em>', '', $first);
|
173 |
+
$first = str_replace('</em>', '', $first);
|
174 |
+
$firstLines = explode("\n", $first);
|
175 |
+
|
176 |
+
$second = trim($codeBlocks->item(1)->nodeValue);
|
177 |
+
$secondTitle = $codeBlocks->item(1)->getAttribute('title');
|
178 |
+
|
179 |
+
$secondTitleLines = array();
|
180 |
+
$tempTitle = '';
|
181 |
+
$words = explode(' ', $secondTitle);
|
182 |
+
|
183 |
+
foreach ($words as $word) {
|
184 |
+
if (strlen($tempTitle.$word) >= 45) {
|
185 |
+
if (strlen($tempTitle.$word) === 45) {
|
186 |
+
// Adding the extra space will push us to the edge
|
187 |
+
// so we are done.
|
188 |
+
$secondTitleLines[] = $tempTitle.$word;
|
189 |
+
$tempTitle = '';
|
190 |
+
} else if (strlen($tempTitle.$word) === 46) {
|
191 |
+
// We are already at the edge, so we are done.
|
192 |
+
$secondTitleLines[] = $tempTitle.$word;
|
193 |
+
$tempTitle = '';
|
194 |
+
} else {
|
195 |
+
$secondTitleLines[] = $tempTitle;
|
196 |
+
$tempTitle = $word;
|
197 |
+
}
|
198 |
+
} else {
|
199 |
+
$tempTitle .= $word.' ';
|
200 |
+
}
|
201 |
+
}//end foreach
|
202 |
+
|
203 |
+
if ($tempTitle !== '') {
|
204 |
+
$secondTitleLines[] = $tempTitle;
|
205 |
+
}
|
206 |
+
|
207 |
+
$second = str_replace('<em>', '', $second);
|
208 |
+
$second = str_replace('</em>', '', $second);
|
209 |
+
$secondLines = explode("\n", $second);
|
210 |
+
|
211 |
+
$maxCodeLines = max(count($firstLines), count($secondLines));
|
212 |
+
$maxTitleLines = max(count($firstTitleLines), count($secondTitleLines));
|
213 |
+
|
214 |
+
echo str_repeat('-', 41);
|
215 |
+
echo ' CODE COMPARISON ';
|
216 |
+
echo str_repeat('-', 42).PHP_EOL;
|
217 |
+
|
218 |
+
for ($i = 0; $i < $maxTitleLines; $i++) {
|
219 |
+
if (isset($firstTitleLines[$i]) === true) {
|
220 |
+
$firstLineText = $firstTitleLines[$i];
|
221 |
+
} else {
|
222 |
+
$firstLineText = '';
|
223 |
+
}
|
224 |
+
|
225 |
+
if (isset($secondTitleLines[$i]) === true) {
|
226 |
+
$secondLineText = $secondTitleLines[$i];
|
227 |
+
} else {
|
228 |
+
$secondLineText = '';
|
229 |
+
}
|
230 |
+
|
231 |
+
echo '| ';
|
232 |
+
echo $firstLineText.str_repeat(' ', (46 - strlen($firstLineText)));
|
233 |
+
echo ' | ';
|
234 |
+
echo $secondLineText.str_repeat(' ', (47 - strlen($secondLineText)));
|
235 |
+
echo ' |'.PHP_EOL;
|
236 |
+
}//end for
|
237 |
+
|
238 |
+
echo str_repeat('-', 100).PHP_EOL;
|
239 |
+
|
240 |
+
for ($i = 0; $i < $maxCodeLines; $i++) {
|
241 |
+
if (isset($firstLines[$i]) === true) {
|
242 |
+
$firstLineText = $firstLines[$i];
|
243 |
+
} else {
|
244 |
+
$firstLineText = '';
|
245 |
+
}
|
246 |
+
|
247 |
+
if (isset($secondLines[$i]) === true) {
|
248 |
+
$secondLineText = $secondLines[$i];
|
249 |
+
} else {
|
250 |
+
$secondLineText = '';
|
251 |
+
}
|
252 |
+
|
253 |
+
echo '| ';
|
254 |
+
echo $firstLineText.str_repeat(' ', (47 - strlen($firstLineText)));
|
255 |
+
echo '| ';
|
256 |
+
echo $secondLineText.str_repeat(' ', (48 - strlen($secondLineText)));
|
257 |
+
echo '|'.PHP_EOL;
|
258 |
+
}//end for
|
259 |
+
|
260 |
+
echo str_repeat('-', 100).PHP_EOL.PHP_EOL;
|
261 |
+
|
262 |
+
}//end printCodeComparisonBlock()
|
263 |
+
|
264 |
+
|
265 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/Exception.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
|
4 |
+
*
|
5 |
+
* PHP version 5
|
6 |
+
*
|
7 |
+
* @category PHP
|
8 |
+
* @package PHP_CodeSniffer
|
9 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
10 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
11 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
12 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
13 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
14 |
+
*/
|
15 |
+
|
16 |
+
/**
|
17 |
+
* An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
|
18 |
+
*
|
19 |
+
* @category PHP
|
20 |
+
* @package PHP_CodeSniffer
|
21 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
22 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
23 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
24 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
25 |
+
* @version Release: @package_version@
|
26 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
27 |
+
*/
|
28 |
+
class PHP_CodeSniffer_Exception extends Exception
|
29 |
+
{
|
30 |
+
|
31 |
+
}//end class
|
vendor/squizlabs/php_codesniffer/CodeSniffer/File.php
ADDED
@@ -0,0 +1,3814 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* A PHP_CodeSniffer_File object represents a PHP source file and the tokens
|
4 |
+
* associated with it.
|
5 |
+
*
|
6 |
+
* PHP version 5
|
7 |
+
*
|
8 |
+
* @category PHP
|
9 |
+
* @package PHP_CodeSniffer
|
10 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
11 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
12 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
13 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
14 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
15 |
+
*/
|
16 |
+
|
17 |
+
/**
|
18 |
+
* A PHP_CodeSniffer_File object represents a PHP source file and the tokens
|
19 |
+
* associated with it.
|
20 |
+
*
|
21 |
+
* It provides a means for traversing the token stack, along with
|
22 |
+
* other token related operations. If a PHP_CodeSniffer_Sniff finds and error or
|
23 |
+
* warning within a PHP_CodeSniffer_File, you can raise an error using the
|
24 |
+
* addError() or addWarning() methods.
|
25 |
+
*
|
26 |
+
* <b>Token Information</b>
|
27 |
+
*
|
28 |
+
* Each token within the stack contains information about itself:
|
29 |
+
*
|
30 |
+
* <code>
|
31 |
+
* array(
|
32 |
+
* 'code' => 301, // the token type code (see token_get_all())
|
33 |
+
* 'content' => 'if', // the token content
|
34 |
+
* 'type' => 'T_IF', // the token name
|
35 |
+
* 'line' => 56, // the line number when the token is located
|
36 |
+
* 'column' => 12, // the column in the line where this token
|
37 |
+
* // starts (starts from 1)
|
38 |
+
* 'level' => 2 // the depth a token is within the scopes open
|
39 |
+
* 'conditions' => array( // a list of scope condition token
|
40 |
+
* // positions => codes that
|
41 |
+
* 2 => 50, // opened the scopes that this token exists
|
42 |
+
* 9 => 353, // in (see conditional tokens section below)
|
43 |
+
* ),
|
44 |
+
* );
|
45 |
+
* </code>
|
46 |
+
*
|
47 |
+
* <b>Conditional Tokens</b>
|
48 |
+
*
|
49 |
+
* In addition to the standard token fields, conditions contain information to
|
50 |
+
* determine where their scope begins and ends:
|
51 |
+
*
|
52 |
+
* <code>
|
53 |
+
* array(
|
54 |
+
* 'scope_condition' => 38, // the token position of the condition
|
55 |
+
* 'scope_opener' => 41, // the token position that started the scope
|
56 |
+
* 'scope_closer' => 70, // the token position that ended the scope
|
57 |
+
* );
|
58 |
+
* </code>
|
59 |
+
*
|
60 |
+
* The condition, the scope opener and the scope closer each contain this
|
61 |
+
* information.
|
62 |
+
*
|
63 |
+
* <b>Parenthesis Tokens</b>
|
64 |
+
*
|
65 |
+
* Each parenthesis token (T_OPEN_PARENTHESIS and T_CLOSE_PARENTHESIS) has a
|
66 |
+
* reference to their opening and closing parenthesis, one being itself, the
|
67 |
+
* other being its opposite.
|
68 |
+
*
|
69 |
+
* <code>
|
70 |
+
* array(
|
71 |
+
* 'parenthesis_opener' => 34,
|
72 |
+
* 'parenthesis_closer' => 40,
|
73 |
+
* );
|
74 |
+
* </code>
|
75 |
+
*
|
76 |
+
* Some tokens can "own" a set of parenthesis. For example a T_FUNCTION token
|
77 |
+
* has parenthesis around its argument list. These tokens also have the
|
78 |
+
* parenthesis_opener and and parenthesis_closer indices. Not all parenthesis
|
79 |
+
* have owners, for example parenthesis used for arithmetic operations and
|
80 |
+
* function calls. The parenthesis tokens that have an owner have the following
|
81 |
+
* auxiliary array indices.
|
82 |
+
*
|
83 |
+
* <code>
|
84 |
+
* array(
|
85 |
+
* 'parenthesis_opener' => 34,
|
86 |
+
* 'parenthesis_closer' => 40,
|
87 |
+
* 'parenthesis_owner' => 33,
|
88 |
+
* );
|
89 |
+
* </code>
|
90 |
+
*
|
91 |
+
* Each token within a set of parenthesis also has an array index
|
92 |
+
* 'nested_parenthesis' which is an array of the
|
93 |
+
* left parenthesis => right parenthesis token positions.
|
94 |
+
*
|
95 |
+
* <code>
|
96 |
+
* 'nested_parenthesis' => array(
|
97 |
+
* 12 => 15
|
98 |
+
* 11 => 14
|
99 |
+
* );
|
100 |
+
* </code>
|
101 |
+
*
|
102 |
+
* <b>Extended Tokens</b>
|
103 |
+
*
|
104 |
+
* PHP_CodeSniffer extends and augments some of the tokens created by
|
105 |
+
* <i>token_get_all()</i>. A full list of these tokens can be seen in the
|
106 |
+
* <i>Tokens.php</i> file.
|
107 |
+
*
|
108 |
+
* @category PHP
|
109 |
+
* @package PHP_CodeSniffer
|
110 |
+
* @author Greg Sherwood <gsherwood@squiz.net>
|
111 |
+
* @author Marc McIntyre <mmcintyre@squiz.net>
|
112 |
+
* @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
113 |
+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
114 |
+
* @version Release: @package_version@
|
115 |
+
* @link http://pear.php.net/package/PHP_CodeSniffer
|
116 |
+
*/
|
117 |
+
class PHP_CodeSniffer_File
|
118 |
+
{
|
119 |
+
|
120 |
+
/**
|
121 |
+
* The absolute path to the file associated with this object.
|
122 |
+
*
|
123 |
+
* @var string
|
124 |
+
*/
|
125 |
+
private $_file = '';
|
126 |
+
|
127 |
+
/**
|
128 |
+
* The EOL character this file uses.
|
129 |
+
*
|
130 |
+
* @var string
|
131 |
+
*/
|
132 |
+
public $eolChar = '';
|
133 |
+
|
134 |
+
/**
|
135 |
+
* The PHP_CodeSniffer object controlling this run.
|
136 |
+
*
|
137 |
+
* @var PHP_CodeSniffer
|
138 |
+
*/
|
139 |
+
public $phpcs = null;
|
140 |
+
|
141 |
+
/**
|
142 |
+
* The Fixer object to control fixing errors.
|
143 |
+
*
|
144 |
+
* @var PHP_CodeSniffer_Fixer
|
145 |
+
*/
|
146 |
+
public $fixer = null;
|
147 |
+
|
148 |
+
/**
|
149 |
+
* The tokenizer being used for this file.
|
150 |
+
*
|
151 |
+
* @var object
|
152 |
+
*/
|
153 |
+
public $tokenizer = null;
|
154 |
+
|
155 |
+
/**
|
156 |
+
* The tokenizer being used for this file.
|
157 |
+
*
|
158 |
+
* @var string
|
159 |
+
*/
|
160 |
+
public $tokenizerType = 'PHP';
|
161 |
+
|
162 |
+
/**
|
163 |
+
* The number of tokens in this file.
|
164 |
+
*
|
165 |
+
* Stored here to save calling count() everywhere.
|
166 |
+
*
|
167 |
+
* @var int
|
168 |
+
*/
|
169 |
+
public $numTokens = 0;
|
170 |
+
|
171 |
+
/**
|
172 |
+
* The tokens stack map.
|
173 |
+
*
|
174 |
+
* Note that the tokens in this array differ in format to the tokens
|
175 |
+
* produced by token_get_all(). Tokens are initially produced with
|
176 |
+
* token_get_all(), then augmented so that it's easier to process them.
|
177 |
+
*
|
178 |
+
* @var array()
|
179 |
+
* @see Tokens.php
|
180 |
+
*/
|
181 |
+
private $_tokens = array();
|
182 |
+
|
183 |
+
/**
|
184 |
+
* The errors raised from PHP_CodeSniffer_Sniffs.
|
185 |
+
*
|
186 |
+
* @var array()
|
187 |
+
* @see getErrors()
|
188 |
+
*/
|
189 |
+
private $_errors = array();
|
190 |
+
|
191 |
+
/**
|
192 |
+
* The warnings raised from PHP_CodeSniffer_Sniffs.
|
193 |
+
*
|
194 |
+
* @var array()
|
195 |
+
* @see getWarnings()
|
196 |
+
*/
|
197 |
+
private $_warnings = array();
|
198 |
+
|
199 |
+
/**
|
200 |
+
* The metrics recorded from PHP_CodeSniffer_Sniffs.
|
201 |
+
*
|
202 |
+
* @var array()
|
203 |
+
* @see getMetrics()
|
204 |
+
*/
|
205 |
+
private $_metrics = array();
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Record the errors and warnings raised.
|
209 |
+
*
|
210 |
+
* @var bool
|
211 |
+
*/
|
212 |
+
private $_recordErrors = true;
|
213 |
+
|
214 |
+
/**
|
215 |
+
* An array of lines that are being ignored.
|
216 |
+
*
|
217 |
+
* @var array()
|
218 |
+
*/
|
219 |
+
private static $_ignoredLines = array();
|
220 |
+
|
221 |
+
/**
|
222 |
+
* An array of sniffs that are being ignored.
|
223 |
+
*
|
224 |
+
* @var array()
|
225 |
+
*/
|
226 |
+
private $_ignoredListeners = array();
|
227 |
+
|
228 |
+
/**
|
229 |
+
* An array of message codes that are being ignored.
|
230 |
+
*
|
231 |
+
* @var array()
|
232 |
+
*/
|
233 |
+
private $_ignoredCodes = array();
|
234 |
+
|
235 |
+
/**
|
236 |
+
* The total number of errors raised.
|
237 |
+
*
|
238 |
+
* @var int
|
239 |
+
*/
|
240 |
+
private $_errorCount = 0;
|
241 |
+
|
242 |
+
/**
|
243 |
+
* The total number of warnings raised.
|
244 |
+
*
|
245 |
+
* @var int
|
246 |
+
*/
|
247 |
+
private $_warningCount = 0;
|
248 |
+
|
249 |
+
/**
|
250 |
+
* The total number of errors/warnings that can be fixed.
|
251 |
+
*
|
252 |
+
* @var int
|
253 |
+
*/
|
254 |
+
private $_fixableCount = 0;
|
255 |
+
|
256 |
+
/**
|
257 |
+
* An array of sniffs listening to this file's processing.
|
258 |
+
*
|
259 |
+
* @var array(PHP_CodeSniffer_Sniff)
|
260 |
+
*/
|
261 |
+
private $_listeners = array();
|
262 |
+
|
263 |
+
/**
|
264 |
+
* The class name of the sniff currently processing the file.
|
265 |
+
*
|
266 |
+
* @var string
|
267 |
+
*/
|
268 |
+
private $_activeListener = '';
|
269 |
+
|
270 |
+
/**
|
271 |
+
* An array of sniffs being processed and how long they took.
|
272 |
+
*
|
273 |
+
* @var array()
|
274 |
+
*/
|
275 |
+
private $_listenerTimes = array();
|
276 |
+
|
277 |
+
/**
|
278 |
+
* An array of rules from the ruleset.xml file.
|
279 |
+
*
|
280 |
+
* This value gets set by PHP_CodeSniffer when the object is created.
|
281 |
+
* It may be empty, indicating that the ruleset does not override
|
282 |
+
* any of the default sniff settings.
|
283 |
+
*
|
284 |
+
* @var array
|
285 |
+
*/
|
286 |
+
protected $ruleset = array();
|
287 |
+
|
288 |
+
|
289 |
+
/**
|
290 |
+
* Constructs a PHP_CodeSniffer_File.
|
291 |
+
*
|
292 |
+
* @param string $file The absolute path to the file to process.
|
293 |
+
* @param array(string) $listeners The initial listeners listening to processing of this file.
|
294 |
+
* to processing of this file.
|
295 |
+
* @param array $ruleset An array of rules from the ruleset.xml file.
|
296 |
+
* ruleset.xml file.
|
297 |
+
* @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object controlling this run.
|
298 |
+
* this run.
|
299 |
+
*
|
300 |
+
* @throws PHP_CodeSniffer_Exception If the register() method does
|
301 |
+
* not return an array.
|
302 |
+
*/
|
303 |
+
public function __construct(
|
304 |
+
$file,
|
305 |
+
array $listeners,
|
306 |
+
array $ruleset,
|
307 |
+
PHP_CodeSniffer $phpcs
|
308 |
+
) {
|
309 |
+
$this->_file = trim($file);
|
310 |
+
$this->_listeners = $listeners;
|
311 |
+
$this->ruleset = $ruleset;
|
312 |
+
$this->phpcs = $phpcs;
|
313 |
+
$this->fixer = new PHP_CodeSniffer_Fixer();
|
314 |
+
|
315 |
+
if (PHP_CODESNIFFER_INTERACTIVE === false) {
|
316 |
+
$cliValues = $phpcs->cli->getCommandLineValues();
|
317 |
+
if (isset($cliValues['showSources']) === true
|
318 |
+
&& $cliValues['showSources'] !== true
|
319 |
+
) {
|
320 |
+
$recordErrors = false;
|
321 |
+
foreach ($cliValues['reports'] as $report => $output) {
|
322 |
+
$reportClass = $phpcs->reporting->factory($report);
|
323 |
+
if (property_exists($reportClass, 'recordErrors') === false
|
324 |
+
|| $reportClass->recordErrors === true
|
325 |
+
) {
|
326 |
+
$recordErrors = true;
|
327 |
+
break;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
$this->_recordErrors = $recordErrors;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
}//end __construct()
|
336 |
+
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Sets the name of the currently active sniff.
|
340 |
+
*
|
341 |
+
* @param string $activeListener The class name of the current sniff.
|
342 |
+
*
|
343 |
+
* @return void
|
344 |
+
*/
|
345 |
+
public function setActiveListener($activeListener)
|
346 |
+
{
|
347 |
+
$this->_activeListener = $activeListener;
|
348 |
+
|
349 |
+
}//end setActiveListener()
|
350 |
+
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Adds a listener to the token stack that listens to the specific tokens.
|
354 |
+
*
|
355 |
+
* When PHP_CodeSniffer encounters on the the tokens specified in $tokens,
|
356 |
+
* it invokes the process method of the sniff.
|
357 |
+
*
|
358 |
+
* @param PHP_CodeSniffer_Sniff $listener The listener to add to the
|
359 |
+
* listener stack.
|
360 |
+
* @param array(int) $tokens The token types the listener wishes to
|
361 |
+
* listen to.
|
362 |
+
*
|
363 |
+
* @return void
|
364 |
+
*/
|
365 |
+
public function addTokenListener(PHP_CodeSniffer_Sniff $listener, array $tokens)
|
366 |
+
{
|
367 |
+
$class = get_class($listener);
|
368 |
+
foreach ($tokens as $token) {
|
369 |
+
if (isset($this->_listeners[$token]) === false) {
|
370 |
+
$this->_listeners[$token] = array();
|
371 |
+
}
|
372 |
+
|
373 |
+
if (isset($this->_listeners[$token][$class]) === false) {
|
374 |
+
$this->_listeners[$token][$class] = $listener;
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
}//end addTokenListener()
|
379 |
+
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Removes a listener from listening from the specified tokens.
|
383 |
+
*
|
384 |
+
* @param PHP_CodeSniffer_Sniff $listener The listener to remove from the
|
385 |
+
* listener stack.
|
386 |
+
* @param array(int) $tokens The token types the listener wishes to
|
387 |
+
* stop listen to.
|
388 |
+
*
|
389 |
+
* @return void
|
390 |
+
*/
|
391 |
+
public function removeTokenListener(
|
392 |
+
PHP_CodeSniffer_Sniff $listener,
|
393 |
+
array $tokens
|
394 |
+
) {
|
395 |
+
$class = get_class($listener);
|
396 |
+
foreach ($tokens as $token) {
|
397 |
+
if (isset($this->_listeners[$token]) === false) {
|
398 |
+
continue;
|
399 |
+
}
|
400 |
+
|
401 |
+
unset($this->_listeners[$token][$class]);
|
402 |
+
}
|
403 |
+
|
404 |
+
}//end removeTokenListener()
|
405 |
+
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Rebuilds the list of listeners to ensure their state is cleared.
|
409 |
+
*
|
410 |
+
* @return void
|
411 |
+
*/
|
412 |
+
public function refreshTokenListeners()
|
413 |
+
{
|
414 |
+
$this->phpcs->populateTokenListeners();
|
415 |
+
$this->_listeners = $this->phpcs->getTokenSniffs();
|
416 |
+
|
417 |
+
}//end refreshTokenListeners()
|
418 |
+
|
419 |
+
|
420 |
+
/**
|
421 |
+
* Returns the token stack for this file.
|
422 |
+
*
|
423 |
+
* @return array
|
424 |
+
*/
|
425 |
+
public function getTokens()
|
426 |
+
{
|
427 |
+
return $this->_tokens;
|
428 |
+
|
429 |
+
}//end getTokens()
|
430 |
+
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Starts the stack traversal and tells listeners when tokens are found.
|
434 |
+
*
|
435 |
+
* @param string $contents The contents to parse. If NULL, the content
|
436 |
+
* is taken from the file system.
|
437 |
+
*
|
438 |
+
* @return void
|
439 |
+
*/
|
440 |
+
public function start($contents=null)
|
441 |
+
{
|
442 |
+
$this->_errors = array();
|
443 |
+
$this->_warnings = array();
|
444 |
+
$this->_errorCount = 0;
|
445 |
+
$this->_warningCount = 0;
|
446 |
+
$this->_fixableCount = 0;
|
447 |
+
|
448 |
+
// Reset the ignored lines because lines numbers may have changed
|
449 |
+
// if we are fixing this file.
|
450 |
+
self::$_ignoredLines = array();
|
451 |
+
|
452 |
+
try {
|
453 |
+
$this->eolChar = self::detectLineEndings($this->_file, $contents);
|
454 |
+
} catch (PHP_CodeSniffer_Exception $e) {
|
455 |
+
$this->addWarning($e->getMessage(), null, 'Internal.DetectLineEndings');
|
456 |
+
return;
|
457 |
+
}
|
458 |
+
|
459 |
+
// If this is standard input, see if a filename was passed in as well.
|
460 |
+
// This is done by including: phpcs_input_file: [file path]
|
461 |
+
// as the first line of content.
|
462 |
+
if ($this->_file === 'STDIN') {
|
463 |
+
$cliValues = $this->phpcs->cli->getCommandLineValues();
|
464 |
+
if ($cliValues['stdinPath'] !== '') {
|
465 |
+
$this->_file = $cliValues['stdinPath'];
|
466 |
+
} else if ($contents !== null && substr($contents, 0, 17) === 'phpcs_input_file:') {
|
467 |
+
$eolPos = strpos($contents, $this->eolChar);
|
468 |
+
$filename = trim(substr($contents, 17, ($eolPos - 17)));
|
469 |
+
$contents = substr($contents, ($eolPos + strlen($this->eolChar)));
|
470 |
+
$this->_file = $filename;
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
$this->_parse($contents);
|
475 |
+
$this->fixer->startFile($this);
|
476 |
+
|
477 |
+
if (PHP_CODESNIFFER_VERBOSITY > 2) {
|
478 |
+
echo "\t*** START TOKEN PROCESSING ***".PHP_EOL;
|
479 |
+
}
|
480 |
+
|
481 |
+
$foundCode = false;
|
482 |
+
$listeners = $this->phpcs->getSniffs();
|
483 |
+
$listenerIgnoreTo = array();
|
484 |
+
$inTests = defined('PHP_CODESNIFFER_IN_TESTS');
|
485 |
+
|
486 |
+
// Foreach of the listeners that have registered to listen for this
|
487 |
+
// token, get them to process it.
|
488 |
+
foreach ($this->_tokens as $stackPtr => $token) {
|
489 |
+
// Check for ignored lines.
|
490 |
+
if ($token['code'] === T_COMMENT
|
491 |
+
|| $token['code'] === T_DOC_COMMENT_TAG
|
492 |
+
|| ($inTests === true && $token['code'] === T_INLINE_HTML)
|
493 |
+
) {
|
494 |
+
if (strpos($token['content'], '@codingStandards') !== false) {
|
495 |
+
if (strpos($token['content'], '@codingStandardsIgnoreFile') !== false) {
|
496 |
+
// Ignoring the whole file, just a little late.
|
497 |
+
$this->_errors = array();
|
498 |
+
$this->_warnings = array();
|
499 |
+
$this->_errorCount = 0;
|
500 |
+
$this->_warningCount = 0;
|
501 |
+
$this->_fixableCount = 0;
|
502 |
+
return;
|
503 |
+
} else if (strpos($token['content'], '@codingStandardsChangeSetting') !== false) {
|
504 |
+
$start = strpos($token['content'], '@codingStandardsChangeSetting');
|
505 |
+
$comment = substr($token['content'], ($start + 30));
|
506 |
+
$parts = explode(' ', $comment);
|
507 |
+
if (count($parts) >= 3
|
508 |
+
&& isset($this->phpcs->sniffCodes[$parts[0]]) === true
|
509 |
+
) {
|
510 |
+
$listenerCode = array_shift($parts);
|
511 |
+
$propertyCode = array_shift($parts);
|
512 |
+
$propertyValue = rtrim(implode(' ', $parts), " */\r\n");
|
513 |
+
$listenerClass = $this->phpcs->sniffCodes[$listenerCode];
|
514 |
+
$this->phpcs->setSniffProperty($listenerClass, $propertyCode, $propertyValue);
|
515 |
+
}
|
516 |
+
}//end if
|
517 |
+
}//end if
|
518 |
+
}//end if
|
519 |
+
|
520 |
+
if (PHP_CODESNIFFER_VERBOSITY > 2) {
|
521 |
+
$type = $token['type'];
|
522 |
+
$content = PHP_CodeSniffer::prepareForOutput($token['content']);
|
523 |
+
echo "\t\tProcess token $stackPtr: $type => $content".PHP_EOL;
|
524 |
+
}
|
525 |
+
|
526 |
+
if ($token['code'] !== T_INLINE_HTML) {
|
527 |
+
$foundCode = true;
|
528 |
+
}
|
529 |
+
|
530 |
+
if (isset($this->_listeners[$token['code']]) === false) {
|
531 |
+
continue;
|
532 |
+
}
|
533 |
+
|
534 |
+
foreach ($this->_listeners[$token['code']] as $listenerData) {
|
535 |
+
if (isset($this->_ignoredListeners[$listenerData['class']]) === true
|
536 |
+
|| (isset($listenerIgnoreTo[$listenerData['class']]) === true
|
537 |
+
&& $listenerIgnoreTo[$listenerData['class']] > $stackPtr)
|
538 |
+
) {
|
539 |
+
// This sniff is ignoring past this token, or the whole file.
|
540 |
+
continue;
|
541 |
+
}
|
542 |
+
|
543 |
+
// Make sure this sniff supports the tokenizer
|
544 |
+
// we are currently using.
|
545 |
+
$class = $listenerData['class'];
|
546 |
+
|
547 |
+
if (isset($listenerData['tokenizers'][$this->tokenizerType]) === false) {
|
548 |
+
continue;
|
549 |
+
}
|
550 |
+
|
551 |
+
// If the file path matches one of our ignore patterns, skip it.
|
552 |
+
// While there is support for a type of each pattern
|
553 |
+
// (absolute or relative) we don't actually support it here.
|
554 |
+
foreach ($listenerData['ignore'] as $pattern) {
|
555 |
+
// We assume a / directory separator, as do the exclude rules
|
556 |
+
// most developers write, so we need a special case for any system
|
557 |
+
// that is different.
|
558 |
+
if (DIRECTORY_SEPARATOR === '\\') {
|
559 |
+
$pattern = str_replace('/', '\\\\', $pattern);
|
560 |
+
}
|
561 |
+
|
562 |
+
$pattern = '`'.$pattern.'`i';
|
563 |
+
if (preg_match($pattern, $this->_file) === 1) {
|
564 |
+
$this->_ignoredListeners[$class] = true;
|
565 |
+
continue(2);
|
566 |
+
}
|
567 |
+
}
|
568 |
+
|
569 |
+
$this->_activeListener = $class;
|
570 |
+
|
571 |
+
if (PHP_CODESNIFFER_VERBOSITY > 2) {
|
572 |
+
$startTime = microtime(true);
|
573 |
+
echo "\t\t\tProcessing ".$this->_activeListener.'... ';
|
574 |
+
}
|
575 |
+
|
576 |
+
$ignoreTo = $listeners[$class]->process($this, $stackPtr);
|
577 |
+
if ($ignoreTo !== null) {
|
578 |
+
$listenerIgnoreTo[$this->_activeListener] = $ignoreTo;
|
579 |
+
}
|
580 |
+
|
581 |
+
if (PHP_CODESNIFFER_VERBOSITY > 2) {
|
582 |
+
$timeTaken = (microtime(true) - $startTime);
|
583 |
+
if (isset($this->_listenerTimes[$this->_activeListener]) === false) {
|
584 |
+
$this->_listenerTimes[$this->_activeListener] = 0;
|
585 |
+
}
|
586 |
+
|
587 |
+
$this->_listenerTimes[$this->_activeListener] += $timeTaken;
|
588 |
+
|
589 |
+
$timeTaken = round(($timeTaken), 4);
|
590 |
+
echo "DONE in $timeTaken seconds".PHP_EOL;
|
591 |
+
}
|
592 |
+
|
593 |
+
$this->_activeListener = '';
|
594 |
+
}//end foreach
|
595 |
+
}//end foreach
|
596 |
+
|
597 |
+
if ($this->_recordErrors === false) {
|
598 |
+
$this->_errors = array();
|
599 |
+
$this->_warnings = array();
|
600 |
+
}
|
601 |
+
|
602 |
+
// If short open tags are off but the file being checked uses
|
603 |
+
// short open tags, the whole content will be inline HTML
|
604 |
+
// and nothing will be checked. So try and handle this case.
|
605 |
+
// We don't show this error for STDIN because we can't be sure the content
|
606 |
+
// actually came directly from the user. It could be something like
|
607 |
+
// refs from a Git pre-push hook.
|
608 |
+
if ($foundCode === false && $this->tokenizerType === 'PHP' && $this->_file !== 'STDIN') {
|
609 |
+
$shortTags = (bool) ini_get('short_open_tag');
|
610 |
+
if ($shortTags === false) {
|
611 |
+
$error = 'No PHP code was found in this file and short open tags are not allowed by this install of PHP. This file may be using short open tags but PHP does not allow them.';
|
612 |
+
$this->addWarning($error, null, 'Internal.NoCodeFound');
|
613 |
+
}
|
614 |
+
}
|
615 |
+
|
616 |
+
if (PHP_CODESNIFFER_VERBOSITY > 2) {
|
617 |
+
echo "\t*** END TOKEN PROCESSING ***".PHP_EOL;
|
618 |
+
echo "\t*** START SNIFF PROCESSING REPORT ***".PHP_EOL;
|
619 |
+
|
620 |
+
asort($this->_listenerTimes, SORT_NUMERIC);
|
621 |
+
$this->_listenerTimes = array_reverse($this->_listenerTimes, true);
|
622 |
+
foreach ($this->_listenerTimes as $listener => $timeTaken) {
|
623 |
+
echo "\t$listener: ".round(($timeTaken), 4).' secs'.PHP_EOL;
|
624 |
+
}
|
625 |
+
|
626 |
+
echo "\t*** END SNIFF PROCESSING REPORT ***".PHP_EOL;
|
627 |
+
}
|
628 |
+
|
629 |
+
}//end start()
|
630 |
+
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Remove vars stored in this file that are no longer required.
|
634 |
+
*
|
635 |
+
* @return void
|
636 |
+
*/
|
637 |
+
public function cleanUp()
|
638 |
+
{
|
639 |
+
$this->_tokens = null;
|
640 |
+
$this->_listeners = null;
|
641 |
+
|
642 |
+
}//end cleanUp()
|
643 |
+
|
644 |
+
|
645 |
+
/**
|
646 |
+
* Tokenizes the file and prepares it for the test run.
|
647 |
+
*
|
648 |
+
* @param string $contents The contents to parse. If NULL, the content
|
649 |
+
* is taken from the file system.
|
650 |
+
*
|
651 |
+
* @return void
|
652 |
+
*/
|
653 |
+
private function _parse($contents=null)
|
654 |
+
{
|
655 |
+
if ($contents === null && empty($this->_tokens) === false) {
|
656 |
+
// File has already been parsed.
|
657 |
+
return;
|
658 |
+
}
|
659 |
+
|
660 |
+
$stdin = false;
|
661 |
+
$cliValues = $this->phpcs->cli->getCommandLineValues();
|
662 |
+
if (empty($cliValues['files']) === true) {
|
663 |
+
$stdin = true;
|
664 |
+
}
|
665 |
+
|
666 |
+
// Determine the tokenizer from the file extension.
|
667 |
+
$fileParts = explode('.', $this->_file);
|
668 |
+
$extension = array_pop($fileParts);
|
669 |
+
if (isset($this->phpcs->allowedFileExtensions[$extension]) === true) {
|
670 |
+
$tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->phpcs->allowedFileExtensions[$extension];
|
671 |
+
$this->tokenizerType = $this->phpcs->allowedFileExtensions[$extension];
|
672 |
+
} else if (isset($this->phpcs->defaultFileExtensions[$extension]) === true) {
|
673 |
+
$tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->phpcs->defaultFileExtensions[$extension];
|
674 |
+
$this->tokenizerType = $this->phpcs->defaultFileExtensions[$extension];
|
675 |
+
} else {
|
676 |
+
// Revert to default.
|
677 |
+
$tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->tokenizerType;
|
678 |
+
}
|
679 |
+
|
680 |
+
$tokenizer = new $tokenizerClass();
|
681 |
+
$this->tokenizer = $tokenizer;
|
682 |
+
|
683 |
+
if ($contents === null) {
|
684 |
+
$contents = file_get_contents($this->_file);
|
685 |
+
}
|
686 |
+
|
687 |
+
try {
|
688 |
+
$tabWidth = null;
|
689 |
+
$encoding = null;
|
690 |
+
if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
|
691 |
+
$cliValues = $this->phpcs->cli->getCommandLineValues();
|
692 |
+
if (isset($cliValues['tabWidth']) === true) {
|
693 |
+
$tabWidth = $cliValues['tabWidth'];
|
694 |
+
}
|
695 |
+
|
696 |
+
if (isset($cliValues['encoding']) === true) {
|
697 |
+
$encoding = $cliValues['encoding'];
|
698 |
+
}
|
699 |
+
}
|
700 |
+
|
701 |
+
$this->_tokens = self::tokenizeString($contents, $tokenizer, $this->eolChar, $tabWidth, $encoding);
|
702 |
+
} catch (PHP_CodeSniffer_Exception $e) {
|
703 |
+
$this->addWarning($e->getMessage(), null, 'Internal.Tokenizer.Exception');
|
704 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
|
705 |
+
echo "[$this->tokenizerType => tokenizer error]... ";
|
706 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
707 |
+
echo PHP_EOL;
|
708 |
+
}
|
709 |
+
}
|
710 |
+
|
711 |
+
return;
|
712 |
+
}//end try
|
713 |
+
|
714 |
+
$this->numTokens = count($this->_tokens);
|
715 |
+
|
716 |
+
// Check for mixed line endings as these can cause tokenizer errors and we
|
717 |
+
// should let the user know that the results they get may be incorrect.
|
718 |
+
// This is done by removing all backslashes, removing the newline char we
|
719 |
+
// detected, then converting newlines chars into text. If any backslashes
|
720 |
+
// are left at the end, we have additional newline chars in use.
|
721 |
+
$contents = str_replace('\\', '', $contents);
|
722 |
+
$contents = str_replace($this->eolChar, '', $contents);
|
723 |
+
$contents = str_replace("\n", '\n', $contents);
|
724 |
+
$contents = str_replace("\r", '\r', $contents);
|
725 |
+
if (strpos($contents, '\\') !== false) {
|
726 |
+
$error = 'File has mixed line endings; this may cause incorrect results';
|
727 |
+
$this->addWarning($error, 0, 'Internal.LineEndings.Mixed');
|
728 |
+
}
|
729 |
+
|
730 |
+
if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
|
731 |
+
if ($this->numTokens === 0) {
|
732 |
+
$numLines = 0;
|
733 |
+
} else {
|
734 |
+
$numLines = $this->_tokens[($this->numTokens - 1)]['line'];
|
735 |
+
}
|
736 |
+
|
737 |
+
echo "[$this->tokenizerType => $this->numTokens tokens in $numLines lines]... ";
|
738 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1) {
|
739 |
+
echo PHP_EOL;
|
740 |
+
}
|
741 |
+
}
|
742 |
+
|
743 |
+
}//end _parse()
|
744 |
+
|
745 |
+
|
746 |
+
/**
|
747 |
+
* Opens a file and detects the EOL character being used.
|
748 |
+
*
|
749 |
+
* @param string $file The full path to the file.
|
750 |
+
* @param string $contents The contents to parse. If NULL, the content
|
751 |
+
* is taken from the file system.
|
752 |
+
*
|
753 |
+
* @return string
|
754 |
+
* @throws PHP_CodeSniffer_Exception If $file could not be opened.
|
755 |
+
*/
|
756 |
+
public static function detectLineEndings($file, $contents=null)
|
757 |
+
{
|
758 |
+
if ($contents === null) {
|
759 |
+
// Determine the newline character being used in this file.
|
760 |
+
// Will be either \r, \r\n or \n.
|
761 |
+
if (is_readable($file) === false) {
|
762 |
+
$error = 'Error opening file; file no longer exists or you do not have access to read the file';
|
763 |
+
throw new PHP_CodeSniffer_Exception($error);
|
764 |
+
} else {
|
765 |
+
$handle = fopen($file, 'r');
|
766 |
+
if ($handle === false) {
|
767 |
+
$error = 'Error opening file; could not auto-detect line endings';
|
768 |
+
throw new PHP_CodeSniffer_Exception($error);
|
769 |
+
}
|
770 |
+
}
|
771 |
+
|
772 |
+
$firstLine = fgets($handle);
|
773 |
+
fclose($handle);
|
774 |
+
|
775 |
+
$eolChar = substr($firstLine, -1);
|
776 |
+
if ($eolChar === "\n") {
|
777 |
+
$secondLastChar = substr($firstLine, -2, 1);
|
778 |
+
if ($secondLastChar === "\r") {
|
779 |
+
$eolChar = "\r\n";
|
780 |
+
}
|
781 |
+
} else if ($eolChar !== "\r") {
|
782 |
+
// Must not be an EOL char at the end of the line.
|
783 |
+
// Probably a one-line file, so assume \n as it really
|
784 |
+
// doesn't matter considering there are no newlines.
|
785 |
+
$eolChar = "\n";
|
786 |
+
}
|
787 |
+
} else {
|
788 |
+
if (preg_match("/\r\n?|\n/", $contents, $matches) !== 1) {
|
789 |
+
// Assuming there are no newlines.
|
790 |
+
$eolChar = "\n";
|
791 |
+
} else {
|
792 |
+
$eolChar = $matches[0];
|
793 |
+
}
|
794 |
+
}//end if
|
795 |
+
|
796 |
+
return $eolChar;
|
797 |
+
|
798 |
+
}//end detectLineEndings()
|
799 |
+
|
800 |
+
|
801 |
+
/**
|
802 |
+
* Records an error against a specific token in the file.
|
803 |
+
*
|
804 |
+
* @param string $error The error message.
|
805 |
+
* @param int $stackPtr The stack position where the error occurred.
|
806 |
+
* @param string $code A violation code unique to the sniff message.
|
807 |
+
* @param array $data Replacements for the error message.
|
808 |
+
* @param int $severity The severity level for this error. A value of 0
|
809 |
+
* will be converted into the default severity level.
|
810 |
+
* @param boolean $fixable Can the error be fixed by the sniff?
|
811 |
+
*
|
812 |
+
* @return boolean
|
813 |
+
*/
|
814 |
+
public function addError(
|
815 |
+
$error,
|
816 |
+
$stackPtr,
|
817 |
+
$code='',
|
818 |
+
$data=array(),
|
819 |
+
$severity=0,
|
820 |
+
$fixable=false
|
821 |
+
) {
|
822 |
+
if ($stackPtr === null) {
|
823 |
+
$line = 1;
|
824 |
+
$column = 1;
|
825 |
+
} else {
|
826 |
+
$line = $this->_tokens[$stackPtr]['line'];
|
827 |
+
$column = $this->_tokens[$stackPtr]['column'];
|
828 |
+
}
|
829 |
+
|
830 |
+
return $this->_addError($error, $line, $column, $code, $data, $severity, $fixable);
|
831 |
+
|
832 |
+
}//end addError()
|
833 |
+
|
834 |
+
|
835 |
+
/**
|
836 |
+
* Records a warning against a specific token in the file.
|
837 |
+
*
|
838 |
+
* @param string $warning The error message.
|
839 |
+
* @param int $stackPtr The stack position where the error occurred.
|
840 |
+
* @param string $code A violation code unique to the sniff message.
|
841 |
+
* @param array $data Replacements for the warning message.
|
842 |
+
* @param int $severity The severity level for this warning. A value of 0
|
843 |
+
* will be converted into the default severity level.
|
844 |
+
* @param boolean $fixable Can the warning be fixed by the sniff?
|
845 |
+
*
|
846 |
+
* @return boolean
|
847 |
+
*/
|
848 |
+
public function addWarning(
|
849 |
+
$warning,
|
850 |
+
$stackPtr,
|
851 |
+
$code='',
|
852 |
+
$data=array(),
|
853 |
+
$severity=0,
|
854 |
+
$fixable=false
|
855 |
+
) {
|
856 |
+
if ($stackPtr === null) {
|
857 |
+
$line = 1;
|
858 |
+
$column = 1;
|
859 |
+
} else {
|
860 |
+
$line = $this->_tokens[$stackPtr]['line'];
|
861 |
+
$column = $this->_tokens[$stackPtr]['column'];
|
862 |
+
}
|
863 |
+
|
864 |
+
return $this->_addWarning($warning, $line, $column, $code, $data, $severity, $fixable);
|
865 |
+
|
866 |
+
}//end addWarning()
|
867 |
+
|
868 |
+
|
869 |
+
/**
|
870 |
+
* Records an error against a specific line in the file.
|
871 |
+
*
|
872 |
+
* @param string $error The error message.
|
873 |
+
* @param int $line The line on which the error occurred.
|
874 |
+
* @param string $code A violation code unique to the sniff message.
|
875 |
+
* @param array $data Replacements for the error message.
|
876 |
+
* @param int $severity The severity level for this error. A value of 0
|
877 |
+
* will be converted into the default severity level.
|
878 |
+
*
|
879 |
+
* @return boolean
|
880 |
+
*/
|
881 |
+
public function addErrorOnLine(
|
882 |
+
$error,
|
883 |
+
$line,
|
884 |
+
$code='',
|
885 |
+
$data=array(),
|
886 |
+
$severity=0
|
887 |
+
) {
|
888 |
+
return $this->_addError($error, $line, 1, $code, $data, $severity, false);
|
889 |
+
|
890 |
+
}//end addErrorOnLine()
|
891 |
+
|
892 |
+
|
893 |
+
/**
|
894 |
+
* Records a warning against a specific token in the file.
|
895 |
+
*
|
896 |
+
* @param string $warning The error message.
|
897 |
+
* @param int $line The line on which the warning occurred.
|
898 |
+
* @param string $code A violation code unique to the sniff message.
|
899 |
+
* @param array $data Replacements for the warning message.
|
900 |
+
* @param int $severity The severity level for this warning. A value of 0
|
901 |
+
* will be converted into the default severity level.
|
902 |
+
*
|
903 |
+
* @return boolean
|
904 |
+
*/
|
905 |
+
public function addWarningOnLine(
|
906 |
+
$warning,
|
907 |
+
$line,
|
908 |
+
$code='',
|
909 |
+
$data=array(),
|
910 |
+
$severity=0
|
911 |
+
) {
|
912 |
+
return $this->_addWarning($warning, $line, 1, $code, $data, $severity, false);
|
913 |
+
|
914 |
+
}//end addWarningOnLine()
|
915 |
+
|
916 |
+
|
917 |
+
/**
|
918 |
+
* Records a fixable error against a specific token in the file.
|
919 |
+
*
|
920 |
+
* Returns true if the error was recorded and should be fixed.
|
921 |
+
*
|
922 |
+
* @param string $error The error message.
|
923 |
+
* @param int $stackPtr The stack position where the error occurred.
|
924 |
+
* @param string $code A violation code unique to the sniff message.
|
925 |
+
* @param array $data Replacements for the error message.
|
926 |
+
* @param int $severity The severity level for this error. A value of 0
|
927 |
+
* will be converted into the default severity level.
|
928 |
+
*
|
929 |
+
* @return boolean
|
930 |
+
*/
|
931 |
+
public function addFixableError(
|
932 |
+
$error,
|
933 |
+
$stackPtr,
|
934 |
+
$code='',
|
935 |
+
$data=array(),
|
936 |
+
$severity=0
|
937 |
+
) {
|
938 |
+
$recorded = $this->addError($error, $stackPtr, $code, $data, $severity, true);
|
939 |
+
if ($recorded === true && $this->fixer->enabled === true) {
|
940 |
+
return true;
|
941 |
+
}
|
942 |
+
|
943 |
+
return false;
|
944 |
+
|
945 |
+
}//end addFixableError()
|
946 |
+
|
947 |
+
|
948 |
+
/**
|
949 |
+
* Records a fixable warning against a specific token in the file.
|
950 |
+
*
|
951 |
+
* Returns true if the warning was recorded and should be fixed.
|
952 |
+
*
|
953 |
+
* @param string $warning The error message.
|
954 |
+
* @param int $stackPtr The stack position where the error occurred.
|
955 |
+
* @param string $code A violation code unique to the sniff message.
|
956 |
+
* @param array $data Replacements for the warning message.
|
957 |
+
* @param int $severity The severity level for this warning. A value of 0
|
958 |
+
* will be converted into the default severity level.
|
959 |
+
*
|
960 |
+
* @return boolean
|
961 |
+
*/
|
962 |
+
public function addFixableWarning(
|
963 |
+
$warning,
|
964 |
+
$stackPtr,
|
965 |
+
$code='',
|
966 |
+
$data=array(),
|
967 |
+
$severity=0
|
968 |
+
) {
|
969 |
+
$recorded = $this->addWarning($warning, $stackPtr, $code, $data, $severity, true);
|
970 |
+
if ($recorded === true && $this->fixer->enabled === true) {
|
971 |
+
return true;
|
972 |
+
}
|
973 |
+
|
974 |
+
return false;
|
975 |
+
|
976 |
+
}//end addFixableWarning()
|
977 |
+
|
978 |
+
|
979 |
+
/**
|
980 |
+
* Adds an error to the error stack.
|
981 |
+
*
|
982 |
+
* @param string $error The error message.
|
983 |
+
* @param int $line The line on which the error occurred.
|
984 |
+
* @param int $column The column at which the error occurred.
|
985 |
+
* @param string $code A violation code unique to the sniff message.
|
986 |
+
* @param array $data Replacements for the error message.
|
987 |
+
* @param int $severity The severity level for this error. A value of 0
|
988 |
+
* will be converted into the default severity level.
|
989 |
+
* @param boolean $fixable Can the error be fixed by the sniff?
|
990 |
+
*
|
991 |
+
* @return boolean
|
992 |
+
*/
|
993 |
+
private function _addError($error, $line, $column, $code, $data, $severity, $fixable)
|
994 |
+
{
|
995 |
+
if (isset(self::$_ignoredLines[$line]) === true) {
|
996 |
+
return false;
|
997 |
+
}
|
998 |
+
|
999 |
+
// Work out which sniff generated the error.
|
1000 |
+
if (substr($code, 0, 9) === 'Internal.') {
|
1001 |
+
// Any internal message.
|
1002 |
+
$sniffCode = $code;
|
1003 |
+
} else {
|
1004 |
+
$parts = explode('_', str_replace('\\', '_', $this->_activeListener));
|
1005 |
+
if (isset($parts[3]) === true) {
|
1006 |
+
$sniff = $parts[0].'.'.$parts[2].'.'.$parts[3];
|
1007 |
+
|
1008 |
+
// Remove "Sniff" from the end.
|
1009 |
+
$sniff = substr($sniff, 0, -5);
|
1010 |
+
} else {
|
1011 |
+
$sniff = 'unknownSniff';
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
$sniffCode = $sniff;
|
1015 |
+
if ($code !== '') {
|
1016 |
+
$sniffCode .= '.'.$code;
|
1017 |
+
}
|
1018 |
+
}//end if
|
1019 |
+
|
1020 |
+
// If we know this sniff code is being ignored for this file, return early.
|
1021 |
+
if (isset($this->_ignoredCodes[$sniffCode]) === true) {
|
1022 |
+
return false;
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
// Make sure this message type has not been set to "warning".
|
1026 |
+
if (isset($this->ruleset[$sniffCode]['type']) === true
|
1027 |
+
&& $this->ruleset[$sniffCode]['type'] === 'warning'
|
1028 |
+
) {
|
1029 |
+
// Pass this off to the warning handler.
|
1030 |
+
return $this->_addWarning($error, $line, $column, $code, $data, $severity, $fixable);
|
1031 |
+
} else if ($this->phpcs->cli->errorSeverity === 0) {
|
1032 |
+
// Don't bother doing any processing as errors are just going to
|
1033 |
+
// be hidden in the reports anyway.
|
1034 |
+
return false;
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
// Make sure we are interested in this severity level.
|
1038 |
+
if (isset($this->ruleset[$sniffCode]['severity']) === true) {
|
1039 |
+
$severity = $this->ruleset[$sniffCode]['severity'];
|
1040 |
+
} else if ($severity === 0) {
|
1041 |
+
$severity = PHPCS_DEFAULT_ERROR_SEV;
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
if ($this->phpcs->cli->errorSeverity > $severity) {
|
1045 |
+
return false;
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
// Make sure we are not ignoring this file.
|
1049 |
+
$patterns = $this->phpcs->getIgnorePatterns($sniffCode);
|
1050 |
+
foreach ($patterns as $pattern => $type) {
|
1051 |
+
// While there is support for a type of each pattern
|
1052 |
+
// (absolute or relative) we don't actually support it here.
|
1053 |
+
$replacements = array(
|
1054 |
+
'\\,' => ',',
|
1055 |
+
'*' => '.*',
|
1056 |
+
);
|
1057 |
+
|
1058 |
+
// We assume a / directory separator, as do the exclude rules
|
1059 |
+
// most developers write, so we need a special case for any system
|
1060 |
+
// that is different.
|
1061 |
+
if (DIRECTORY_SEPARATOR === '\\') {
|
1062 |
+
$replacements['/'] = '\\\\';
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
$pattern = '`'.strtr($pattern, $replacements).'`i';
|
1066 |
+
if (preg_match($pattern, $this->_file) === 1) {
|
1067 |
+
$this->_ignoredCodes[$sniffCode] = true;
|
1068 |
+
return false;
|
1069 |
+
}
|
1070 |
+
}//end foreach
|
1071 |
+
|
1072 |
+
$this->_errorCount++;
|
1073 |
+
if ($fixable === true) {
|
1074 |
+
$this->_fixableCount++;
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
if ($this->_recordErrors === false) {
|
1078 |
+
if (isset($this->_errors[$line]) === false) {
|
1079 |
+
$this->_errors[$line] = 0;
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
$this->_errors[$line]++;
|
1083 |
+
return true;
|
1084 |
+
}
|
1085 |
+
|
1086 |
+
// Work out the error message.
|
1087 |
+
if (isset($this->ruleset[$sniffCode]['message']) === true) {
|
1088 |
+
$error = $this->ruleset[$sniffCode]['message'];
|
1089 |
+
}
|
1090 |
+
|
1091 |
+
if (empty($data) === true) {
|
1092 |
+
$message = $error;
|
1093 |
+
} else {
|
1094 |
+
$message = vsprintf($error, $data);
|
1095 |
+
}
|
1096 |
+
|
1097 |
+
if (isset($this->_errors[$line]) === false) {
|
1098 |
+
$this->_errors[$line] = array();
|
1099 |
+
}
|
1100 |
+
|
1101 |
+
if (isset($this->_errors[$line][$column]) === false) {
|
1102 |
+
$this->_errors[$line][$column] = array();
|
1103 |
+
}
|
1104 |
+
|
1105 |
+
$this->_errors[$line][$column][] = array(
|
1106 |
+
'message' => $message,
|
1107 |
+
'source' => $sniffCode,
|
1108 |
+
'severity' => $severity,
|
1109 |
+
'fixable' => $fixable,
|
1110 |
+
);
|
1111 |
+
|
1112 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1
|
1113 |
+
&& $this->fixer->enabled === true
|
1114 |
+
&& $fixable === true
|
1115 |
+
) {
|
1116 |
+
@ob_end_clean();
|
1117 |
+
echo "\tE: [Line $line] $message ($sniffCode)".PHP_EOL;
|
1118 |
+
ob_start();
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
return true;
|
1122 |
+
|
1123 |
+
}//end _addError()
|
1124 |
+
|
1125 |
+
|
1126 |
+
/**
|
1127 |
+
* Adds an warning to the warning stack.
|
1128 |
+
*
|
1129 |
+
* @param string $warning The error message.
|
1130 |
+
* @param int $line The line on which the warning occurred.
|
1131 |
+
* @param int $column The column at which the warning occurred.
|
1132 |
+
* @param string $code A violation code unique to the sniff message.
|
1133 |
+
* @param array $data Replacements for the warning message.
|
1134 |
+
* @param int $severity The severity level for this warning. A value of 0
|
1135 |
+
* will be converted into the default severity level.
|
1136 |
+
* @param boolean $fixable Can the warning be fixed by the sniff?
|
1137 |
+
*
|
1138 |
+
* @return boolean
|
1139 |
+
*/
|
1140 |
+
private function _addWarning($warning, $line, $column, $code, $data, $severity, $fixable)
|
1141 |
+
{
|
1142 |
+
if (isset(self::$_ignoredLines[$line]) === true) {
|
1143 |
+
return false;
|
1144 |
+
}
|
1145 |
+
|
1146 |
+
// Work out which sniff generated the warning.
|
1147 |
+
if (substr($code, 0, 9) === 'Internal.') {
|
1148 |
+
// Any internal message.
|
1149 |
+
$sniffCode = $code;
|
1150 |
+
} else {
|
1151 |
+
$parts = explode('_', str_replace('\\', '_', $this->_activeListener));
|
1152 |
+
if (isset($parts[3]) === true) {
|
1153 |
+
$sniff = $parts[0].'.'.$parts[2].'.'.$parts[3];
|
1154 |
+
|
1155 |
+
// Remove "Sniff" from the end.
|
1156 |
+
$sniff = substr($sniff, 0, -5);
|
1157 |
+
} else {
|
1158 |
+
$sniff = 'unknownSniff';
|
1159 |
+
}
|
1160 |
+
|
1161 |
+
$sniffCode = $sniff;
|
1162 |
+
if ($code !== '') {
|
1163 |
+
$sniffCode .= '.'.$code;
|
1164 |
+
}
|
1165 |
+
}//end if
|
1166 |
+
|
1167 |
+
// If we know this sniff code is being ignored for this file, return early.
|
1168 |
+
if (isset($this->_ignoredCodes[$sniffCode]) === true) {
|
1169 |
+
return false;
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
// Make sure this message type has not been set to "error".
|
1173 |
+
if (isset($this->ruleset[$sniffCode]['type']) === true
|
1174 |
+
&& $this->ruleset[$sniffCode]['type'] === 'error'
|
1175 |
+
) {
|
1176 |
+
// Pass this off to the error handler.
|
1177 |
+
return $this->_addError($warning, $line, $column, $code, $data, $severity, $fixable);
|
1178 |
+
} else if ($this->phpcs->cli->warningSeverity === 0) {
|
1179 |
+
// Don't bother doing any processing as warnings are just going to
|
1180 |
+
// be hidden in the reports anyway.
|
1181 |
+
return false;
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
// Make sure we are interested in this severity level.
|
1185 |
+
if (isset($this->ruleset[$sniffCode]['severity']) === true) {
|
1186 |
+
$severity = $this->ruleset[$sniffCode]['severity'];
|
1187 |
+
} else if ($severity === 0) {
|
1188 |
+
$severity = PHPCS_DEFAULT_WARN_SEV;
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
if ($this->phpcs->cli->warningSeverity > $severity) {
|
1192 |
+
return false;
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
// Make sure we are not ignoring this file.
|
1196 |
+
$patterns = $this->phpcs->getIgnorePatterns($sniffCode);
|
1197 |
+
foreach ($patterns as $pattern => $type) {
|
1198 |
+
// While there is support for a type of each pattern
|
1199 |
+
// (absolute or relative) we don't actually support it here.
|
1200 |
+
$replacements = array(
|
1201 |
+
'\\,' => ',',
|
1202 |
+
'*' => '.*',
|
1203 |
+
);
|
1204 |
+
|
1205 |
+
// We assume a / directory separator, as do the exclude rules
|
1206 |
+
// most developers write, so we need a special case for any system
|
1207 |
+
// that is different.
|
1208 |
+
if (DIRECTORY_SEPARATOR === '\\') {
|
1209 |
+
$replacements['/'] = '\\\\';
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
$pattern = '`'.strtr($pattern, $replacements).'`i';
|
1213 |
+
if (preg_match($pattern, $this->_file) === 1) {
|
1214 |
+
$this->_ignoredCodes[$sniffCode] = true;
|
1215 |
+
return false;
|
1216 |
+
}
|
1217 |
+
}//end foreach
|
1218 |
+
|
1219 |
+
$this->_warningCount++;
|
1220 |
+
if ($fixable === true) {
|
1221 |
+
$this->_fixableCount++;
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
if ($this->_recordErrors === false) {
|
1225 |
+
if (isset($this->_warnings[$line]) === false) {
|
1226 |
+
$this->_warnings[$line] = 0;
|
1227 |
+
}
|
1228 |
+
|
1229 |
+
$this->_warnings[$line]++;
|
1230 |
+
return true;
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
// Work out the warning message.
|
1234 |
+
if (isset($this->ruleset[$sniffCode]['message']) === true) {
|
1235 |
+
$warning = $this->ruleset[$sniffCode]['message'];
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
if (empty($data) === true) {
|
1239 |
+
$message = $warning;
|
1240 |
+
} else {
|
1241 |
+
$message = vsprintf($warning, $data);
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
if (isset($this->_warnings[$line]) === false) {
|
1245 |
+
$this->_warnings[$line] = array();
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
if (isset($this->_warnings[$line][$column]) === false) {
|
1249 |
+
$this->_warnings[$line][$column] = array();
|
1250 |
+
}
|
1251 |
+
|
1252 |
+
$this->_warnings[$line][$column][] = array(
|
1253 |
+
'message' => $message,
|
1254 |
+
'source' => $sniffCode,
|
1255 |
+
'severity' => $severity,
|
1256 |
+
'fixable' => $fixable,
|
1257 |
+
);
|
1258 |
+
|
1259 |
+
if (PHP_CODESNIFFER_VERBOSITY > 1
|
1260 |
+
&& $this->fixer->enabled === true
|
1261 |
+
&& $fixable === true
|
1262 |
+
) {
|
1263 |
+
@ob_end_clean();
|
1264 |
+
echo "\tW: $message ($sniffCode)".PHP_EOL;
|
1265 |
+
ob_start();
|
1266 |
+
}
|
1267 |
+
|
1268 |
+
return true;
|
1269 |
+
|
1270 |
+
}//end _addWarning()
|
1271 |
+
|
1272 |
+
|
1273 |
+
/**
|
1274 |
+
* Adds an warning to the warning stack.
|
1275 |
+
*
|
1276 |
+
* @param int $stackPtr The stack position where the metric was recorded.
|
1277 |
+
* @param string $metric The name of the metric being recorded.
|
1278 |
+
* @param string $value The value of the metric being recorded.
|
1279 |
+
*
|
1280 |
+
* @return boolean
|
1281 |
+
*/
|
1282 |
+
public function recordMetric($stackPtr, $metric, $value)
|
1283 |
+
{
|
1284 |
+
if (isset($this->_metrics[$metric]) === false) {
|
1285 |
+
$this->_metrics[$metric] = array(
|
1286 |
+
'values' => array(
|
1287 |
+
$value => array($stackPtr),
|
1288 |
+
),
|
1289 |
+
);
|
1290 |
+
} else {
|
1291 |
+
if (isset($this->_metrics[$metric]['values'][$value]) === false) {
|
1292 |
+
$this->_metrics[$metric]['values'][$value] = array($stackPtr);
|
1293 |
+
} else {
|
1294 |
+
$this->_metrics[$metric]['values'][$value][] = $stackPtr;
|
1295 |
+
}
|
1296 |
+
}
|
1297 |
+
|
1298 |
+
return true;
|
1299 |
+
|
1300 |
+
}//end recordMetric()
|
1301 |
+
|
1302 |
+
|
1303 |
+
/**
|
1304 |
+
* Returns the number of errors raised.
|
1305 |
+
*
|
1306 |
+
* @return int
|
1307 |
+
*/
|
1308 |
+
public function getErrorCount()
|
1309 |
+
{
|
1310 |
+
return $this->_errorCount;
|
1311 |
+
|
1312 |
+
}//end getErrorCount()
|
1313 |
+
|
1314 |
+
|
1315 |
+
/**
|
1316 |
+
* Returns the number of warnings raised.
|
1317 |
+
*
|
1318 |
+
* @return int
|
1319 |
+
*/
|
1320 |
+
public function getWarningCount()
|
1321 |
+
{
|
1322 |
+
return $this->_warningCount;
|
1323 |
+
|
1324 |
+
}//end getWarningCount()
|
1325 |
+
|
1326 |
+
|
1327 |
+
/**
|
1328 |
+
* Returns the number of successes recorded.
|
1329 |
+
*
|
1330 |
+
* @return int
|
1331 |
+
*/
|
1332 |
+
public function getSuccessCount()
|
1333 |
+
{
|
1334 |
+
return $this->_successCount;
|
1335 |
+
|
1336 |
+
}//end getSuccessCount()
|
1337 |
+
|
1338 |
+
|
1339 |
+
/**
|
1340 |
+
* Returns the number of fixable errors/warnings raised.
|
1341 |
+
*
|
1342 |
+
* @return int
|
1343 |
+
*/
|
1344 |
+
public function getFixableCount()
|
1345 |
+
{
|
1346 |
+
return $this->_fixableCount;
|
1347 |
+
|
1348 |
+
}//end getFixableCount()
|
1349 |
+
|
1350 |
+
|
1351 |
+
/**
|
1352 |
+
* Returns the list of ignored lines.
|
1353 |
+
*
|
1354 |
+
* @return array
|
1355 |
+
*/
|
1356 |
+
public function getIgnoredLines()
|
1357 |
+
{
|
1358 |
+
return self::$_ignoredLines;
|
1359 |
+
|
1360 |
+
}//end getIgnoredLines()
|
1361 |
+
|
1362 |
+
|
1363 |
+
/**
|
1364 |
+
* Returns the errors raised from processing this file.
|
1365 |
+
*
|
1366 |
+
* @return array
|
1367 |
+
*/
|
1368 |
+
public function getErrors()
|
1369 |
+
{
|
1370 |
+
return $this->_errors;
|
1371 |
+
|
1372 |
+
}//end getErrors()
|
1373 |
+
|
1374 |
+
|
1375 |
+
/**
|
1376 |
+
* Returns the warnings raised from processing this file.
|
1377 |
+
*
|
1378 |
+
* @return array
|
1379 |
+
*/
|
1380 |
+
public function getWarnings()
|
1381 |
+
{
|
1382 |
+
return $this->_warnings;
|
1383 |
+
|
1384 |
+
}//end getWarnings()
|
1385 |
+
|
1386 |
+
|
1387 |
+
/**
|
1388 |
+
* Returns the metrics found while processing this file.
|
1389 |
+
*
|
1390 |
+
* @return array
|
1391 |
+
*/
|
1392 |
+
public function getMetrics()
|
1393 |
+
{
|
1394 |
+
return $this->_metrics;
|
1395 |
+
|
1396 |
+
}//end getMetrics()
|
1397 |
+
|
1398 |
+
|
1399 |
+
/**
|
1400 |
+
* Returns the absolute filename of this file.
|
1401 |
+
*
|
1402 |
+
* @return string
|
1403 |
+
*/
|
1404 |
+
public function getFilename()
|
1405 |
+
{
|
1406 |
+
return $this->_file;
|
1407 |
+
|
1408 |
+
}//end getFilename()
|
1409 |
+
|
1410 |
+
|
1411 |
+
/**
|
1412 |
+
* Creates an array of tokens when given some PHP code.
|
1413 |
+
*
|
1414 |
+
* Starts by using token_get_all() but does a lot of extra processing
|
1415 |
+
* to insert information about the context of the token.
|
1416 |
+
*
|
1417 |
+
* @param string $string The string to tokenize.
|
1418 |
+
* @param object $tokenizer A tokenizer class to use to tokenize the string.
|
1419 |
+
* @param string $eolChar The EOL character to use for splitting strings.
|
1420 |
+
* @param int $tabWidth The number of spaces each tab respresents.
|
1421 |
+
* @param string $encoding The charset of the sniffed file.
|
1422 |
+
*
|
1423 |
+
* @throws PHP_CodeSniffer_Exception If the file cannot be processed.
|
1424 |
+
* @return array
|
1425 |
+
*/
|
1426 |
+
public static function tokenizeString($string, $tokenizer, $eolChar='\n', $tabWidth=null, $encoding=null)
|
1427 |
+
{
|
1428 |
+
// Minified files often have a very large number of characters per line
|
1429 |
+
// and cause issues when tokenizing.
|
1430 |
+
if (property_exists($tokenizer, 'skipMinified') === true
|
1431 |
+
&& $tokenizer->skipMinified === true
|
1432 |
+
) {
|
1433 |
+
$numChars = strlen($string);
|
1434 |
+
$numLines = (substr_count($string, $eolChar) + 1);
|
1435 |
+
$average = ($numChars / $numLines);
|
1436 |
+
if ($average > 100) {
|
1437 |
+
throw new PHP_CodeSniffer_Exception('File appears to be minified and cannot be processed');
|
1438 |
+
}
|
1439 |
+
}
|
1440 |
+
|
1441 |
+
$tokens = $tokenizer->tokenizeString($string, $eolChar);
|
1442 |
+
|
1443 |
+
if ($tabWidth === null) {
|
1444 |
+
$tabWidth = PHP_CODESNIFFER_TAB_WIDTH;
|
1445 |
+
}
|
1446 |
+
|
1447 |
+
if ($encoding === null) {
|
1448 |
+
$encoding = PHP_CODESNIFFER_ENCODING;
|
1449 |
+
}
|
1450 |
+
|
1451 |
+
self::_createPositionMap($tokens, $tokenizer, $eolChar, $encoding, $tabWidth);
|
1452 |
+
self::_createTokenMap($tokens, $tokenizer, $eolChar);
|
1453 |
+
self::_createParenthesisNestingMap($tokens, $tokenizer, $eolChar);
|
1454 |
+
self::_createScopeMap($tokens, $tokenizer, $eolChar);
|
1455 |
+
|
1456 |
+
self::_createLevelMap($tokens, $tokenizer, $eolChar);
|
1457 |
+
|
1458 |
+
// Allow the tokenizer to do additional processing if required.
|
1459 |
+
$tokenizer->processAdditional($tokens, $eolChar);
|
1460 |
+
|
1461 |
+
return $tokens;
|
1462 |
+
|
1463 |
+
}//end tokenizeString()
|
1464 |
+
|
1465 |
+
|
1466 |
+
/**
|
1467 |
+
* Sets token position information.
|
1468 |
+
*
|
1469 |
+
* Can also convert tabs into spaces. Each tab can represent between
|
1470 |
+
* 1 and $width spaces, so this cannot be a straight string replace.
|
1471 |
+
*
|
1472 |
+
* @param array $tokens The array of tokens to process.
|
1473 |
+
* @param object $tokenizer The tokenizer being used to process this file.
|
1474 |
+
* @param string $eolChar The EOL character to use for splitting strings.
|
1475 |
+
* @param string $encoding The charset of the sniffed file.
|
1476 |
+
* @param int $tabWidth The number of spaces that each tab represents.
|
1477 |
+
* Set to 0 to disable tab replacement.
|
1478 |
+
*
|
1479 |
+
* @return void
|
1480 |
+
*/
|
1481 |
+
private static function _createPositionMap(&$tokens, $tokenizer, $eolChar, $encoding, $tabWidth)
|
1482 |
+
{
|
1483 |
+
$currColumn = 1;
|
1484 |
+
$lineNumber = 1;
|
1485 |
+
$eolLen = (strlen($eolChar) * -1);
|
1486 |
+
$tokenizerType = get_class($tokenizer);
|
1487 |
+
$ignoring = false;
|
1488 |
+
$inTests = defined('PHP_CODESNIFFER_IN_TESTS');
|
1489 |
+
|
1490 |
+
$checkEncoding = false;
|
1491 |
+
if ($encoding !== 'iso-8859-1' && function_exists('iconv_strlen') === true) {
|
1492 |
+
$checkEncoding = true;
|
1493 |
+
}
|
1494 |
+
|
1495 |
+
$tokensWithTabs = array(
|
1496 |
+
T_WHITESPACE => true,
|
1497 |
+
T_COMMENT => true,
|
1498 |
+
T_DOC_COMMENT => true,
|
1499 |
+
T_DOC_COMMENT_WHITESPACE => true,
|
1500 |
+
T_DOC_COMMENT_STRING => true,
|
1501 |
+
T_CONSTANT_ENCAPSED_STRING => true,
|
1502 |
+
T_DOUBLE
|