/wp-content/plugins/seo-ultimate/modules/opengraph/opengraph.php
PHP | 409 lines | 293 code | 82 blank | 34 comment | 37 complexity | 95593fe6b7c811c1cc92fcfc0ba35a4f MD5 | raw file
1<?php
2/**
3 * Open Graph Integrator Module
4 *
5 * @since 7.3
6 */
7
8if (class_exists('SU_Module')) {
9
10class SU_OpenGraph extends SU_Module {
11
12 var $namespaces_declared = false;
13 var $jlsuggest_box_post_id = false;
14
15 function get_module_title() { return __('Open Graph Integrator', 'seo-ultimate'); }
16 function get_menu_title() { return __('Open Graph', 'seo-ultimate'); }
17
18 function get_default_settings() {
19 return array(
20 'default_post_og_type' => 'article'
21 , 'default_page_og_type' => 'article'
22 , 'default_post_twitter_card' => 'summary'
23 , 'default_page_twitter_card' => 'summary'
24 , 'default_attachment_twitter_card' => 'photo'
25 );
26 }
27
28 function init() {
29 add_filter('language_attributes', array(&$this, 'html_tag_xmlns_attrs'), 1000);
30 add_action('su_head', array(&$this, 'head_tag_output'));
31 add_filter('su_get_setting-opengraph-twitter_site_handle', array(&$this, 'sanitize_twitter_handle'));
32 add_filter('user_contactmethods', array(&$this, 'add_twitter_field'));
33 }
34
35 function html_tag_xmlns_attrs($attrs) {
36 $this->namespaces_declared = true;
37 return $attrs . ' ' . implode(' ', $this->get_xmlns_attrs());
38 }
39
40 function get_xmlns_attrs() {
41 return array(
42 'og' => 'xmlns:og="http://ogp.me/ns#"'
43 , 'fb' => 'xmlns:fb="http://ogp.me/ns/fb#"'
44 );
45 }
46
47 function head_tag_output() {
48
49 $tags = $twitter_tags = array();
50
51 if (is_home()) {
52
53 //Type
54 $tags['og:type'] = 'blog';
55
56 //Twitter Type
57 $twitter_tags['twitter:card'] = 'summary';
58
59 //Title
60 if (!($tags['og:title'] = $this->get_setting('home_og_title')))
61 $tags['og:title'] = get_bloginfo('name');
62
63 //Description
64 if (!($tags['og:description'] = $this->get_setting('home_og_description')))
65 $tags['og:description'] = get_bloginfo('description');
66
67 //URL
68 $tags['og:url'] = get_bloginfo('url');
69
70 //Image
71 $tags['og:image'] = $this->get_setting('home_og_image');
72
73 } elseif (is_singular()) {
74
75 global $wp_query;
76 $post = $wp_query->get_queried_object();
77
78 if (is_object($post)) {
79 //Type
80 if (!($tags['og:type'] = $this->get_postmeta('og_type')))
81 $tags['og:type'] = $this->get_setting("default_{$post->post_type}_og_type");
82
83 //Twitter Type
84 if (!($twitter_tags['twitter:card'] = $this->get_postmeta('twitter_card')))
85 $twitter_tags['twitter:card'] = $this->get_setting("default_{$post->post_type}_twitter_card");
86
87 //Title
88 if (!($tags['og:title'] = $this->get_postmeta('og_title')))
89 $tags['og:title'] = strip_tags( apply_filters( 'single_post_title', $post->post_title ) );
90
91 //Description
92 if (!($tags['og:description'] = $this->get_postmeta('og_description')))
93 if ($this->plugin->call_module_func('meta-descriptions', 'get_meta_desc', $meta_desc, false) && $meta_desc)
94 $tags['og:description'] = $meta_desc;
95
96 //URL
97 $tags['og:url'] = get_permalink($post->ID);
98
99 //Image
100 $tags['og:image'] = $this->jlsuggest_value_to_url($this->get_postmeta('og_image'), true);
101 if (!$tags['og:image']) {
102 if ('attachment' == $post->post_type)
103 $tags['og:image'] = wp_get_attachment_url();
104 elseif ($thumbnail_id = get_post_thumbnail_id($post->ID))
105 $tags['og:image'] = wp_get_attachment_url($thumbnail_id);
106 }
107
108 //Additional fields
109 switch ($tags['og:type']) {
110 case 'article':
111
112 $tags['article:published_time'] = get_the_date('Y-m-d');
113 $tags['article:modified_time'] = get_the_modified_date('Y-m-d');
114 $tags['article:author'] = get_author_posts_url($post->post_author);
115
116 $single_category = (count(get_the_category()) == 1);
117
118 $taxonomy_names = suwp::get_taxonomy_names();
119 foreach ($taxonomy_names as $taxonomy_name) {
120 if ($terms = get_the_terms(get_the_ID(), $taxonomy_name)) {
121
122 if ($single_category && 'category' == $taxonomy_name)
123 $meta_property = 'article:section';
124 else
125 $meta_property = 'article:tag';
126
127 foreach ($terms as $term) {
128 $tags[$meta_property][] = $term->name;
129 }
130 }
131 }
132
133 break;
134 }
135
136 //Author's Twitter Handle
137 $handle = get_user_meta($post->post_author, 'twitter', true);
138 $handle = $this->sanitize_twitter_handle($handle);
139 $twitter_tags['twitter:creator'] = $handle;
140 }
141 } elseif (is_author()) {
142
143 global $wp_query;
144 $author = $wp_query->get_queried_object();
145
146 if (is_object($author)) {
147 //Type
148 $tags['og:type'] = 'profile';
149
150 //Title
151 $tags['og:title'] = $author->display_name;
152
153 //Description
154 $tags['og:title'] = get_the_author_meta('description', $author->ID);
155
156 //Image
157 $tags['og:image'] = false;
158
159 //URL
160 $tags['og:url'] = get_author_posts_url($author->ID, $author->user_nicename);
161
162 //First Name
163 $tags['profile:first_name'] = get_the_author_meta('first_name', $author->ID);
164
165 //Last Name
166 $tags['profile:last_name'] = get_the_author_meta('last_name', $author->ID);
167
168 //Username
169 $tags['profile:username'] = $author->user_login;
170
171 //Twitter Handle
172 $handle = get_user_meta($author->ID, 'twitter', true);
173 $handle = $this->sanitize_twitter_handle($handle);
174 $twitter_tags['twitter:creator'] = $handle;
175 }
176 } else
177 return;
178
179 if ($tags['og:type'] == 'none')
180 $tags['og:type'] = '';
181
182 if ((!isset($tags['og:image']) || !$tags['og:image']) && $tags['og:image'] !== false)
183 $tags['og:image'] = $this->jlsuggest_value_to_url($this->get_setting('default_og_image'), true);
184
185 //Site Name
186 if (!($tags['og:site_name'] = $this->get_setting('og_site_name')))
187 $tags['og:site_name'] = get_bloginfo('name');
188
189 //FB App ID
190 $tags['fb:app_id'] = $this->get_setting('default_fb_app_id');
191
192 //Twitter Site Handle
193 $twitter_tags['twitter:site'] = $this->get_setting('twitter_site_handle');
194
195 //Output meta tags
196 $xmlns_attrs = $this->namespaces_declared ? array() : $this->get_xmlns_attrs();
197
198 $output_formats = array(
199 '<meta property="%1$s" content="%2$s" %3$s/>' => $tags
200 , '<meta name="%1$s" content="%2$s" />' => $twitter_tags
201 );
202 foreach ($output_formats as $html_format => $format_tags) {
203 foreach ($format_tags as $property => $values) {
204 foreach ((array)$values as $value) {
205 $property = su_esc_attr($property);
206 $value = su_esc_attr($value);
207 if (strlen(trim($property)) && strlen(trim($value))) {
208 $xmlns = sustr::upto($property, ':');
209 $xmlns_attr = empty($xmlns_attrs[$xmlns]) ? '' : $xmlns_attrs[$xmlns] . ' ';
210 echo "\t";
211 printf($html_format, $property, $value, $xmlns_attr);
212 echo "\n";
213 }
214 }
215 }
216 }
217 }
218
219 function admin_page_init() {
220 $this->jlsuggest_init();
221 }
222
223 function editor_init() {
224 $this->jlsuggest_init();
225 }
226
227 function get_admin_page_tabs() {
228
229 $postmeta_edit_tabs = $this->get_postmeta_edit_tabs(array(
230 array(
231 'type' => 'dropdown'
232 , 'options' => array_merge(array('' => __('Use default', 'seo-ultimate')), $this->get_type_options())
233 , 'name' => 'og_type'
234 , 'label' => __('Type', 'seo-ultimate')
235 )
236 , array(
237 'type' => 'textbox'
238 , 'name' => 'og_title'
239 , 'label' => __('Title', 'seo-ultimate')
240 )
241 , array(
242 'type' => 'textbox'
243 , 'name' => 'og_description'
244 , 'label' => __('Description', 'seo-ultimate')
245 )
246 , array(
247 'type' => 'jlsuggest'
248 , 'name' => 'og_image'
249 , 'label' => __('Image', 'seo-ultimate')
250 , 'options' => array(
251 'params' => 'types=posttype_attachment&post_mime_type=image/*'
252 ))
253 ));
254
255 //Remove the Image boxes from the Media tab
256 //(it's obvious what the og:image of an attachment should be...)
257 unset($postmeta_edit_tabs['attachment']['callback'][5][3]);
258
259 return array_merge(
260 array(
261 array('title' => __('Sitewide Values', 'seo-ultimate'), 'id' => 'su-sitewide-values', 'callback' => 'global_tab')
262 , array('title' => __('Default Values', 'seo-ultimate'), 'id' => 'su-default-values', 'callback' => 'defaults_tab')
263 , array('title' => __('Blog Homepage', 'seo-ultimate'), 'id' => 'su-homepage', 'callback' => 'home_tab')
264 )
265 , $postmeta_edit_tabs
266 );
267 }
268
269 function global_tab() {
270 $this->admin_form_table_start();
271 $this->textbox('og_site_name', __('Site Name', 'seo-ultimate'), false, false, array(), array('placeholder' => get_bloginfo('name')));
272 $this->textbox('default_fb_app_id', __('Facebook App ID', 'seo-ultimate'));
273 $this->textbox('twitter_site_handle', __('This Site’s Twitter Handle', 'seo-ultimate'));
274 $this->admin_form_table_end();
275 }
276
277 function defaults_tab() {
278 $posttypes = suwp::get_post_type_objects();
279
280 $this->admin_subheader(__('Default Types', 'seo-ultimate'));
281 $this->admin_wftable_start(array(
282 'posttype' => __('Post Type', 'seo-ultimate')
283 , 'og' => __('Open Graph Type', 'seo-ultimate')
284 , 'twitter' => __('Twitter Type', 'seo-ultimate')
285 ));
286 foreach ($posttypes as $posttype) {
287 echo "<tr valign='middle'>\n";
288 echo "\t<th class='su-opengraph-posttype' scope='row'>" . esc_html($posttype->labels->name) . "</th>\n";
289 echo "\t<td class='su-opengraph-og'>";
290 $this->dropdown("default_{$posttype->name}_og_type", $this->get_type_options(), false, '%s', array('in_table' => false));
291 echo "</td>\n";
292 echo "\t<td class='su-opengraph-twitter'>";
293 $this->dropdown("default_{$posttype->name}_twitter_card", $this->get_twitter_type_options(), false, '%s', array('in_table' => false));
294 echo "</td>\n";
295 echo "</tr>\n";
296 }
297 $this->admin_wftable_end();
298
299 $this->admin_subheader(__('Default Image', 'seo-ultimate'));
300 $this->admin_form_table_start();
301
302 $this->textblock(__('In the box below, you can specify an image URL or an image from your media library to use as a default image in the event that there is no image otherwise specified for a given webpage on your site.', 'seo-ultimate'));
303
304 $this->jlsuggest_box('default_og_image', __('Default Image', 'seo-ultimate'), 'types=posttype_attachment&post_mime_type=image/*');
305
306 $this->admin_form_table_end();
307 }
308
309 function home_tab() {
310 $this->admin_form_table_start();
311 $this->textbox('home_og_title', __('Blog Homepage Title', 'seo-ultimate'), false, false, array(), array('placeholder' => get_bloginfo('name')));
312 $this->textbox('home_og_description', __('Blog Homepage Description', 'seo-ultimate'), false, false, array(), array('placeholder' => get_bloginfo('description')));
313 $this->jlsuggest_box('home_og_image', __('Blog Homepage Image', 'seo-ultimate'), 'types=posttype_attachment&post_mime_type=image/*');
314 $this->admin_form_table_end();
315 }
316
317 function postmeta_fields($fields) {
318
319 $fields['opengraph'][10]['og_title'] = $this->get_postmeta_textbox('og_title', __('Title:', 'seo-ultimate'));
320 $fields['opengraph'][20]['og_description'] = $this->get_postmeta_textarea('og_description', __('Description:', 'seo-ultimate'));
321 $fields['opengraph'][30]['og_image'] = $this->get_postmeta_jlsuggest_box('og_image', __('Image:', 'seo-ultimate'), 'types=posttype_attachment&post_mime_type=image/*');
322 $fields['opengraph'][40]['og_type'] = $this->get_postmeta_dropdown('og_type', array_merge(array('' => __('Use default', 'seo-ultimate')), $this->get_type_options()), __('Open Graph Type:', 'seo-ultimate'));
323 $fields['opengraph'][50]['twitter_card'] = $this->get_postmeta_dropdown('twitter_card', array_merge(array('' => __('Use default', 'seo-ultimate')), $this->get_twitter_type_options()), __('Twitter Type:', 'seo-ultimate'));
324
325 return $fields;
326 }
327
328 function get_postmeta_jlsuggest_boxes($jls_boxes) {
329 $this->jlsuggest_box_post_id = suwp::get_post_id();
330 return parent::get_postmeta_jlsuggest_boxes($jls_boxes);
331 }
332
333 function get_input_element($type, $name, $value=null, $extra=false, $inputid=true) {
334
335 $name_parts = explode('_', $name);
336 if (isset($name_parts[1]) && is_numeric($post_id = $name_parts[1]))
337 $this->jlsuggest_box_post_id = $post_id;
338 else
339 $this->jlsuggest_box_post_id = false;
340
341 return parent::get_input_element($type, $name, $value, $extra, $inputid);
342 }
343
344 function get_jlsuggest_box($name, $value, $params='', $placeholder='') {
345
346 if (empty($value) && $this->jlsuggest_box_post_id && $thumbnail_id = get_post_thumbnail_id($this->jlsuggest_box_post_id)) {
347 $selected_post = get_post($thumbnail_id);
348 $placeholder = sprintf(__('Featured Image: %s', 'seo-ultimate'), $selected_post->post_title);
349 }
350
351 return parent::get_jlsuggest_box($name, $value, $params, $placeholder);
352 }
353
354 function get_type_options() {
355 return array(
356 'none' => __('None', 'seo-ultimate')
357 , __('Internet', 'seo-ultimate') => array(
358 'article' => __('Article', 'seo-ultimate')
359 , 'blog' => __('Blog', 'seo-ultimate')
360 , 'profile' => __('Profile', 'seo-ultimate')
361 , 'website' => __('Website', 'seo-ultimate')
362 ),__('Products', 'seo-ultimate') => array(
363 'book' => __('Book', 'seo-ultimate')
364 ),__('Music', 'seo-ultimate') => array(
365 'music.album' => __('Album', 'seo-ultimate')
366 , 'music.playlist' => __('Playlist', 'seo-ultimate')
367 , 'music.radio_station' => __('Radio Station', 'seo-ultimate')
368 , 'music.song' => __('Song', 'seo-ultimate')
369 ),__('Videos', 'seo-ultimate') => array(
370 'video.movie' => __('Movie', 'seo-ultimate')
371 , 'video.episode' => __('TV Episode', 'seo-ultimate')
372 , 'video.tv_show' => __('TV Show', 'seo-ultimate')
373 , 'video.other' => __('Video', 'seo-ultimate')
374 )
375 );
376 }
377
378 function get_twitter_type_options() {
379 return array(
380 'summary' => __('Regular', 'seo-ultimate')
381 , 'photo' => __('Photo', 'seo-ultimate')
382 );
383 }
384
385 function sanitize_twitter_handle($value) {
386 if (strpos($value, '/') === false) {
387 $handle = ltrim($value, '@');
388 } else {
389 $url_parts = explode('/', $value);
390 $handle = array_pop($url_parts);
391 }
392
393 $handle = sustr::preg_filter('a-zA-Z0-9_', $handle);
394 $handle = trim($handle);
395
396 if ($handle)
397 $handle = "@$handle";
398
399 return $handle;
400 }
401
402 function add_twitter_field( $contactmethods ) {
403 $contactmethods['twitter'] = __('Twitter Handle', 'seo-ultimate');
404 return $contactmethods;
405 }
406}
407
408}
409?>