@@ -280,6 +280,9 @@ class Parser {
280280 /** @var boolean Whether to include experimental language parsing in the result */
281281 public $ lang = false ;
282282
283+ /** @var bool Whether to include alternates object (dropped from spec in favor of rel-urls) */
284+ public $ enableAlternates = false ;
285+
283286 /**
284287 * Elements upgraded to mf2 during backcompat
285288 * @var SplObjectStorage
@@ -1153,62 +1156,89 @@ public function parseImpliedPhoto(\DOMElement $e) {
11531156 }
11541157
11551158 /**
1156- * Parse Rels and Alternatives
1159+ * Parse rels and alternates
11571160 *
1158- * Returns [$rels, $alternatives]. If the $rels value is to be empty, i.e. there are no links on the page
1159- * with a rel value *not* containing `alternate`, then the type of $rels depends on $this->jsonMode. If set
1160- * to true, it will be a stdClass instance, optimising for JSON serialisation. Otherwise (the default case),
1161- * it will be an empty array.
1161+ * Returns [$rels, $rel_urls, $alternates].
1162+ * For $rels and $rel_urls, if they are empty and $this->jsonMode = true, they will be returned as stdClass,
1163+ * optimizing for JSON serialization. Otherwise they will be returned as an empty array.
1164+ * Note that $alternates is deprecated in the microformats spec in favor of $rel_urls. $alternates only appears
1165+ * in parsed results if $this->enableAlternates = true.
1166+ * @return array|stdClass
11621167 */
11631168 public function parseRelsAndAlternates () {
11641169 $ rels = array ();
1170+ $ rel_urls = array ();
11651171 $ alternates = array ();
11661172
11671173 // Iterate through all a, area and link elements with rel attributes
11681174 foreach ($ this ->xpath ->query ('//a[@rel and @href] | //link[@rel and @href] | //area[@rel and @href] ' ) as $ hyperlink ) {
1169- if ($ hyperlink ->getAttribute ('rel ' ) == '' )
1175+ if ($ hyperlink ->getAttribute ('rel ' ) == '' ) {
11701176 continue ;
1177+ }
11711178
11721179 // Resolve the href
11731180 $ href = $ this ->resolveUrl ($ hyperlink ->getAttribute ('href ' ));
11741181
11751182 // Split up the rel into space-separated values
11761183 $ linkRels = array_filter (explode (' ' , $ hyperlink ->getAttribute ('rel ' )));
11771184
1178- // If alternate in rels, create alternate structure, append
1179- if (in_array ('alternate ' , $ linkRels )) {
1180- $ alt = array (
1181- 'url ' => $ href ,
1182- 'rel ' => implode (' ' , array_diff ($ linkRels , array ('alternate ' )))
1183- );
1184- if ($ hyperlink ->hasAttribute ('media ' ))
1185- $ alt ['media ' ] = $ hyperlink ->getAttribute ('media ' );
1185+ $ rel_attributes = array ();
11861186
1187- if ($ hyperlink ->hasAttribute ('hreflang ' ))
1188- $ alt ['hreflang ' ] = $ hyperlink ->getAttribute ('hreflang ' );
1187+ if ($ hyperlink ->hasAttribute ('media ' )) {
1188+ $ rel_attributes ['media ' ] = $ hyperlink ->getAttribute ('media ' );
1189+ }
11891190
1190- if ($ hyperlink ->hasAttribute ('title ' ))
1191- $ alt ['title ' ] = $ hyperlink ->getAttribute ('title ' );
1191+ if ($ hyperlink ->hasAttribute ('hreflang ' )) {
1192+ $ rel_attributes ['hreflang ' ] = $ hyperlink ->getAttribute ('hreflang ' );
1193+ }
11921194
1193- if ($ hyperlink ->hasAttribute ('type ' ))
1194- $ alt ['type ' ] = $ hyperlink ->getAttribute ('type ' );
1195+ if ($ hyperlink ->hasAttribute ('title ' )) {
1196+ $ rel_attributes ['title ' ] = $ hyperlink ->getAttribute ('title ' );
1197+ }
11951198
1196- if ($ hyperlink ->nodeValue )
1197- $ alt ['text ' ] = $ hyperlink ->nodeValue ;
1199+ if ($ hyperlink ->hasAttribute ('type ' )) {
1200+ $ rel_attributes ['type ' ] = $ hyperlink ->getAttribute ('type ' );
1201+ }
11981202
1199- $ alternates [] = $ alt ;
1200- } else {
1201- foreach ($ linkRels as $ rel ) {
1202- $ rels [$ rel ][] = $ href ;
1203+ if ($ hyperlink ->nodeValue ) {
1204+ $ rel_attributes ['text ' ] = $ hyperlink ->nodeValue ;
1205+ }
1206+
1207+ if ($ this ->enableAlternates ) {
1208+ // If 'alternate' in rels, create 'alternates' structure, append
1209+ if (in_array ('alternate ' , $ linkRels )) {
1210+ $ alternates [] = array_merge (
1211+ $ rel_attributes ,
1212+ array (
1213+ 'url ' => $ href ,
1214+ 'rel ' => implode (' ' , array_diff ($ linkRels , array ('alternate ' )))
1215+ )
1216+ );
12031217 }
12041218 }
1219+
1220+ foreach ($ linkRels as $ rel ) {
1221+ $ rels [$ rel ][] = $ href ;
1222+ }
1223+
1224+ if (!in_array ($ href , $ rel_urls )) {
1225+ $ rel_urls [$ href ] = array_merge (
1226+ $ rel_attributes ,
1227+ array ('rels ' => $ linkRels )
1228+ );
1229+ }
1230+
12051231 }
12061232
12071233 if (empty ($ rels ) and $ this ->jsonMode ) {
12081234 $ rels = new stdClass ();
12091235 }
12101236
1211- return array ($ rels , $ alternates );
1237+ if (empty ($ rel_urls ) and $ this ->jsonMode ) {
1238+ $ rel_urls = new stdClass ();
1239+ }
1240+
1241+ return array ($ rels , $ rel_urls , $ alternates );
12121242 }
12131243
12141244 /**
@@ -1239,14 +1269,15 @@ public function parse($convertClassic = true, DOMElement $context = null) {
12391269 }
12401270
12411271 // Parse rels
1242- list ($ rels , $ alternates ) = $ this ->parseRelsAndAlternates ();
1272+ list ($ rels , $ rel_urls , $ alternates ) = $ this ->parseRelsAndAlternates ();
12431273
12441274 $ top = array (
12451275 'items ' => array_values (array_filter ($ mfs )),
1246- 'rels ' => $ rels
1276+ 'rels ' => $ rels ,
1277+ 'rel-urls ' => $ rel_urls ,
12471278 );
12481279
1249- if (count ($ alternates )) {
1280+ if ($ this -> enableAlternates && count ($ alternates )) {
12501281 $ top ['alternates ' ] = $ alternates ;
12511282 }
12521283
0 commit comments