Changeset 1962318
- Timestamp:
- 10/24/2018 07:05:57 PM (7 years ago)
- Location:
- somatic-framework/trunk
- Files:
-
- 7 edited
-
inc/somaFunctions.php (modified) (2 diffs)
-
inc/somaMetaboxes.php (modified) (1 diff)
-
inc/somaOptions.php (modified) (2 diffs)
-
inc/somaSave.php (modified) (4 diffs)
-
inc/somaTypes.php (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
-
somaticFramework.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
somatic-framework/trunk/inc/somaFunctions.php
r1600892 r1962318 3 3 class somaFunctions extends somaticFramework { 4 4 5 function __construct() {6 add_action( 'init', array(__CLASS__,'init' ));7 add_action( 'admin_init', array(__CLASS__,'check_plugin_dependency' ));8 add_filter( 'query_vars', array(__CLASS__,'custom_query_vars' ));9 add_filter( 'parse_query', array(__CLASS__,'filter_current_query' ));// empty at the moment10 add_filter( 'pre_get_posts', array(__CLASS__,'pre_get_posts'));11 add_action( 'before_delete_post', array(__CLASS__, 'delete_attachments_when_parents_die' ));// have to do this "before", as wp_delete_post detaches all attachments before the 'delete_post' action, which left us unable to retrieve connected attachments...12 add_filter( 'gettext', array(__CLASS__, 'modify_core_language' ), 20, 3);13 add_filter( 'ngettext', array(__CLASS__, 'modify_core_language' ), 20, 3);14 // add_filter( 'login_redirect', array(__CLASS__, 'dashboard_redirect' ));15 add_filter( 'add_menu_classes', array(__CLASS__, 'show_pending_number'));16 // add_filter( 'wp_die_handler', array(__CLASS__, 'soma_wp_die_handler'),10,3);17 add_filter( 'editable_roles', array(__CLASS__, 'editable_roles'));18 add_filter( 'map_meta_cap', array(__CLASS__, 'admin_map_meta_cap'), 10, 4);19 remove_filter('check_comment_flood', 'check_comment_flood_db');// deal with "posting too quickly" problem....20 add_filter( 'edit_posts_per_page', array(__CLASS__, 'edit_list_length'));21 add_action( 'wp_ajax_unlink_file', array(__CLASS__, 'ajax_unlink_file'));22 add_action( 'wp_ajax_delete_attachment', array(__CLASS__, 'ajax_delete_attachment'));23 add_action( 'admin_notices', array(__CLASS__,'soma_admin_notices'), 100);24 }25 26 function init() {27 // localization init needed?? no translations yet28 // load_plugin_textdomain( 'stock-media-asset-manager', SOMA_DIR . '/lang', basename( dirname( __FILE__ ) ) . '/lang' );29 // self::session_manager(); /// WARNING this occasionally causes PHP errors: "Cannot send session cache limiter - headers already sent" -- do we need this?30 self::wp_version_check();31 self::check_staff();32 }33 34 // displays notices using the core wp messge box.35 function soma_admin_notices() {36 // if (soma_fetch_index($_GET['soma-notify']) == true) {37 // if (get_query_var('soma_notify') == true) {38 $notices = get_transient( 'soma_notices' );// check if any waiting39 if ($notices === false) return;40 foreach ($notices as $notice) {41 if (empty($notice['msg'])) continue;42 if (empty($notice['type'])) $notice['type'] == 'updated';43 echo "<div class='{$notice['type']}'>";44 echo "<p>{$notice['msg']}</p>";45 echo "</div>";46 }47 // }48 delete_transient('soma_notices');49 }50 51 // adds an admin notice message to the queue. can use 'updated', or 'error'52 function queue_notice($type = 'updated', $msg) {53 $notices = get_transient( 'soma_notices' );// grab any existing notices54 if ($notices === false || !is_array($notices)) $notices = array();// or init55 $notices[] = array('type' => $type, 'msg' => $msg);// add to the queue56 set_transient( 'soma_notices', $notices );// store it57 }58 59 // adds an admin notice as well as reloads the page to display the notice. good for returning the result of a custom manipulation function without leaving the page60 function completion_notice($type, $msg) {61 somaFunctions::queue_notice($type, $msg);62 // $result = add_query_arg( 'soma_notify', 'true', $_SERVER['HTTP_REFERER'] );// used to be needed to trigger, but now we just check for the transient itself63 // wp_redirect( $result );64 wp_redirect( $_SERVER['HTTP_REFERER'] );65 exit;// this halts everything, so this better be your last function call66 }67 68 // set if user has staff privileges (default to editors)69 function check_staff() {70 $privs = 'edit_others_posts';71 $privs = apply_filters('soma_staff_privs', $privs);72 define( 'SOMA_STAFF', current_user_can( $privs ));73 }74 75 // changes how many items are shown per page in /wp-admin/edit.php76 function edit_list_length() {77 return 40;78 }79 80 // checks if something is truly empty (not set) or null, and not simply set to a valid but negative value, like false or - 0 (0 as an integer) - 0.0 (0 as a float) - "0" (0 as a string)81 // NOTE: THIS DOESN'T AVOID THE PHP NOTICE ERROR IF SOMETHING DOESN'T EXIST (not set)82 function is_blank( $value ) {83 return empty( $value ) && !is_numeric( $value ) && $value !== false;84 }85 86 // checks if array is associative or not87 function array_is_associative($arr) {88 if (!is_array($arr)) return false;89 return array_keys($arr) !== range(0, count($arr) - 1);90 }91 92 // returns URL to facebook image from facebook ID stored in post_meta93 function fetch_facebook_pic($pid, $size = "square") {94 // sizes: square, small, normal, large95 96 $fid = somaFunctions::asset_meta('get', $pid, 'facebook_id');97 if (!$fid) return SOMA_IMG . '/generic-female-thumb.png';98 99 // $userurl = "http://graph.facebook.com/$fid";100 // $user = json_decode(file_get_contents($userurl));101 // $feedurl = "http://graph.facebook.com/$fid/feed";102 // $feed = json_decode(file_get_contents($feedurl));103 return "https://graph.facebook.com/$fid/picture?type=$size";104 }105 106 // since our postmeta is serialized, to query posts by postmeta requires retrieving a set of posts and then checking each entry against the desired postmeta for matches107 function fetch_posts($args, $meta_key = null, $meta_value = null) {108 if (!is_array($args)) return null;109 $args['numberposts'] = -1;// always retrieve all, not just first 5110 $items = get_posts($args);111 $matches = array();112 foreach ($items as $item) {113 $val = somaFunctions::asset_meta('get', $item->ID, $meta_key);114 if ($val == $meta_value) {115 $matches[] = $item;116 }117 }118 return $matches;119 }120 121 // retrieves array of user objects for a given role name122 function get_role_members_OLD($rolename) {123 $blogusers = get_users_of_blog();124 $members = array();125 foreach ($blogusers as $user) {126 $userdata = get_userdata($user->ID);127 // check role name128 if ($userdata->wp_capabilities[$rolename] == '1') {129 // add to new role array130 $members[] = $userdata;131 }132 }133 return $members;134 }135 136 137 // retrieves array of user objects for a given role name138 function get_role_members($roles = null) {139 if (!$roles) return false;140 // convert to array if single141 if (!is_array($roles)) {142 $roles = array($roles);143 }144 // init output array145 $members = array();146 global $wp_roles;147 foreach ($roles as $role) {148 if (!array_key_exists($role, $wp_roles->roles)) continue;// abort if given a non-existant role (otherwise the user_query will return everyone)149 $wp_user_search = new WP_User_Query( array( 'role' => $role) );150 // wp_die(var_dump($wp_user_search));151 $users = $wp_user_search->get_results();152 if (empty($users)) continue;153 foreach ($users as $user) {154 $members[] = $user;155 }156 }157 return $members;158 }159 160 // retrieves name of role assigned to pass user id or current user if not provided161 function get_user_role( $uid = null ) {162 if (!$uid) {163 $user = wp_get_current_user();164 } else {165 $user = new WP_User( $uid );166 }167 if ( !empty( $user->roles ) && is_array( $user->roles ) ) {168 foreach ( $user->roles as $role )169 return $role;170 }171 }172 173 // comparison function for usort - allows sorting of arrays of objects by object properties174 function usort_displaynames($a, $b) {175 if ($a->display_name == $b->display_name)176 return 0;177 else178 return ($a->display_name < $b->display_name ? -1 : 1);179 }180 181 // comparison function for usort - allows sorting of arrays of objects by object properties182 function usort_ids($a, $b) {183 if ($a->ID == $b->ID)184 return 0;185 else186 return ($a->ID < $b->ID ? -1 : 1);187 }188 189 // checks to see if $_GET or $_POST values are set, avoids Undefined index error190 function fetch_index($array, $index) {191 if (!is_array($array)) return null;192 return isset($array[$index]) ? $array[$index] : null;193 }194 195 //196 function fetch_author($author_id = null, $output = "display_name") {197 if ($author_id != null) {198 $user = get_userdata($author_id);199 if ($user == null) {200 return new WP_Error('missing','can\'t find the user...');201 }202 } else {203 return new WP_Error('missing','must provide author id...');204 }205 // $code = get_the_author_meta( somaMetaboxes::$meta_prefix .'user_code', $post->post_author );206 // $code = get_the_author_meta( 'user_exclusive', $post->post_author );207 208 if ($output == "link") {209 if (is_admin()) {210 $url = admin_url() . "edit.php?author=" . $user->ID;211 $url .= $type ? "&post_type=".$type : "";212 } else {213 $url = home_url() . "?author=" . $user->ID;214 $url .= $type ? "&post_type=" . $type : "";215 }216 return "<a href=\"" . $url . "\">". $user->display_name . "</a>";217 }218 return $user->$output;219 }220 221 //222 function fetch_post_author($post_id = null, $output = "display_name" ) {223 if (!$post_id) {224 global $post;225 if ($post == null) {226 return new WP_Error('missing','can\'t find the post...');227 }228 } else {229 $post = get_post($post_id);230 }231 $type = $post->post_type;232 $user = get_userdata($post->post_author);233 234 // $code = get_the_author_meta( somaMetaboxes::$meta_prefix .'user_code', $post->post_author );235 // $code = get_the_author_meta( 'user_exclusive', $post->post_author );236 237 if ($output == "link") {238 if (is_admin()) {239 $url = admin_url() . "edit.php?author=" . $user->ID;240 $url .= $type ? "&post_type=".$type : "";241 } else {242 $url = home_url() . "?author=" . $user->ID;243 $url .= $type ? "&post_type=" . $type : "";244 }245 return "<a href=\"" . $url . "\">". $user->display_name . "</a>";246 }247 return $user->$output;248 }249 250 //251 function fetch_current_user($output = "display_name") {252 global $current_user;253 if ($current_user == null) {254 return new WP_Error('missing','can\'t find the user...');255 }256 257 if ($output == "link") {258 if (is_admin()) {259 $url = admin_url() . "edit.php?author=" . $current_user->ID;260 $url .= $type ? "&post_type=".$type : "";261 } else {262 $url = home_url() . "?author=" . $current_user->ID;263 $url .= $type ? "&post_type=" . $type : "";264 }265 return "<a href=\"" . $url . "\">". $current_user->display_name . "</a>";266 }267 return $current_user->$output;268 }269 270 271 //** clone of core get_the_term_list() - modifies the URL output if inside admin to stay in admin and to link to the edit post listing screen, also - can output comma separated string instead of links272 function fetch_the_term_list( $id = null, $taxonomy, $before = '', $sep = ', ', $after = '', $output = 'html' ) {273 if (is_null($id)) return false;274 $terms = wp_get_object_terms( $id, $taxonomy );275 $type = get_post_type($id);276 if ( is_wp_error( $terms ) )277 return $terms->get_error_message();278 if ( empty( $terms ) )279 return false;280 // create array with links281 if ($output == "html") {282 foreach ( $terms as $term ) {283 // within admin, link to the admin edit post list screen, but filtering for this taxonomy term284 if (is_admin()) {285 $link = admin_url() . "edit.php?" . $taxonomy . "=" . $term->slug . "&post_type=" . $type;286 } else {287 $link = get_term_link( $term, $taxonomy );288 }289 if ( is_wp_error( $link ) )290 return $link->get_error_message();291 $term_links[] = '<a href="' . $link . '" rel="tag">' . $term->name . '</a>';292 }293 // create plain string of comma-separated names294 }295 if ($output == "text") {296 foreach ($terms as $term) {297 $term_links[] = $term->name;298 }299 }300 301 // outputs a vertical stack table for items in the edit.php listing302 if ($output == "table") {303 if (!is_admin()) return false;304 305 $table = "<table>";306 $i = 1;307 $max = count($terms);308 foreach ($terms as $term) {309 // avoid border on last entry310 if ($i == $max) {311 $table .= "<tr><td class=\"last\">";312 } else {313 $table .= "<tr><td>";314 }315 $link = admin_url() . "edit.php?" . $taxonomy . "=" . $term->slug . "&post_type=" . $type;316 $table .= "<a href=\"".$link."\" rel=\"tag\">$term->name</a></td></tr>";317 $i++;318 }319 $table .= "</table>";320 return $table;321 }322 323 return $before . join( $sep, $term_links ) . $after;324 }325 326 // retrieves taxonomy terms that are used in a singular way (only one possible state, ie ON or OFF)327 function fetch_the_singular_term( $post, $taxonomy, $label = "slug" ) {328 if (is_wp_error($post)) return $post;329 if (empty($post)) return new WP_Error('missing', "must pass a post argument!");330 if (is_object($post)) {331 $pid = $post->ID;332 } else {333 $pid = intval($post);334 }335 336 $term = wp_get_object_terms( $pid, $taxonomy );337 if (is_wp_error($term) || empty($term)) return null;// taxonomy doesn't exist OR there are no terms assigned338 if ($label == 'slug') {339 return $term[0]->slug;340 }341 if ($label == 'name') {342 return $term[0]->name;343 }344 if ($label == 'link') {345 if (is_admin()) {346 $link = admin_url() . "edit.php?" . $taxonomy . "=" . $term[0]->slug . "&post_type=" . get_post_type($pid);347 } else {348 $link = get_term_link( $term[0] );349 }350 return '<a href="' . $link . '">' . $term[0]->name . '</a>';351 }352 if ($label == 'id' || $label == 'term_id') {353 return $term[0]->term_id;354 }355 return null;356 }357 358 359 //** for retrieving p2p connected posts360 // can output count, array of post objects, list of html links, list of text, a table of links, or select dropdown input values361 // note - modifies the URL output if inside wp-admin to stay in admin and to link to the edit post listing screen rather than the post permalink362 // $pid = can be single integer or array of post ID's363 // $p2pname = the name of the connection you made with "p2p_register_connection_type"364 // $dir = connection direction (to, from, any)365 // $output = how to format the return data366 367 function fetch_connected_items( $pid = 0, $p2pname, $dir = 'any', $output = 'html', $sep = ", " ) {368 if (!function_exists('p2p_register_connection_type')) return 'No P2P plugin!';// make sure plugin is enabled369 370 // https://github.com/scribu/wp-posts-to-posts/wiki/Query-vars371 372 $args = array( 'connected_type' => $p2pname );373 switch( $dir ) {374 case "to" :375 $args['connected_to'] = $pid;376 break;377 case "from" :378 $args['connected_from'] = $pid;379 break;380 default :381 $args['connected_items'] = $pid;// this passes "any" for direction382 break;383 }384 385 if ($meta_key && $meta_value) {386 $args['connected_meta'] = array(387 $meta_key => $meta_value388 );389 }390 391 $query = new WP_Query( $args );392 $items = array();393 $items = $query->posts;394 395 if ( is_wp_error( $items ) )396 return $items->get_error_message();;397 398 // output how many connected items399 if ($output == "count") {400 if ( empty( $items ) ) return 0;401 return count($items);402 }403 404 405 // simply output the array of matching post objects406 if ($output == "objects") {407 if ( empty( $items ) ) return false;408 return $items;409 }410 411 // create array with links412 if ($output == "html") {413 if ( empty( $items ) ) return false;414 foreach ( $items as $item ) {415 // within admin, link to the admin edit post list screen, but filtering for this taxonomy term416 if (is_admin()) {417 $link = get_edit_post_link($item->ID);418 } else {419 $link = get_permalink($item->ID);420 }421 if ( is_wp_error( $link ) )422 return $link->get_error_message();;423 $item_list[] = '<a href="' . $link . '">' . $item->post_title . '</a>';424 }425 return $before . join( $sep, $item_list ) . $after;426 427 // return p2p_list_posts( p2p_type( $p2pname )->get_connected( $post->ID ) ); // a helpful function from scribu to do the same thing ;-)428 }429 430 // create plain string of comma-separated names431 if ($output == "text") {432 if ( empty( $items ) ) return false;433 foreach ($items as $item) {434 $item_list[] = $item->post_title;435 }436 return $before . join( $sep, $item_list ) . $after;437 }438 439 // outputs a vertical stack table for items in the edit.php listing440 if ($output == "table") {441 if (!is_admin()) return false;442 if ( empty( $items ) ) return false;443 // generate table html444 $table = "<table>";445 $i = 1;446 $max = count($items);447 foreach ($items as $item) {448 // avoid border on last entry449 if ($i == $max) {450 $table .= "<tr><td class=\"last\">";451 } else {452 $table .= "<tr><td>";453 }454 $table .= "<a href=\"".get_edit_post_link($item->ID)."\">$item->post_title</a></td></tr>";455 $i++;456 }457 $table .= "</table>";458 return $table;459 }460 461 // outputs an array for populating select dropdown inputs462 if ($output == "select") {463 if ( empty( $items ) ) {464 return array(array('name' => '[nothing to select]', 'value' => '0'));// no user role matches, output empty list465 }466 foreach ($items as $item) {467 $list[] = array('name' => $item->post_title, 'value' => intval($item->ID));468 }469 return $list;470 }471 }472 473 474 //** generates mini box html output of asset ------------------------------------------------------//475 function mini_asset_output($items) {476 if (!is_array($items)) {477 $items = array($items);478 }479 $html = "<div class=\"mini-asset-list\">\n";480 $html .= "<ul class=\"slider\">\n";481 482 foreach ($items as $item) {483 484 $view = get_permalink($item->ID);485 $edit = get_edit_post_link($item->ID);486 $title = get_the_title($item->ID);487 $services = somaFunctions::fetch_the_term_list($item->ID, 'service','','<br/>','','html');488 $status = somaFunctions::fetch_the_singular_term($item->ID, 'app_status');489 $type = $item->post_type;490 $img = somaFunctions::fetch_featured_image($item->ID);491 492 493 $html .= "<li class=\"item $status\">\n";494 495 $html .= "\t<ul>\n";496 497 // in admin, click image to edit the item, in front-end, click image to go to single asset view498 // if (is_admin()) {499 //if ( $review ) {500 //// add lightbox link to image501 //$html .= "\t<li class=\"post-thumb\"><a class=\"lightbox\" rel=\"gallery\" href=\"{$img['large']['url']}\"><img src=\"{$img['thumbnail']['url']}\" /></a></li>\n";502 //} else {503 //// add edit link to image504 //$html .= "\t<li class=\"post-thumb\"><a href=\"". get_edit_post_link($item->ID) ."\"><img src=\"{$img['thumbnail']['url']}\" /></a></li>\n";505 //}506 // } else {507 //// add view link to image508 //$html .= "<li class=\"post-thumb\"><a href=\"". get_permalink($item->ID) . "\"><img src=\"{$img['thumbnail']['url']}\" /></a></li>\n";509 // }510 511 512 $html .= "\t\t<li class=\"asset-thumb\">\n";513 514 $html .= "\t\t\t<a href=\"$edit\"><div class=\"fb-thumb\"><img src=\"{$img['thumbnail']['url']}\"/></a></div>\n";515 // $html .= "\t\t\t<a href=\"$edit\"><img src=\"{$img['thumbnail']['url']}\"/></a>\n";516 $html .= "\t\t</li>\n";517 518 $html .= "\t\t<li class=\"title\"><strong><a href=\"$edit\">". get_the_title($item->ID). "</a></strong></li>\n";519 520 // $html .= "\t\t<li class=\"services\">". $services . "</li>\n";521 522 // $html .= "\t\t<li class=\"creator\">". somaFunctions::fetch_post_author( $item->ID) ."</li>\n";523 524 525 if ($type == "classes") {526 $conn = get_posts( array(527 'post_type' => array('clients'),528 'suppress_filters' => false,529 'numberposts' => -1,530 'connected' => $item->ID,531 ) );532 $max = somaFunctions::asset_meta('get', $item->ID, 'class_max');533 if (!$max) $max = "?";534 $count = count( $conn);535 $html .= "\t\t<li class=\"count\">" .$count . " Enrolled / $max Max</li>\n";536 $html .= "\t\t<li class=\"type\">$type</li>\n";// minibox label537 } else {538 $html .= "\t\t<li class=\"type\">$status</li>\n";// minibox label539 }540 541 $html .= "\t</ul>\n";542 $html .= "</li>\n";543 }544 $html .= "</ul>\n";545 $html .= "</div>\n";546 return $html;547 }548 549 // need this?550 function extract_numbers($string) {551 preg_match_all('/([\d]+)/', $string, $match);552 return $match[0];553 }554 555 // automatically sends user to dashboard after login, instead of their profile page556 function dashboard_redirect($url) {557 global $user;558 // if ($user->roles[0] == 'foo')559 //return 'wp-admin/admin.php?page=foo-user-page';560 return 'wp-admin/index.php';561 }562 563 /**564 * Performs a query for results within a set of multiple terms (matching any one of, not all)565 *566 * @param string $type (required) Post Type slug567 * @param string $tax (required) Taxonomy slug568 * @param array strings $terms (required) Term slugs to match within569 * @return array of objects570 */571 function multi_term_query($type = null, $tax = null, $terms = null) {572 global $wpdb;573 574 if (!$type || !$tax || !is_array($terms)) {575 wp_die('missing an argument...');576 }577 578 $querystr = "SELECT *579 FROM $wpdb->posts580 LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)581 LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)582 LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)583 WHERE $wpdb->posts.post_type = '$type'584 AND $wpdb->posts.post_status = 'publish'585 AND $wpdb->term_taxonomy.taxonomy = '$tax'586 AND (";587 $i = 1;588 foreach ($terms as $term) {589 $querystr .= "$wpdb->terms.slug = '$term'";590 if ($i < count($terms)) {591 $querystr .= " OR ";592 }593 $i++;594 }595 596 $querystr .= ")\nORDER BY $wpdb->posts.post_date ASC";597 // echo $querystr;598 $posts = $wpdb->get_results($querystr, OBJECT);599 return $posts;600 }601 602 603 // add_action('post_submitbox_misc_actions','my_post_submitbox_misc_actions');604 function my_post_submitbox_misc_actions() {605 ?>606 <script type="text/javascript">607 jQuery(document).ready(function($) {608 $("#misc-publishing-actions select#post_status option[value='pending']").remove();609 });610 </script>611 <?php612 }613 614 // changes words throughout wordpress615 function modify_core_language( $translated ) {616 // $translated = str_replace( 'Publish', 'Ingest', $translated );617 // $translated = str_replace( 'Dashboard', 'Overview', $translated );618 $translated = str_replace( 'featured', 'assigned', $translated );619 $translated = str_replace( 'Start typing the title of a post', 'Start typing the title of an asset', $translated );// p2p metabox620 // $translated = str_replace( 'Post', 'Article', $translated );621 return $translated;622 }623 624 // deletes all attachments (including the actual files on server) when a post is deleted -- custom post type args or this post's post_meta must be set for this to happen, so its not universal625 function delete_attachments_when_parents_die($post_id) {626 $metakill = somaFunctions::asset_meta('get', $post_id, 'delete_attachments_upon_deletion');627 $ptype = get_post_type($post_id);628 $ptobj = get_post_type_object($ptype);629 $typekill = $ptobj->delete_attachments_upon_deletion;630 if ( $metakill || $typekill ) {631 global $wpdb;632 $attids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_parent = %d AND post_type = %s", $post_id, 'attachment')); // properly prepared safe query633 foreach ( $attids as $attid ) {634 wp_delete_attachment($attid);635 }636 }637 }638 639 //** allows use of custom field data in the query vars URL string. without this, would need to call the query_posts() function and pass meta_key/meta_value...640 function custom_query_vars($qvars) {641 $qvars[] = "meta_key";642 $qvars[] = "meta_value";643 $qvars[] = "meta_compare";644 return $qvars;645 }646 647 //** modifies the QUERY before output ------------------------------------------------------//648 function filter_current_query($query) {649 return $query;650 }651 652 // this is much like filter_current_query653 function pre_get_posts($query) {654 // wp_die(var_dump($query));655 return $query;656 }657 658 /**5 function __construct() { 6 add_action( 'init', array(__CLASS__,'init' )); 7 add_action( 'admin_init', array(__CLASS__,'check_plugin_dependency' )); 8 add_filter( 'query_vars', array(__CLASS__,'custom_query_vars' )); 9 add_filter( 'parse_query', array(__CLASS__,'filter_current_query' )); // empty at the moment 10 add_filter( 'pre_get_posts', array(__CLASS__,'pre_get_posts')); 11 add_action( 'before_delete_post', array(__CLASS__, 'delete_attachments_when_parents_die' )); // have to do this "before", as wp_delete_post detaches all attachments before the 'delete_post' action, which left us unable to retrieve connected attachments... 12 add_filter( 'gettext', array(__CLASS__, 'modify_core_language' ), 20, 3); 13 add_filter( 'ngettext', array(__CLASS__, 'modify_core_language' ), 20, 3); 14 // add_filter( 'login_redirect', array(__CLASS__, 'dashboard_redirect' )); 15 add_filter( 'add_menu_classes', array(__CLASS__, 'show_pending_number')); 16 // add_filter( 'wp_die_handler', array(__CLASS__, 'soma_wp_die_handler'),10,3); 17 add_filter( 'editable_roles', array(__CLASS__, 'editable_roles')); 18 add_filter( 'map_meta_cap', array(__CLASS__, 'admin_map_meta_cap'), 10, 4); 19 remove_filter('check_comment_flood', 'check_comment_flood_db'); // deal with "posting too quickly" problem.... 20 add_filter( 'edit_posts_per_page', array(__CLASS__, 'edit_list_length')); 21 add_action( 'wp_ajax_unlink_file', array(__CLASS__, 'ajax_unlink_file')); 22 add_action( 'wp_ajax_delete_attachment', array(__CLASS__, 'ajax_delete_attachment')); 23 add_action( 'admin_notices', array(__CLASS__,'soma_admin_notices'), 100); 24 } 25 26 function init() { 27 // localization init needed?? no translations yet 28 // load_plugin_textdomain( 'stock-media-asset-manager', SOMA_DIR . '/lang', basename( dirname( __FILE__ ) ) . '/lang' ); 29 // self::session_manager(); /// WARNING this occasionally causes PHP errors: "Cannot send session cache limiter - headers already sent" -- do we need this? 30 self::wp_version_check(); 31 self::check_staff(); 32 } 33 34 // displays notices using the core wp messge box. 35 function soma_admin_notices() { 36 // if (soma_fetch_index($_GET['soma-notify']) == true) { 37 // if (get_query_var('soma_notify') == true) { 38 $notices = get_transient('soma_notices'); // check if any waiting 39 if ($notices === false) return; 40 foreach ($notices as $notice) { 41 if (empty($notice['msg'])) continue; 42 if (empty($notice['type'])) $notice['type'] == 'updated'; 43 echo "<div class='{$notice['type']}'>"; 44 echo "<p>{$notice['msg']}</p>"; 45 echo "</div>"; 46 } 47 // } 48 delete_transient('soma_notices'); 49 } 50 51 // adds an admin notice message to the queue. can use 'updated', or 'error' 52 function queue_notice($type = 'updated', $msg) { 53 $notices = get_transient( 'soma_notices' ); // grab any existing notices 54 if ($notices === false || !is_array($notices)) $notices = array(); // or init 55 $notices[] = array('type' => $type, 'msg' => $msg); // add to the queue 56 set_transient( 'soma_notices', $notices ); // store it 57 } 58 59 // adds an admin notice as well as reloads the page to display the notice. good for returning the result of a custom manipulation function without leaving the page 60 function completion_notice($type, $msg) { 61 somaFunctions::queue_notice($type, $msg); 62 // $result = add_query_arg( 'soma_notify', 'true', $_SERVER['HTTP_REFERER'] ); // used to be needed to trigger, but now we just check for the transient itself 63 // wp_redirect( $result ); 64 wp_redirect( $_SERVER['HTTP_REFERER'] ); 65 exit; // this halts everything, so this better be your last function call 66 } 67 68 // set if user has staff privileges (default to editors) 69 function check_staff() { 70 $privs = 'edit_others_posts'; 71 $privs = apply_filters('soma_staff_privs', $privs); 72 define( 'SOMA_STAFF', current_user_can( $privs )); 73 } 74 75 // changes how many items are shown per page in /wp-admin/edit.php 76 function edit_list_length() { 77 return 40; 78 } 79 80 // checks if something is truly empty (not set) or null, and not simply set to a valid but negative value, like false or - 0 (0 as an integer) - 0.0 (0 as a float) - "0" (0 as a string) 81 // NOTE: THIS DOESN'T AVOID THE PHP NOTICE ERROR IF SOMETHING DOESN'T EXIST (not set) 82 function is_blank( $value ) { 83 return empty( $value ) && !is_numeric( $value ) && $value !== false; 84 } 85 86 // checks if array is associative or not 87 function array_is_associative($arr) { 88 if (!is_array($arr)) return false; 89 return array_keys($arr) !== range(0, count($arr) - 1); 90 } 91 92 // returns URL to facebook image from facebook ID stored in post_meta 93 function fetch_facebook_pic($pid, $size = "square") { 94 // sizes: square, small, normal, large 95 96 $fid = somaFunctions::asset_meta('get', $pid, 'facebook_id'); 97 if (!$fid) return SOMA_IMG . '/generic-female-thumb.png'; 98 99 // $userurl = "http://graph.facebook.com/$fid"; 100 // $user = json_decode(file_get_contents($userurl)); 101 // $feedurl = "http://graph.facebook.com/$fid/feed"; 102 // $feed = json_decode(file_get_contents($feedurl)); 103 return "https://graph.facebook.com/$fid/picture?type=$size"; 104 } 105 106 // since our postmeta is serialized, to query posts by postmeta requires retrieving a set of posts and then checking each entry against the desired postmeta for matches 107 function fetch_posts($args, $meta_key = null, $meta_value = null) { 108 if (!is_array($args)) return null; 109 $args['numberposts'] = -1; // always retrieve all, not just first 5 110 $items = get_posts($args); 111 $matches = array(); 112 foreach ($items as $item) { 113 $val = somaFunctions::asset_meta('get', $item->ID, $meta_key); 114 if ($val == $meta_value) { 115 $matches[] = $item; 116 } 117 } 118 return $matches; 119 } 120 121 // retrieves array of user objects for a given role name 122 function get_role_members_OLD($rolename) { 123 $blogusers = get_users_of_blog(); 124 $members = array(); 125 foreach ($blogusers as $user) { 126 $userdata = get_userdata($user->ID); 127 // check role name 128 if ($userdata->wp_capabilities[$rolename] == '1') { 129 // add to new role array 130 $members[] = $userdata; 131 } 132 } 133 return $members; 134 } 135 136 137 // retrieves array of user objects for a given role name 138 function get_role_members($roles = null) { 139 if (!$roles) return false; 140 // convert to array if single 141 if (!is_array($roles)) { 142 $roles = array($roles); 143 } 144 // init output array 145 $members = array(); 146 global $wp_roles; 147 foreach ($roles as $role) { 148 if (!array_key_exists($role, $wp_roles->roles)) continue; // abort if given a non-existant role (otherwise the user_query will return everyone) 149 $wp_user_search = new WP_User_Query( array( 'role' => $role) ); 150 // wp_die(var_dump($wp_user_search)); 151 $users = $wp_user_search->get_results(); 152 if (empty($users)) continue; 153 foreach ($users as $user) { 154 $members[] = $user; 155 } 156 } 157 return $members; 158 } 159 160 // retrieves name of role assigned to pass user id or current user if not provided 161 function get_user_role( $uid = null ) { 162 if (!$uid) { 163 $user = wp_get_current_user(); 164 } else { 165 $user = new WP_User( $uid ); 166 } 167 if ( !empty( $user->roles ) && is_array( $user->roles ) ) { 168 foreach ( $user->roles as $role ) 169 return $role; 170 } 171 } 172 173 // comparison function for usort - allows sorting of arrays of objects by object properties 174 function usort_displaynames($a, $b) { 175 if ($a->display_name == $b->display_name) 176 return 0; 177 else 178 return ($a->display_name < $b->display_name ? -1 : 1); 179 } 180 181 // comparison function for usort - allows sorting of arrays of objects by object properties 182 function usort_ids($a, $b) { 183 if ($a->ID == $b->ID) 184 return 0; 185 else 186 return ($a->ID < $b->ID ? -1 : 1); 187 } 188 189 // checks to see if $_GET or $_POST values are set, avoids Undefined index error 190 function fetch_index($array, $index) { 191 if (!is_array($array)) return null; 192 return isset($array[$index]) ? $array[$index] : null; 193 } 194 195 // 196 function fetch_author($author_id = null, $output = "display_name") { 197 if ($author_id != null) { 198 $user = get_userdata($author_id); 199 if ($user == null) { 200 return new WP_Error('missing','can\'t find the user...'); 201 } 202 } else { 203 return new WP_Error('missing','must provide author id...'); 204 } 205 // $code = get_the_author_meta( somaMetaboxes::$meta_prefix .'user_code', $post->post_author ); 206 // $code = get_the_author_meta( 'user_exclusive', $post->post_author ); 207 208 if ($output == "link") { 209 if (is_admin()) { 210 $url = admin_url() . "edit.php?author=" . $user->ID; 211 $url .= $type ? "&post_type=".$type : ""; 212 } else { 213 $url = home_url() . "?author=" . $user->ID; 214 $url .= $type ? "&post_type=" . $type : ""; 215 } 216 return "<a href=\"" . $url . "\">". $user->display_name . "</a>"; 217 } 218 return $user->$output; 219 } 220 221 // 222 function fetch_post_author($post_id = null, $output = "display_name" ) { 223 if (!$post_id) { 224 global $post; 225 if ($post == null) { 226 return new WP_Error('missing','can\'t find the post...'); 227 } 228 } else { 229 $post = get_post($post_id); 230 } 231 $type = $post->post_type; 232 $user = get_userdata($post->post_author); 233 234 // $code = get_the_author_meta( somaMetaboxes::$meta_prefix .'user_code', $post->post_author ); 235 // $code = get_the_author_meta( 'user_exclusive', $post->post_author ); 236 237 if ($output == "link") { 238 if (is_admin()) { 239 $url = admin_url() . "edit.php?author=" . $user->ID; 240 $url .= $type ? "&post_type=".$type : ""; 241 } else { 242 $url = home_url() . "?author=" . $user->ID; 243 $url .= $type ? "&post_type=" . $type : ""; 244 } 245 return "<a href=\"" . $url . "\">". $user->display_name . "</a>"; 246 } 247 return $user->$output; 248 } 249 250 // 251 function fetch_current_user($output = "display_name") { 252 global $current_user; 253 if ($current_user == null) { 254 return new WP_Error('missing','can\'t find the user...'); 255 } 256 257 if ($output == "link") { 258 if (is_admin()) { 259 $url = admin_url() . "edit.php?author=" . $current_user->ID; 260 $url .= $type ? "&post_type=".$type : ""; 261 } else { 262 $url = home_url() . "?author=" . $current_user->ID; 263 $url .= $type ? "&post_type=" . $type : ""; 264 } 265 return "<a href=\"" . $url . "\">". $current_user->display_name . "</a>"; 266 } 267 return $current_user->$output; 268 } 269 270 271 //** clone of core get_the_term_list() - modifies the URL output if inside admin to stay in admin and to link to the edit post listing screen, also - can output comma separated string instead of links 272 function fetch_the_term_list( $id = null, $taxonomy, $before = '', $sep = ', ', $after = '', $output = 'html' ) { 273 if (is_null($id)) return false; 274 $terms = wp_get_object_terms( $id, $taxonomy ); 275 $type = get_post_type($id); 276 if ( is_wp_error( $terms ) ) 277 return $terms->get_error_message(); 278 if ( empty( $terms ) ) 279 return false; 280 // create array with links 281 if ($output == "html") { 282 foreach ( $terms as $term ) { 283 // within admin, link to the admin edit post list screen, but filtering for this taxonomy term 284 if (is_admin()) { 285 $link = admin_url() . "edit.php?" . $taxonomy . "=" . $term->slug . "&post_type=" . $type; 286 } else { 287 $link = get_term_link( $term, $taxonomy ); 288 } 289 if ( is_wp_error( $link ) ) 290 return $link->get_error_message(); 291 $term_links[] = '<a href="' . $link . '" rel="tag">' . $term->name . '</a>'; 292 } 293 // create plain string of comma-separated names 294 } 295 if ($output == "text") { 296 foreach ($terms as $term) { 297 $term_links[] = $term->name; 298 } 299 } 300 301 // outputs a vertical stack table for items in the edit.php listing 302 if ($output == "table") { 303 if (!is_admin()) return false; 304 305 $table = "<table>"; 306 $i = 1; 307 $max = count($terms); 308 foreach ($terms as $term) { 309 // avoid border on last entry 310 if ($i == $max) { 311 $table .= "<tr><td class=\"last\">"; 312 } else { 313 $table .= "<tr><td>"; 314 } 315 $link = admin_url() . "edit.php?" . $taxonomy . "=" . $term->slug . "&post_type=" . $type; 316 $table .= "<a href=\"".$link."\" rel=\"tag\">$term->name</a></td></tr>"; 317 $i++; 318 } 319 $table .= "</table>"; 320 return $table; 321 } 322 323 return $before . join( $sep, $term_links ) . $after; 324 } 325 326 // retrieves taxonomy terms that are used in a singular way (only one possible state, ie ON or OFF) 327 function fetch_the_singular_term( $post, $taxonomy, $label = "slug" ) { 328 if (is_wp_error($post)) return $post; 329 if (empty($post)) return new WP_Error('missing', "must pass a post argument!"); 330 if (is_object($post)) { 331 $pid = $post->ID; 332 } else { 333 $pid = intval($post); 334 } 335 336 $term = wp_get_object_terms( $pid, $taxonomy ); 337 if (is_wp_error($term) || empty($term)) return null; // taxonomy doesn't exist OR there are no terms assigned 338 if ($label == 'slug') { 339 return $term[0]->slug; 340 } 341 if ($label == 'name') { 342 return $term[0]->name; 343 } 344 if ($label == 'link') { 345 if (is_admin()) { 346 $link = admin_url() . "edit.php?" . $taxonomy . "=" . $term[0]->slug . "&post_type=" . get_post_type($pid); 347 } else { 348 $link = get_term_link( $term[0] ); 349 } 350 return '<a href="' . $link . '">' . $term[0]->name . '</a>'; 351 } 352 if ($label == 'id' || $label == 'term_id') { 353 return $term[0]->term_id; 354 } 355 return null; 356 } 357 358 359 //** for retrieving p2p connected posts 360 // can output count, array of post objects, list of html links, list of text, a table of links, or select dropdown input values 361 // note - modifies the URL output if inside wp-admin to stay in admin and to link to the edit post listing screen rather than the post permalink 362 // $pid = can be single integer or array of post ID's 363 // $p2pname = the name of the connection you made with "p2p_register_connection_type" 364 // $dir = connection direction (to, from, any) 365 // $output = how to format the return data 366 367 function fetch_connected_items( $pid = 0, $p2pname, $dir = 'any', $output = 'html', $sep = ", " ) { 368 if (!function_exists('p2p_register_connection_type')) return 'No P2P plugin!'; // make sure plugin is enabled 369 370 // https://github.com/scribu/wp-posts-to-posts/wiki/Query-vars 371 372 $args = array( 'connected_type' => $p2pname ); 373 switch( $dir ) { 374 case "to" : 375 $args['connected_to'] = $pid; 376 break; 377 case "from" : 378 $args['connected_from'] = $pid; 379 break; 380 default : 381 $args['connected_items'] = $pid; // this passes "any" for direction 382 break; 383 } 384 385 if ($meta_key && $meta_value) { 386 $args['connected_meta'] = array( 387 $meta_key => $meta_value 388 ); 389 } 390 391 $query = new WP_Query( $args ); 392 $items = array(); 393 $items = $query->posts; 394 395 if ( is_wp_error( $items ) ) 396 return $items->get_error_message();; 397 398 // output how many connected items 399 if ($output == "count") { 400 if ( empty( $items ) ) return 0; 401 return count($items); 402 } 403 404 405 // simply output the array of matching post objects 406 if ($output == "objects") { 407 if ( empty( $items ) ) return false; 408 return $items; 409 } 410 411 // create array with links 412 if ($output == "html") { 413 if ( empty( $items ) ) return false; 414 foreach ( $items as $item ) { 415 // within admin, link to the admin edit post list screen, but filtering for this taxonomy term 416 if (is_admin()) { 417 $link = get_edit_post_link($item->ID); 418 } else { 419 $link = get_permalink($item->ID); 420 } 421 if ( is_wp_error( $link ) ) 422 return $link->get_error_message();; 423 $item_list[] = '<a href="' . $link . '">' . $item->post_title . '</a>'; 424 } 425 return $before . join( $sep, $item_list ) . $after; 426 427 // return p2p_list_posts( p2p_type( $p2pname )->get_connected( $post->ID ) ); // a helpful function from scribu to do the same thing ;-) 428 } 429 430 // create plain string of comma-separated names 431 if ($output == "text") { 432 if ( empty( $items ) ) return false; 433 foreach ($items as $item) { 434 $item_list[] = $item->post_title; 435 } 436 return $before . join( $sep, $item_list ) . $after; 437 } 438 439 // outputs a vertical stack table for items in the edit.php listing 440 if ($output == "table") { 441 if (!is_admin()) return false; 442 if ( empty( $items ) ) return false; 443 // generate table html 444 $table = "<table>"; 445 $i = 1; 446 $max = count($items); 447 foreach ($items as $item) { 448 // avoid border on last entry 449 if ($i == $max) { 450 $table .= "<tr><td class=\"last\">"; 451 } else { 452 $table .= "<tr><td>"; 453 } 454 $table .= "<a href=\"".get_edit_post_link($item->ID)."\">$item->post_title</a></td></tr>"; 455 $i++; 456 } 457 $table .= "</table>"; 458 return $table; 459 } 460 461 // outputs an array for populating select dropdown inputs 462 if ($output == "select") { 463 if ( empty( $items ) ) { 464 return array(array('name' => '[nothing to select]', 'value' => '0')); // no user role matches, output empty list 465 } 466 foreach ($items as $item) { 467 $list[] = array('name' => $item->post_title, 'value' => intval($item->ID)); 468 } 469 return $list; 470 } 471 } 472 473 474 //** generates mini box html output of asset ------------------------------------------------------// 475 function mini_asset_output($items) { 476 if (!is_array($items)) { 477 $items = array($items); 478 } 479 $html = "<div class=\"mini-asset-list\">\n"; 480 $html .= "<ul class=\"slider\">\n"; 481 482 foreach ($items as $item) { 483 484 $view = get_permalink($item->ID); 485 $edit = get_edit_post_link($item->ID); 486 $title = get_the_title($item->ID); 487 $services = somaFunctions::fetch_the_term_list($item->ID, 'service','','<br/>','','html'); 488 $status = somaFunctions::fetch_the_singular_term($item->ID, 'app_status'); 489 $type = $item->post_type; 490 $img = somaFunctions::fetch_featured_image($item->ID); 491 492 493 $html .= "<li class=\"item $status\">\n"; 494 495 $html .= "\t<ul>\n"; 496 497 // in admin, click image to edit the item, in front-end, click image to go to single asset view 498 // if (is_admin()) { 499 // if ( $review ) { 500 // // add lightbox link to image 501 // $html .= "\t<li class=\"post-thumb\"><a class=\"lightbox\" rel=\"gallery\" href=\"{$img['large']['url']}\"><img src=\"{$img['thumbnail']['url']}\" /></a></li>\n"; 502 // } else { 503 // // add edit link to image 504 // $html .= "\t<li class=\"post-thumb\"><a href=\"". get_edit_post_link($item->ID) ."\"><img src=\"{$img['thumbnail']['url']}\" /></a></li>\n"; 505 // } 506 // } else { 507 // // add view link to image 508 // $html .= "<li class=\"post-thumb\"><a href=\"". get_permalink($item->ID) . "\"><img src=\"{$img['thumbnail']['url']}\" /></a></li>\n"; 509 // } 510 511 512 $html .= "\t\t<li class=\"asset-thumb\">\n"; 513 514 $html .= "\t\t\t<a href=\"$edit\"><div class=\"fb-thumb\"><img src=\"{$img['thumbnail']['url']}\"/></a></div>\n"; 515 // $html .= "\t\t\t<a href=\"$edit\"><img src=\"{$img['thumbnail']['url']}\"/></a>\n"; 516 $html .= "\t\t</li>\n"; 517 518 $html .= "\t\t<li class=\"title\"><strong><a href=\"$edit\">". get_the_title($item->ID). "</a></strong></li>\n"; 519 520 // $html .= "\t\t<li class=\"services\">". $services . "</li>\n"; 521 522 // $html .= "\t\t<li class=\"creator\">". somaFunctions::fetch_post_author( $item->ID) ."</li>\n"; 523 524 525 if ($type == "classes") { 526 $conn = get_posts( array( 527 'post_type' => array('clients'), 528 'suppress_filters' => false, 529 'numberposts' => -1, 530 'connected' => $item->ID, 531 ) ); 532 $max = somaFunctions::asset_meta('get', $item->ID, 'class_max'); 533 if (!$max) $max = "?"; 534 $count = count( $conn); 535 $html .= "\t\t<li class=\"count\">" .$count . " Enrolled / $max Max</li>\n"; 536 $html .= "\t\t<li class=\"type\">$type</li>\n"; // minibox label 537 } else { 538 $html .= "\t\t<li class=\"type\">$status</li>\n"; // minibox label 539 } 540 541 $html .= "\t</ul>\n"; 542 $html .= "</li>\n"; 543 } 544 $html .= "</ul>\n"; 545 $html .= "</div>\n"; 546 return $html; 547 } 548 549 // need this? 550 function extract_numbers($string) { 551 preg_match_all('/([\d]+)/', $string, $match); 552 return $match[0]; 553 } 554 555 // automatically sends user to dashboard after login, instead of their profile page 556 function dashboard_redirect($url) { 557 global $user; 558 // if ($user->roles[0] == 'foo') 559 // return 'wp-admin/admin.php?page=foo-user-page'; 560 return 'wp-admin/index.php'; 561 } 562 563 /** 564 * Performs a query for results within a set of multiple terms (matching any one of, not all) 565 * 566 * @param string $type (required) Post Type slug 567 * @param string $tax (required) Taxonomy slug 568 * @param array strings $terms (required) Term slugs to match within 569 * @return array of objects 570 */ 571 function multi_term_query($type = null, $tax = null, $terms = null) { 572 global $wpdb; 573 574 if (!$type || !$tax || !is_array($terms)) { 575 wp_die('missing an argument...'); 576 } 577 578 $querystr = "SELECT * 579 FROM $wpdb->posts 580 LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id) 581 LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) 582 LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id) 583 WHERE $wpdb->posts.post_type = '$type' 584 AND $wpdb->posts.post_status = 'publish' 585 AND $wpdb->term_taxonomy.taxonomy = '$tax' 586 AND ("; 587 $i = 1; 588 foreach ($terms as $term) { 589 $querystr .= "$wpdb->terms.slug = '$term'"; 590 if ($i < count($terms)) { 591 $querystr .= " OR "; 592 } 593 $i++; 594 } 595 596 $querystr .= ")\nORDER BY $wpdb->posts.post_date ASC"; 597 // echo $querystr; 598 $posts = $wpdb->get_results($querystr, OBJECT); 599 return $posts; 600 } 601 602 603 // add_action('post_submitbox_misc_actions','my_post_submitbox_misc_actions'); 604 function my_post_submitbox_misc_actions() { 605 ?> 606 <script type="text/javascript"> 607 jQuery(document).ready(function($) { 608 $("#misc-publishing-actions select#post_status option[value='pending']").remove(); 609 }); 610 </script> 611 <?php 612 } 613 614 // changes words throughout wordpress 615 function modify_core_language( $translated ) { 616 // $translated = str_replace( 'Publish', 'Ingest', $translated ); 617 // $translated = str_replace( 'Dashboard', 'Overview', $translated ); 618 $translated = str_replace( 'featured', 'assigned', $translated ); 619 $translated = str_replace( 'Start typing the title of a post', 'Start typing the title of an asset', $translated ); // p2p metabox 620 // $translated = str_replace( 'Post', 'Article', $translated ); 621 return $translated; 622 } 623 624 // deletes all attachments (including the actual files on server) when a post is deleted -- custom post type args or this post's post_meta must be set for this to happen, so its not universal 625 function delete_attachments_when_parents_die($post_id) { 626 $metakill = somaFunctions::asset_meta('get', $post_id, 'delete_attachments_upon_deletion'); 627 $ptype = get_post_type($post_id); 628 $ptobj = get_post_type_object($ptype); 629 $typekill = $ptobj->delete_attachments_upon_deletion; 630 if ( $metakill || $typekill ) { 631 global $wpdb; 632 $attids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_parent = %d AND post_type = %s", $post_id, 'attachment')); // properly prepared safe query 633 foreach ( $attids as $attid ) { 634 wp_delete_attachment($attid); 635 } 636 } 637 } 638 639 //** allows use of custom field data in the query vars URL string. without this, would need to call the query_posts() function and pass meta_key/meta_value... 640 function custom_query_vars($qvars) { 641 $qvars[] = "meta_key"; 642 $qvars[] = "meta_value"; 643 $qvars[] = "meta_compare"; 644 return $qvars; 645 } 646 647 //** modifies the QUERY before output ------------------------------------------------------// 648 function filter_current_query($query) { 649 return $query; 650 } 651 652 // this is much like filter_current_query 653 function pre_get_posts($query) { 654 // wp_die(var_dump($query)); 655 return $query; 656 } 657 658 /** 659 659 * Merge new query parameters with existing parameters. 660 660 * … … 678 678 } 679 679 680 //** retrieves featured image of a post, or an attachment itself and returns array of intermediate sizes, paths, urls ----------------------------------------------------------------------------------// 681 public function fetch_featured_image($post = null, $specific = null) { 682 if (is_wp_error($post)) return $post; 683 if (empty($post)) return new WP_Error('missing', "must pass a post argument!"); 684 if (is_object($post)) { 685 $pid = $post->ID; 686 } else { 687 $pid = intval($post); 688 } 689 690 $img = array(); // container 691 692 // fetch id of featured image attachment 693 if (has_post_thumbnail($pid)) { 694 $att_id = get_post_thumbnail_id($pid); 695 } 696 697 // post is already attachment - just pass ID 698 if (get_post_type($pid) == 'attachment') { 699 $att_id = $pid; 700 } 701 702 // some attachment successfully found 703 if ($att_id) { 704 $att_meta = wp_get_attachment_metadata($att_id); // get metadata of attachment 705 if ( !empty( $att_meta['subdir'] ) ) { // the original SMAM system generates this custom attachment meta when it created upload directories based on type/author. If it exists, use it 706 $subdir = $att_meta['subdir'] . '/'; 707 } 708 $dirname = dirname( $att_meta['file'] ); // when "Organize my uploads into month- and year-based folders" is turned on, the date subfolder is stored in file path 709 if ( $dirname == "." ) { // no subdirectory path is needed 710 $subdir = "/"; 711 } else { 712 $subdir = '/'. dirname($att_meta['file']) . '/'; 713 } 714 // build the paths from the base media upload dir and the subdir 715 $media_path = WP_MEDIA_DIR . $subdir; 716 $media_url = WP_MEDIA_URL . $subdir; 717 718 // NEW ARRAY 719 $img['id'] = $att_id; 720 721 // 'sizes' key will only exist if the uploaded image was equal or larger than the site option for thumbnail size 722 if ( !is_null( somaFunctions::fetch_index( $att_meta, 'sizes' ) ) && !empty( $att_meta[ 'sizes' ] ) ) { 723 // loop through all available image sizes, including any custom ones via add_image_size() 724 foreach ($att_meta['sizes'] as $size => $data) { 725 $img[$size]['file'] = $data['file']; 726 $img[$size]['height'] = $data['height']; 727 $img[$size]['width'] = $data['width']; 728 $img[$size]['url'] = $media_url . $img[$size]['file']; 729 $img[$size]['path'] = $media_path . $img[$size]['file']; 730 } 731 $img['full']['file'] = basename($att_meta['file']); // $att_meta['file'] contains the entire server path, so extract just the name 732 $img['full']['url'] = $media_url . $img['full']['file']; 733 $img['full']['path'] = $media_path . $img['full']['file']; 734 $img['full']['height'] = $att_meta['height']; 735 $img['full']['width'] = $att_meta['width']; 736 $img['loc']['path'] = $media_path; 737 $img['loc']['url'] = $media_url; 738 739 // populate thumb data with the direct file info, as the uploaded image was smaller or equal to the site option for thumbnail size. Yes, the thumb and the full img info are the same in this case... 740 } else { 741 $img['thumbnail']['file'] = basename($att_meta['file']); 742 $img['thumbnail']['height'] = $att_meta['height']; 743 $img['thumbnail']['width'] = $att_meta['width']; 744 $img['thumbnail']['url'] = WP_MEDIA_URL . '/'. $att_meta['file']; // don't include subdir when building paths, as we're taking path directly from 'file', which already includes it... 745 $img['thumbnail']['path'] = WP_MEDIA_DIR . '/'. $att_meta['file']; 746 $img['full']['file'] = basename($att_meta['file']); 747 $img['full']['url'] = WP_MEDIA_URL . '/'. $att_meta['file']; 748 $img['full']['path'] = WP_MEDIA_DIR . '/'. $att_meta['file']; 749 $img['full']['height'] = $att_meta['height']; 750 $img['full']['width'] = $att_meta['width']; 751 $img['loc']['path'] = WP_MEDIA_DIR; 752 $img['loc']['url'] = WP_MEDIA_URL; 753 754 //** FUTURE NOTE: might be good when there isn't a medium or large version of the image to default to some kind of "missing" image that actually says "image was too small" 755 } 756 757 $img['mime'] = get_post_mime_type($att_id); // mime-type of file 758 $img['date'] = get_the_date('M j, Y',$att_id) ." - ". get_the_time('h:iA',$att_id); // date attachment was created 759 $img['orientation'] = somaFunctions::fetch_index($att_meta, 'orientation'); // custom attribute, generated with ACME system 760 $img['original'] = somaFunctions::fetch_index($att_meta, 'original'); // custom attribute, generated with ACME system 761 762 // should we pass along? too confusing... use the typical meta fields below instead 763 // $img['image_meta'] = $att_meta['image_meta']; 764 765 // need to fetch the post from the table to get all the extra fields 766 $att_post = get_post($att_id); 767 $img['title'] = $att_post->post_title; 768 $img['description'] = $att_post->post_content; 769 $img['caption'] = $att_post->post_excerpt; 770 $img['alt'] = get_post_meta($att_id, '_wp_attachment_image_alt', true); 771 772 } else { 773 // nothing found, return generic placeholder image 774 $img['id'] = false; 775 $sizes = get_intermediate_image_sizes(); 776 foreach ($sizes as $size) { 777 $img[$size]['url'] = SOMA_IMG . 'placeholder-image.png'; 778 } 779 $img['thumbnail']['width'] = SOMA_THUMB_WIDTH; 780 $img['thumbnail']['height'] = SOMA_THUMB_HEIGHT; 781 $img['full']['name'] = 'MISSING IMAGE'; 782 $img['full']['url'] = SOMA_IMG . 'placeholder-image.png'; 783 $img['file']['path'] = SOMA_DIR . 'images/placeholder-image.png'; 784 $img['file']['file'] = 'placeholder-image.png'; 785 } 786 787 // return just the requested URL 788 if (!is_null($specific)) { 789 if ($specific == 'filename') return $img['full']['file']; 790 if (isset($att_meta['sizes']) && is_array($att_meta['sizes'])) { 791 if (array_key_exists($specific, $img)) { 792 return $img[$specific]['url']; // this allows for custom image sizes to be passed via $specific 793 } else { 794 return $img['full']['url']; // couldn't find the size requested, so just give original file 795 } 796 } else { 797 return null; // no sizes have been generated for this attachment 798 } 799 } else { 800 return $img; // return array of variants 801 } 802 803 } 804 805 // handles saving and retrieving post_meta via serialized arrays 806 public function asset_meta( $action = null, $post = null, $key = null, $value = null, $serialize = null, $use_prefix = true ) { 807 if (is_wp_error($post)) return $post; 808 if ( empty($post) || empty($action) ) return new WP_Error('missing', "Must pass ID and action..."); 809 if (is_object($post)) { 810 $pid = $post->ID; 811 } else { 812 $pid = intval($post); 813 } 814 815 816 global $soma_options; // fetch options 817 if ( $serialize === null ) { 818 $serialize = somaFunctions::fetch_index($soma_options, 'meta_serialize'); // use default var if not passed in params 819 if ($serialize == 1) { // explicit true if evaluates as true 820 $serialize = true; 821 } else { 822 $serialize = false; // default false 823 } 824 } 825 $prefix = $soma_options['meta_prefix']; 826 // if we're supposed to use a prefix and we have one... 827 if ( $use_prefix && !empty($prefix) ) { 828 if ( $serialize ) { 829 $meta_key = $prefix . "_asset_meta"; 830 } else { 831 $meta_key = $prefix . "_" . $key; 832 } 833 } else { 834 // just use the given key, no prefix 835 $meta_key = $key; 836 } 837 838 839 840 switch ( $action ) { 841 case ('save') : 842 if (!$key) return new WP_Error('missing', "Must specify a field to save to..."); 843 if (!$value) return new WP_Error('missing', "Missing a value for $key..."); 844 845 $post_meta = get_post_meta( $pid, $meta_key, true); // retrieve meta 846 if (empty($value)) { 847 if ( $serialize ) { 848 unset($post_meta[$key]); // remove key if value is empty (otherwise key will be saved with blank value) 849 } else { 850 return delete_post_meta( $pid, $meta_key ); // trash meta because value is empty 851 } 852 } else { // set new value 853 if ( $serialize ) { 854 $post_meta[$key] = $value; 855 } else { 856 $post_meta = $value; 857 } 858 } 859 return update_post_meta( $pid, $meta_key, $post_meta ); // rewrite the array to post_meta 860 break; 861 862 case ('get') : 863 $post_meta = get_post_meta( $pid, $meta_key, true); // retrieve meta 864 if ( $serialize ) { 865 if (!$key) return $post_meta; // return whole meta array if no field specified 866 return $post_meta[$key]; // return field 867 } else { 868 return $post_meta; 869 } 870 break; 871 872 case ('delete') : 873 // if (!$key) return delete_post_meta( $pid, $meta_key ); // note: this deletes the whole meta_key, all fields lost 874 if (!$key) return new WP_Error('missing', "Missing a key..."); 875 $post_meta = get_post_meta( $pid, $meta_key, true); // retrieve meta 876 if ( !empty( $post_meta ) ) { // if there was data to be deleted, proceed 877 if ( $serialize ) { 878 unset($post_meta[$key]); // trash meta 879 return update_post_meta( $pid, $meta_key, $post_meta ); // rewrite the array to post_meta 880 } else { 881 return delete_post_meta( $pid, $meta_key ); // trash meta 882 } 883 } else { // nothing to delete, so don't bother (this happens when post gets saved with fields still blank, and the save_post functions attempt to clear the metadata) 884 return false; 885 } 886 break; 887 888 default : 889 return new WP_Error('action', "First parameter must be 'save', 'get', or 'delete'..."); 890 break; 891 } 892 } 893 894 895 // returns all attachments (except featured image) 896 public function fetch_attached_media($post = null, $mime = null, $include_featured = false) { 897 if (is_wp_error($post)) return $post; 898 if (empty($post)) return new WP_Error('missing', "must pass a post argument!"); 899 if (is_object($post)) { 900 $pid = $post->ID; 901 } else { 902 $pid = intval($post); 903 } 904 905 $args = array( 906 'post_parent' => $pid, 907 'post_type' => 'attachment', 908 'numberposts' => -1, 909 'post_status' => 'any', 910 'orderby' => 'menu_order', 911 'order' => 'ASC', 912 'exclude' => get_post_thumbnail_id($pid), 913 ); 914 if ($include_featured == true) { 915 unset($args['exclude']); 916 } 917 if (!empty($mime)) { 918 // only return requested media type (audio/mpeg, video/mp4, image/jpeg, application/pdf, application/zip) 919 $args['post_mime_type'] = $mime; 920 } 921 // fetch children (results in array of objects, even if only one exists) 922 $kids = get_posts($args); 923 // check if empty 924 $media = ( !empty($kids) ) ? $kids : null; 925 return $media; 926 } 927 928 function session_manager() { 929 if (!session_id()) { 930 session_start(); 931 } 932 $_SESSION['media'] = WP_MEDIA_DIR; 933 $_SESSION['images'] = SOMA_IMG; 934 global $current_user; 935 $_SESSION['user'] = $current_user->data ? $current_user->roles[0] : 'guest'; 936 } 937 938 939 940 //** checks for activation of plugins that somaFramework is dependent on ------------------------------------------------------// 941 function check_plugin_dependency() { 942 // require scribu's p2p plugin 943 global $soma_options; 944 945 if ( somaFunctions::fetch_index($soma_options, 'p2p') && !function_exists('p2p_register_connection_type') ) { 946 add_action( 'admin_notices', create_function('', " 947 echo '<div id=\"message\" class=\"error\" style=\"font-weight: bold\"><p>PLUGIN REQUIRED: \"Posts 2 Posts\" - please <a href=\"http://scribu.net/wordpress/posts-to-posts\" target=\"_blank\">download</a> and/or activate!</p></div>'; 948 ")); 949 } 950 951 // // require companion SOMA theme 952 // $themes = get_themes(); 953 // if (!isset($themes['Stock Media Asset Manager'])) { // theme is not installed! 954 // add_action('admin_notices', 'theme_install_error_msg' ); 955 // function theme_install_error_msg() { 956 // echo '<div id="message" class="error" style="font-weight: bold">'; 957 // echo '<p>THEME MISSING: "Stock Media Asset Manager" - please <a href="' . network_admin_url() .'/themes.php">install!</a></p>'; 958 // echo '</div>'; 959 // } 960 // } 961 // if (get_current_theme() != 'Stock Media Asset Manager') { // theme is not activated! 962 // add_action('admin_notices', 'theme_active_error_msg' ); 963 // function theme_active_error_msg() { 964 // echo '<div id="message" class="updated" style="font-weight: bold">'; 965 // echo '<p>THEME NOT ACTIVE: "Stock Media Asset Manager" - please <a href="' . network_admin_url() .'/themes.php">activate!</a></p>'; 966 // echo '</div>'; 967 // } 968 // } 969 } 970 971 //** generates full current url string with current query vars ------------------------------------------------------// 972 function get_current_url() { 973 $urlis = 'http://' . $_SERVER['HTTP_HOST'] . htmlentities($_SERVER['PHP_SELF']) . $_SERVER['REQUEST_URI']; 974 return $urlis; 975 } 976 977 // displays warning error msg if wp version too old ------------------------------------------------------// 978 function wp_version_check() { 979 global $wp_version; #wp 980 $new_admin_version = '4.4'; 981 $updateURL = ""; 982 if (version_compare($wp_version, $new_admin_version, '<')) { 983 add_action( 'admin_notices', create_function('', " 984 echo '<div id=\"message\" class=\"error\" style=\"font-weight: bold\"><p>WORDPRESS 4.4 MINIMUM REQUIRED - please update WP or de-activate this plugin!</p></div>'; 985 ")); 986 } 987 } 988 989 /** 990 * Displays (and returns) total number of posts within specified categories 991 * 992 * @param string $catslugs Comma separated category slugs 993 * @param bool $display (optional) Echo the result? 994 * @return int Post count 995 */ 996 function in_category_count($catslugs = '', $display = true) { 997 global $wpdb; 998 999 $post_count = 0; 1000 $slug_where = ''; 1001 $catslugs_arr = explode(',', $catslugs); 1002 1003 foreach ($catslugs_arr as $catslugkey => $catslug) { 1004 if ( $catslugkey > 0 ) { 1005 $slug_where .= ', '; 1006 } 1007 1008 $slug_where .= "'" . trim($catslug) . "'"; 1009 } 1010 1011 $slug_where = "cat_terms.slug IN (" . $slug_where . ")"; 1012 1013 $sql = "SELECT COUNT( DISTINCT cat_posts.ID ) AS post_count " . 1014 "FROM " . $wpdb->term_taxonomy . " AS cat_term_taxonomy INNER JOIN " . $wpdb->terms . " AS cat_terms ON " . 1015 "cat_term_taxonomy.term_id = cat_terms.term_id " . 1016 "INNER JOIN " . $wpdb->term_relationships . " AS cat_term_relationships ON " . 1017 "cat_term_taxonomy.term_taxonomy_id = cat_term_relationships.term_taxonomy_id " . 1018 "INNER JOIN " . $wpdb->posts . " AS cat_posts ON " . 1019 "cat_term_relationships.object_id = cat_posts.ID " . 1020 "WHERE cat_posts.post_status = 'publish' AND " . 1021 "cat_posts.post_type = 'post' AND " . 1022 "cat_term_taxonomy.taxonomy = 'category' AND " . 1023 $slug_where; 1024 1025 $post_count = $wpdb->get_var($sql); 1026 1027 if ( $display ) { 1028 echo $post_count; 1029 } 1030 1031 return $post_count; 1032 } 1033 1034 // are we using this?? 1035 function get_posts_related_by_taxonomySQL($post_id, $taxonomy, $args=array()) { 1036 global $wpdb; 1037 $sql = <<<SQL 1038 SELECT 1039 related.object_id 1040 FROM 1041 {$wpdb->term_relationships} post 1042 INNER JOIN {$wpdb->term_taxonomy} link ON post.term_taxonomy_id = link.term_taxonomy_id 1043 INNER JOIN {$wpdb->term_relationships} related ON post.term_taxonomy_id = related.term_taxonomy_id 1044 WHERE 1=1 1045 AND link.taxonomy=$taxonomy 1046 AND post.object_id=$post_id 1047 AND post.object_id<>related.object_id 1048 AND post.post_type==related.post_type 680 //** retrieves featured image of a post, or an attachment itself and returns array of intermediate sizes, paths, urls ----------------------------------------------------------------------------------// 681 public function fetch_featured_image($post = null, $specific = null) { 682 if (is_wp_error($post)) return $post; 683 if (empty($post)) return new WP_Error('missing', "must pass a post argument!"); 684 if (is_object($post)) { 685 $pid = $post->ID; 686 } else { 687 $pid = intval($post); 688 } 689 690 $img = array(); // container 691 692 // fetch id of featured image attachment 693 if (has_post_thumbnail($pid)) { 694 $att_id = get_post_thumbnail_id($pid); 695 } 696 697 // post is already attachment - just pass ID 698 if (get_post_type($pid) == 'attachment') { 699 $att_id = $pid; 700 } 701 702 // some attachment successfully found 703 if ($att_id) { 704 $att_meta = wp_get_attachment_metadata($att_id); // get metadata of attachment 705 if ( !empty( $att_meta['subdir'] ) ) { // the original SMAM system generates this custom attachment meta when it created upload directories based on type/author. If it exists, use it 706 $subdir = $att_meta['subdir'] . '/'; 707 } 708 $dirname = dirname( $att_meta['file'] ); // when "Organize my uploads into month- and year-based folders" is turned on, the date subfolder is stored in file path 709 if ( $dirname == "." ) { // no subdirectory path is needed 710 $subdir = "/"; 711 } else { 712 $subdir = '/'. dirname($att_meta['file']) . '/'; 713 } 714 // build the paths from the base media upload dir and the subdir 715 $media_path = WP_MEDIA_DIR . $subdir; 716 $media_url = WP_MEDIA_URL . $subdir; 717 718 // NEW ARRAY 719 $img['id'] = $att_id; 720 721 // 'sizes' key will only exist if the uploaded image was equal or larger than the site option for thumbnail size 722 if ( !is_null( somaFunctions::fetch_index( $att_meta, 'sizes' ) ) && !empty( $att_meta[ 'sizes' ] ) ) { 723 // loop through all available image sizes, including any custom ones via add_image_size() 724 foreach ($att_meta['sizes'] as $size => $data) { 725 $img[$size]['file'] = $data['file']; 726 $img[$size]['height'] = $data['height']; 727 $img[$size]['width'] = $data['width']; 728 $img[$size]['url'] = $media_url . $img[$size]['file']; 729 $img[$size]['path'] = $media_path . $img[$size]['file']; 730 } 731 $img['full']['file'] = basename($att_meta['file']); // $att_meta['file'] contains the entire server path, so extract just the name 732 $img['full']['url'] = $media_url . $img['full']['file']; 733 $img['full']['path'] = $media_path . $img['full']['file']; 734 $img['full']['height'] = $att_meta['height']; 735 $img['full']['width'] = $att_meta['width']; 736 $img['loc']['path'] = $media_path; 737 $img['loc']['url'] = $media_url; 738 739 // populate thumb data with the direct file info, as the uploaded image was smaller or equal to the site option for thumbnail size. Yes, the thumb and the full img info are the same in this case... 740 } else { 741 $img['thumbnail']['file'] = basename($att_meta['file']); 742 $img['thumbnail']['height'] = $att_meta['height']; 743 $img['thumbnail']['width'] = $att_meta['width']; 744 $img['thumbnail']['url'] = WP_MEDIA_URL . '/'. $att_meta['file']; // don't include subdir when building paths, as we're taking path directly from 'file', which already includes it... 745 $img['thumbnail']['path'] = WP_MEDIA_DIR . '/'. $att_meta['file']; 746 $img['full']['file'] = basename($att_meta['file']); 747 $img['full']['url'] = WP_MEDIA_URL . '/'. $att_meta['file']; 748 $img['full']['path'] = WP_MEDIA_DIR . '/'. $att_meta['file']; 749 $img['full']['height'] = $att_meta['height']; 750 $img['full']['width'] = $att_meta['width']; 751 $img['loc']['path'] = WP_MEDIA_DIR; 752 $img['loc']['url'] = WP_MEDIA_URL; 753 754 //** FUTURE NOTE: might be good when there isn't a medium or large version of the image to default to some kind of "missing" image that actually says "image was too small" 755 } 756 757 $img['mime'] = get_post_mime_type($att_id); // mime-type of file 758 $img['date'] = get_the_date('M j, Y',$att_id) ." - ". get_the_time('h:iA',$att_id); // date attachment was created 759 $img['orientation'] = somaFunctions::fetch_index($att_meta, 'orientation'); // custom attribute, generated with ACME system 760 $img['original'] = somaFunctions::fetch_index($att_meta, 'original'); // custom attribute, generated with ACME system 761 762 // should we pass along? too confusing... use the typical meta fields below instead 763 // $img['image_meta'] = $att_meta['image_meta']; 764 765 // need to fetch the post from the table to get all the extra fields 766 $att_post = get_post($att_id); 767 $img['title'] = $att_post->post_title; 768 $img['description'] = $att_post->post_content; 769 $img['caption'] = $att_post->post_excerpt; 770 $img['alt'] = get_post_meta($att_id, '_wp_attachment_image_alt', true); 771 772 } else { 773 // nothing found, return generic placeholder image 774 $img['id'] = false; 775 $sizes = get_intermediate_image_sizes(); 776 foreach ($sizes as $size) { 777 $img[$size]['url'] = SOMA_IMG . 'placeholder-image.png'; 778 } 779 $img['thumbnail']['width'] = SOMA_THUMB_WIDTH; 780 $img['thumbnail']['height'] = SOMA_THUMB_HEIGHT; 781 $img['full']['name'] = 'MISSING IMAGE'; 782 $img['full']['url'] = SOMA_IMG . 'placeholder-image.png'; 783 $img['file']['path'] = SOMA_DIR . 'images/placeholder-image.png'; 784 $img['file']['file'] = 'placeholder-image.png'; 785 } 786 787 // return just the requested URL 788 if (!is_null($specific)) { 789 if ($specific == 'filename') return $img['full']['file']; 790 if (isset($att_meta['sizes']) && is_array($att_meta['sizes'])) { 791 if (array_key_exists($specific, $img)) { 792 return $img[$specific]['url']; // this allows for custom image sizes to be passed via $specific 793 } else { 794 return $img['full']['url']; // couldn't find the size requested, so just give original file 795 } 796 } else { 797 return null; // no sizes have been generated for this attachment 798 } 799 } else { 800 return $img; // return array of variants 801 } 802 803 } 804 805 // handles saving and retrieving post_meta via serialized arrays 806 public function asset_meta( $action = null, $post = null, $key = null, $value = null, $serialize = null, $use_prefix = true ) { 807 if (is_wp_error($post)) return $post; 808 if ( empty($post) || empty($action) ) return new WP_Error('missing', "Must pass ID and action..."); 809 if (is_object($post)) { 810 $pid = $post->ID; 811 } else { 812 $pid = intval($post); 813 } 814 815 816 global $soma_options; // fetch options 817 if ( $serialize === null ) { 818 $serialize = somaFunctions::fetch_index($soma_options, 'meta_serialize'); // use default var if not passed in params 819 if ($serialize == 1) { // explicit true if evaluates as true 820 $serialize = true; 821 } else { 822 $serialize = false; // default false 823 } 824 } 825 $prefix = $soma_options['meta_prefix']; 826 // if we're supposed to use a prefix and we have one... 827 if ( $use_prefix && !empty($prefix) ) { 828 if ( $serialize ) { 829 $meta_key = $prefix . "_asset_meta"; 830 } else { 831 $meta_key = $prefix . "_" . $key; 832 } 833 } else { 834 // just use the given key, no prefix 835 $meta_key = $key; 836 } 837 838 839 840 switch ( $action ) { 841 case ('save') : 842 if (!$key) return new WP_Error('missing', "Must specify a field to save to..."); 843 if (!$value) return new WP_Error('missing', "Missing a value for $key..."); 844 845 $post_meta = get_post_meta( $pid, $meta_key, true); // retrieve meta 846 if (empty($value)) { 847 if ( $serialize ) { 848 unset($post_meta[$key]); // remove key if value is empty (otherwise key will be saved with blank value) 849 } else { 850 return delete_post_meta( $pid, $meta_key ); // trash meta because value is empty 851 } 852 } else { // set new value 853 if ( $serialize ) { 854 $post_meta[$key] = $value; 855 } else { 856 $post_meta = $value; 857 } 858 } 859 return update_post_meta( $pid, $meta_key, $post_meta ); // rewrite the array to post_meta 860 break; 861 862 case ('get') : 863 $post_meta = get_post_meta( $pid, $meta_key, true); // retrieve meta 864 if ( $serialize ) { 865 if (!$key) return $post_meta; // return whole meta array if no field specified 866 return $post_meta[$key]; // return field 867 } else { 868 return $post_meta; 869 } 870 break; 871 872 case ('delete') : 873 // if (!$key) return delete_post_meta( $pid, $meta_key ); // note: this deletes the whole meta_key, all fields lost 874 if (!$key) return new WP_Error('missing', "Missing a key..."); 875 $post_meta = get_post_meta( $pid, $meta_key, true); // retrieve meta 876 if ( !empty( $post_meta ) ) { // if there was data to be deleted, proceed 877 if ( $serialize ) { 878 unset($post_meta[$key]); // trash meta 879 return update_post_meta( $pid, $meta_key, $post_meta ); // rewrite the array to post_meta 880 } else { 881 return delete_post_meta( $pid, $meta_key ); // trash meta 882 } 883 } else { // nothing to delete, so don't bother (this happens when post gets saved with fields still blank, and the save_post functions attempt to clear the metadata) 884 return false; 885 } 886 break; 887 888 default : 889 return new WP_Error('action', "First parameter must be 'save', 'get', or 'delete'..."); 890 break; 891 } 892 } 893 894 895 // returns all attachments (except featured image) 896 public function fetch_attached_media($post = null, $mime = null, $include_featured = false) { 897 if (is_wp_error($post)) return $post; 898 if (empty($post)) return new WP_Error('missing', "must pass a post argument!"); 899 if (is_object($post)) { 900 $pid = $post->ID; 901 } else { 902 $pid = intval($post); 903 } 904 905 $args = array( 906 'post_parent' => $pid, 907 'post_type' => 'attachment', 908 'numberposts' => -1, 909 'post_status' => 'any', 910 'orderby' => 'menu_order', 911 'order' => 'ASC', 912 'exclude' => get_post_thumbnail_id($pid), 913 ); 914 if ($include_featured == true) { 915 unset($args['exclude']); 916 } 917 if (!empty($mime)) { 918 // only return requested media type (audio/mpeg, video/mp4, image/jpeg, application/pdf, application/zip) 919 $args['post_mime_type'] = $mime; 920 } 921 // fetch children (results in array of objects, even if only one exists) 922 $kids = get_posts($args); 923 // check if empty 924 $media = ( !empty($kids) ) ? $kids : null; 925 return $media; 926 } 927 928 function session_manager() { 929 if (!session_id()) { 930 session_start(); 931 } 932 $_SESSION['media'] = WP_MEDIA_DIR; 933 $_SESSION['images'] = SOMA_IMG; 934 global $current_user; 935 $_SESSION['user'] = $current_user->data ? $current_user->roles[0] : 'guest'; 936 } 937 938 939 940 //** checks for activation of plugins that somaFramework is dependent on ------------------------------------------------------// 941 function check_plugin_dependency() { 942 // require scribu's p2p plugin 943 global $soma_options; 944 945 if ( somaFunctions::fetch_index($soma_options, 'p2p') && !function_exists('p2p_register_connection_type') ) { 946 add_action( 'admin_notices', function() { 947 echo '<div id=\"message\" class=\"error\" style=\"font-weight: bold\"><p>PLUGIN REQUIRED: \"Posts 2 Posts\" - please <a href=\"http://scribu.net/wordpress/posts-to-posts\" target=\"_blank\">download</a> and/or activate!</p></div>'; 948 } 949 ); 950 } 951 952 // // require companion SOMA theme 953 // $themes = get_themes(); 954 // if (!isset($themes['Stock Media Asset Manager'])) { // theme is not installed! 955 // add_action('admin_notices', 'theme_install_error_msg' ); 956 // function theme_install_error_msg() { 957 // echo '<div id="message" class="error" style="font-weight: bold">'; 958 // echo '<p>THEME MISSING: "Stock Media Asset Manager" - please <a href="' . network_admin_url() .'/themes.php">install!</a></p>'; 959 // echo '</div>'; 960 // } 961 // } 962 // if (get_current_theme() != 'Stock Media Asset Manager') { // theme is not activated! 963 // add_action('admin_notices', 'theme_active_error_msg' ); 964 // function theme_active_error_msg() { 965 // echo '<div id="message" class="updated" style="font-weight: bold">'; 966 // echo '<p>THEME NOT ACTIVE: "Stock Media Asset Manager" - please <a href="' . network_admin_url() .'/themes.php">activate!</a></p>'; 967 // echo '</div>'; 968 // } 969 // } 970 } 971 972 //** generates full current url string with current query vars ------------------------------------------------------// 973 function get_current_url() { 974 $urlis = 'http://' . $_SERVER['HTTP_HOST'] . htmlentities($_SERVER['PHP_SELF']) . $_SERVER['REQUEST_URI']; 975 return $urlis; 976 } 977 978 // displays warning error msg if wp version too old ------------------------------------------------------// 979 function wp_version_check() { 980 global $wp_version; #wp 981 $new_admin_version = '4.4'; 982 $updateURL = ""; 983 if (version_compare($wp_version, $new_admin_version, '<')) { 984 add_action( 'admin_notices', function() { 985 echo '<div id=\"message\" class=\"error\" style=\"font-weight: bold\"><p>WORDPRESS 4.4 MINIMUM REQUIRED - please update WP or de-activate this plugin!</p></div>'; 986 } 987 ); 988 } 989 } 990 991 /** 992 * Displays (and returns) total number of posts within specified categories 993 * 994 * @param string $catslugs Comma separated category slugs 995 * @param bool $display (optional) Echo the result? 996 * @return int Post count 997 */ 998 function in_category_count($catslugs = '', $display = true) { 999 global $wpdb; 1000 1001 $post_count = 0; 1002 $slug_where = ''; 1003 $catslugs_arr = explode(',', $catslugs); 1004 1005 foreach ($catslugs_arr as $catslugkey => $catslug) { 1006 if ( $catslugkey > 0 ) { 1007 $slug_where .= ', '; 1008 } 1009 1010 $slug_where .= "'" . trim($catslug) . "'"; 1011 } 1012 1013 $slug_where = "cat_terms.slug IN (" . $slug_where . ")"; 1014 1015 $sql = "SELECT COUNT( DISTINCT cat_posts.ID ) AS post_count " . 1016 "FROM " . $wpdb->term_taxonomy . " AS cat_term_taxonomy INNER JOIN " . $wpdb->terms . " AS cat_terms ON " . 1017 "cat_term_taxonomy.term_id = cat_terms.term_id " . 1018 "INNER JOIN " . $wpdb->term_relationships . " AS cat_term_relationships ON " . 1019 "cat_term_taxonomy.term_taxonomy_id = cat_term_relationships.term_taxonomy_id " . 1020 "INNER JOIN " . $wpdb->posts . " AS cat_posts ON " . 1021 "cat_term_relationships.object_id = cat_posts.ID " . 1022 "WHERE cat_posts.post_status = 'publish' AND " . 1023 "cat_posts.post_type = 'post' AND " . 1024 "cat_term_taxonomy.taxonomy = 'category' AND " . 1025 $slug_where; 1026 1027 $post_count = $wpdb->get_var($sql); 1028 1029 if ( $display ) { 1030 echo $post_count; 1031 } 1032 1033 return $post_count; 1034 } 1035 1036 // are we using this?? 1037 function get_posts_related_by_taxonomySQL($post_id, $taxonomy, $args=array()) { 1038 global $wpdb; 1039 $sql = <<<SQL 1040 SELECT 1041 related.object_id 1042 FROM 1043 {$wpdb->term_relationships} post 1044 INNER JOIN {$wpdb->term_taxonomy} link ON post.term_taxonomy_id = link.term_taxonomy_id 1045 INNER JOIN {$wpdb->term_relationships} related ON post.term_taxonomy_id = related.term_taxonomy_id 1046 WHERE 1=1 1047 AND link.taxonomy=$taxonomy 1048 AND post.object_id=$post_id 1049 AND post.object_id<>related.object_id 1050 AND post.post_type==related.post_type 1049 1051 SQL; 1050 $post_ids = $wpdb->get_col($wpdb->prepare($sql));1051 $post = get_post($post_id);1052 $args = wp_parse_args($args,array(1053 'post_type' => $post->post_type,1054 'post__in' => $post_ids,1055 ));1056 var_dump($args);1057 return new WP_Query($args);1058 }1059 1060 function get_posts_related_by_taxonomy($post_id,$taxonomy,$args=array()) {1061 $query = new WP_Query();1062 $terms = wp_get_object_terms($post_id,$taxonomy);1063 if (count($terms)) {1064 // Assumes only one term for per post in this taxonomy1065 $post_ids = get_objects_in_term($terms[0]->term_id,$taxonomy);1066 $post = get_post($post_id);1067 $args = wp_parse_args($args,array(1068 'post_type' => $post->post_type, // The assumes the post types match1069 'post__in' => $post_ids,1070 'post__not_in' => $post->ID,1071 'taxonomy' => $taxonomy,1072 'term' => $terms[0]->slug,1073 ));1074 $query = new WP_Query($args);1075 }1076 return $query;1077 }1078 1079 // checks if date string is actually formatted as desired1080 function check_datetime_format($date = null, $format = "Y-m-d H:i:s") {1081 if ($date == null) return false;1082 1083 $date = trim($date);1084 $time = strtotime($date);1085 1086 $is_valid = date($format, $time) == $date;1087 1088 return $is_valid;1089 }1090 1091 function fetch_start_timestamp($pid) {1092 $date = somaFunctions::asset_meta('get', $pid, 'start_date');1093 $time = somaFunctions::asset_meta('get', $pid, 'start_time');1094 $start = strtotime($date . " " . $time);1095 return $start;1096 }1097 1098 function fetch_end_timestamp($pid) {1099 $date = somaFunctions::asset_meta('get', $pid, 'end_date');1100 $time = somaFunctions::asset_meta('get', $pid, 'end_time');1101 $end = strtotime($date . " " . $time);1102 return $end;1103 }1104 1105 // shows an indicator in the admin side menu for pending items1106 function show_pending_number( $menu ) {1107 // currently this function returns count for site-wide posts, not by author, so disable for non-staff1108 if (!SOMA_STAFF) return $menu;1109 //1110 $status = "pending";1111 $types = get_post_types( array( '_builtin' => false ), 'names' );1112 foreach ($types as $type) {1113 $num_posts = wp_count_posts( $type, 'readable' );1114 $pending_count = 0;1115 if ( !empty($num_posts->$status) )1116 $pending_count = $num_posts->$status;1117 1118 // build string to match in $menu array1119 $menu_str = 'edit.php?post_type=' . $type;1120 1121 // loop through $menu items, find match, add indicator1122 foreach( $menu as $menu_key => $menu_data ) {1123 if( $menu_str != $menu_data[2] )1124 continue;1125 $menu[$menu_key][0] .= " <span class='update-plugins count-$pending_count'><span class='plugin-count'>" . number_format_i18n($pending_count) . '</span></span>';1126 }1127 }1128 return $menu;1129 }1130 1131 /**1132 * Kill WordPress execution and display HTML message with error message.1133 *1134 * @since 3.0.01135 * @access private1136 *1137 * @param string $message Error message.1138 * @param string $title Error title.1139 * @param string|array $args Optional arguements to control behaviour.1140 * inspired by JPB_User_Caps1141 */1142 function soma_wp_die_handler( $message, $title = '', $args = array() ) {1143 var_dump(func_get_args());1144 $defaults = array( 'response' => 500 );1145 $r = wp_parse_args($args, $defaults);1146 1147 $have_gettext = function_exists('__');1148 1149 if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {1150 if ( empty( $title ) ) {1151 $error_data = $message->get_error_data();1152 if ( is_array( $error_data ) && isset( $error_data['title'] ) )1153 $title = $error_data['title'];1154 }1155 $errors = $message->get_error_messages();1156 switch ( count( $errors ) ) :1157 case 0 :1158 $message = '';1159 break;1160 case 1 :1161 $message = "<p>{$errors[0]}</p>";1162 break;1163 default :1164 $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";1165 break;1166 endswitch;1167 } elseif ( is_string( $message ) ) {1168 $message = "<p>$message</p>";1169 }1170 1171 if ( isset( $r['back_link'] ) && $r['back_link'] ) {1172 $back_text = $have_gettext? __('« Back') : '« Back';1173 $message .= "\n<p><a href='javascript:history.back()'>$back_text</p>";1174 }1175 1176 if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL )1177 $admin_dir = WP_SITEURL . '/wp-admin/';1178 elseif ( function_exists( 'get_bloginfo' ) && '' != get_bloginfo( 'wpurl' ) )1179 $admin_dir = get_bloginfo( 'wpurl' ) . '/wp-admin/';1180 elseif ( strpos( $_SERVER['PHP_SELF'], 'wp-admin' ) !== false )1181 $admin_dir = '';1182 else1183 $admin_dir = 'wp-admin/';1184 1185 if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) :1186 if ( !headers_sent() ) {1187 status_header( $r['response'] );1188 nocache_headers();1189 header( 'Content-Type: text/html; charset=utf-8' );1190 }1191 1192 if ( empty($title) )1193 $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error';1194 1195 $text_direction = 'ltr';1196 if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] )1197 $text_direction = 'rtl';1198 elseif ( function_exists( 'is_rtl' ) && is_rtl() )1199 $text_direction = 'rtl';1200 ?>1201 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">1202 <!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono -->1203 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>>1204 <head>1205 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />1206 <title><?php echo $title ?></title>1207 <link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install.css" type="text/css" />1208 <?php1209 if ( 'rtl' == $text_direction ) : ?>1210 <link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install-rtl.css" type="text/css" />1211 <?php endif; ?>1212 </head>1213 <body id="error-page">1214 <?php endif; ?>1215 <?php echo $message; ?>1216 </body>1217 </html>1218 <?php1219 die();1220 }1221 1222 //** end soma_wp_die_handler1223 1224 // Remove 'Administrator' from the list of roles if the current user is not an admin1225 function editable_roles( $roles ){1226 if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){1227 unset( $roles['administrator']);1228 }1229 return $roles;1230 }1231 1232 // If someone is trying to edit or delete an admin and that user isn't an admin, don't allow it -- IS THIS STILL NEEDED?1233 function admin_map_meta_cap( $caps, $cap, $user_id, $args ){1234 1235 switch( $cap ){1236 case 'edit_user':1237 case 'remove_user':1238 case 'promote_user':1239 if( isset($args[0]) && $args[0] == $user_id )1240 break;1241 elseif( !isset($args[0]) )1242 $caps[] = 'do_not_allow';1243 $other = new WP_User( absint($args[0]) );1244 if( $other->has_cap( 'administrator' ) ){1245 if(!current_user_can('administrator')){1246 $caps[] = 'do_not_allow';1247 }1248 }1249 break;1250 case 'delete_user':1251 case 'delete_users':1252 if( !isset($args[0]) )1253 break;1254 $other = new WP_User( absint($args[0]) );1255 if( $other->has_cap( 'administrator' ) ){1256 if(!current_user_can('administrator')){1257 $caps[] = 'do_not_allow';1258 }1259 }1260 break;1261 default:1262 break;1263 }1264 return $caps;1265 }1266 1267 // AJAX delete images on the fly.1268 // can't use nonce checking because the elements calling this function are dynamically created in javascript1269 function ajax_unlink_file() {1270 $file = somaFunctions::fetch_index($_POST, 'data');// retrieve file from ajax post1271 if ($file && file_exists($file)) {// make sure it's there1272 $delete = unlink($file);// kill it1273 if ($delete) {1274 $response = array( 'success' => true, 'msg' => 'Successfully deleted the uploaded file!' );1275 } else {1276 $response = array( 'error' => true, 'msg' => 'Could not delete the uploaded file...' );1277 }1278 } else {1279 $response = array( 'error' => true, 'msg' => 'Could not find the file to delete...' );1280 }1281 echo json_encode( $response );1282 exit;1283 }1284 1285 // AJAX delete attachments1286 function ajax_delete_attachment() {1287 $nonce = check_ajax_referer( 'soma-delete-attachment', 'nonce', false );1288 if (!$nonce) {1289 $response = array( 'error' => true, 'msg' => 'nonce verification failed...' );1290 echo json_encode( $response );1291 exit;1292 }1293 $att_id = somaFunctions::fetch_index($_POST, 'data');1294 if ($att_id) {1295 $result = wp_delete_attachment($att_id, true);1296 $response = array( 'success' => true, 'msg' => $result );1297 } else {1298 $response = array( 'error' => true, 'msg' => 'Could not find the attachment...' );1299 }1300 echo json_encode( $response );1301 exit;1302 }1303 1304 1305 1306 // grabs metadata from public vimeo API, returns array1307 function fetch_vimeo_meta( $link = null ) {1308 if ( !$link ) return new WP_Error('missing', "Must specify a video ID");1309 // use the oembed API to parse the raw URL for us1310 $oembed = json_decode(file_get_contents("http://vimeo.com/api/oembed.json?url=".urlencode($link)), true);1311 $meta = array_shift(unserialize(file_get_contents("http://vimeo.com/api/v2/video/{$oembed['video_id']}.php")));1312 $meta = array_merge($oembed, $meta);1313 return $meta;1314 }1315 1316 // grabs metadata from public youtube API, returns array1317 function fetch_youtube_meta( $url = null ) {1318 if ( !$url ) return new WP_Error('missing', "Must specify a video ID");1319 // extract ID1320 if (preg_match('%(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match)) {1321 $id = $match[1];1322 }1323 $meta = json_decode(file_get_contents("http://gdata.youtube.com/feeds/api/videos/$id?v=2&alt=json"), true); // json_decode true returns data as array instead of object1324 $meta = $meta['entry']; // isolate the single entry we requested1325 return $meta;1326 }1327 1328 // grab metadata from external site URL1329 // only supporting 3 media sites right now: youtube, vimeo, soundcloud1330 function fetch_external_media($url = null, $width = null, $height = null) {1331 if ( !$url ) return new WP_Error('missing', "Must specify a valid URL from a supported site");1332 1333 // in case user didn't include http1334 if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {1335 $url = "http://" . $url;1336 }1337 1338 // identify which site1339 switch (true) {1340 case ( strpos( $url, 'youtube.com' ) > 0 || strpos ($url, 'youtu.be' ) > 0 ) :1341 $site = 'youtube';1342 break;1343 case ( strpos( $url, 'vimeo.com' ) > 0 ) :1344 $site = 'vimeo';1345 break;1346 case ( strpos( $url, 'soundcloud.com' ) > 0 ) :1347 $site = 'soundcloud';1348 break;1349 default:1350 return new WP_Error('missing', "Problem with the URL. Can't figure out which site it's from (or it's not supported). Check to make sure you entered it correctly...");1351 break;1352 }1353 1354 1355 $media = array();// init container1356 $width = $width ? $width : "853";// iframe default1357 $height = $height ? $height : "480";// iframe default1358 1359 // extract ID, fetch meta, build output1360 switch ($site) {1361 case "youtube";1362 if (preg_match('%(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match)) {1363 $id = $match[1];1364 ob_start();1365 ini_set('user_agent','Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17');1366 // $meta = file_get_contents("http://gdata.youtube.com/feeds/api/videos/".$id."?v=2&alt=json"); // old, don't work??1367 $meta = file_get_contents("https://www.youtube.com/oembed?url=".$url."&format=json");1368 $meta = json_decode($meta, true);// json_decode true returns data as array instead of object1369 ob_end_clean();1370 1371 $media['url'] = "http://www.youtube.com/watch?v=$id";// rebuild external url1372 $media['id']= $id;1373 $media['site']= $site;1374 $media['thumb'] = $meta['thumbnail_url'];// grabs url of medium 360x480 image1375 $media['title']= $meta['title'];1376 // $media['desc']= stripslashes($meta['media$group']['media$description']['$t']);1377 // $media['duration']= $meta['media$group']['media$content'][0]['duration'];1378 $media['mobile'] = "youtube:$id";// launches youtube app, i think...1379 $media['embed']= "<iframe width=\"$width\" height=\"$height\" src=\"http://www.youtube.com/embed/$id?rel=0&hd=1\" frameborder=\"0\" allowfullscreen></iframe>";1380 $media['iframe'] = "http://www.youtube.com/embed/$id?rel=0&hd=1&autoplay=1";// url to pass to iframe renderers1381 // $media['api'] = $meta;// we include everything we got from the site API, just in case (each site formats differently)1382 } else {1383 return new WP_Error('missing', "Can't extract ID from youtube URL...");1384 }1385 break;1386 case "vimeo";1387 // try to get around 403 forbidden errors when using file_get_contents1388 ob_start();1389 ini_set('user_agent','Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17');1390 $oembed = file_get_contents("https://vimeo.com/api/oembed.json?url=".urlencode($url));1391 $oembed = json_decode($oembed, true);1392 ob_end_clean();1393 if (!empty($oembed)) {// get oembed metadata1394 $id = $oembed['video_id'];// extract id from api response1395 ob_start();1396 ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0)');1397 $meta = file_get_contents("https://vimeo.com/api/v2/video/$id.php");1398 ob_end_clean();1399 $meta = array_shift(unserialize($meta));// get more metadata (note: we're making two distinct calls to API for vimeo)1400 $meta = array_merge($oembed, $meta);// combine the two (including some overlapping keys)1401 $media['url'] = "http://vimeo.com/$id";// rebuild external url1402 $media['id'] = $id;// store raw media ID1403 $media['site'] = $site;//1404 $media['thumb'] = $meta['thumbnail_url'];// grabs url of default image 640x3601405 $media['title'] = stripslashes($meta['title']);//1406 $media['desc'] = stripslashes($meta['description']);//1407 $media['duration'] = $meta['duration'];// in seconds1408 $media['mobile'] = $meta['mobile_url'];// mobile-friendly display url1409 $media['embed'] = $meta['html'];// auto embed code (should be HTML5/ipad compatible)1410 $media['iframe'] = "http://player.vimeo.com/video/$id?title=0&byline=0&portrait=0&&frameborder=0&autoplay=1";// url to pass to iframe renderers (like colorbox)1411 $media['api'] = $meta;// we include everything we got from the site API, just in case (each site formats differently)1412 } else {1413 return new WP_Error('missing', "Can't extract ID from vimeo URL...");1414 }1415 break;1416 case "soundcloud";1417 $clientid = "006b3d9b3bbd5bd6cc7d27ab05d9a11b";// my soundcloud api id1418 if ($meta = json_decode(file_get_contents("http://api.soundcloud.com/resolve?client_id=".$clientid."&format=json&url=".urlencode($url)), true)) {1419 //$oembed = json_decode(file_get_contents("http://soundcloud.com/oembed?format=json&show_comments=false&auto_play=true&url=".urlencode($url)), true);1420 $media['id']= $meta['id'];1421 $media['url']= $meta['permalink_url'];1422 $media['site']= $site;1423 if (empty($meta['artwork_url'])) {1424 $media['thumb']= $meta['waveform_url'];1425 } else {1426 $media['thumb']= $meta['artwork_url'];1427 }1428 $media['title']= $meta['title'];1429 $media['desc']= $meta['description'];1430 $media['duration']= $meta['duration'];1431 $media['mobile']= $meta['stream_url']."?client_id=006b3d9b3bbd5bd6cc7d27ab05d9a11b";1432 $media['direct']= $meta['stream_url']."?client_id=006b3d9b3bbd5bd6cc7d27ab05d9a11b";1433 $media['iframe'] = "http://w.soundcloud.com/player/?url=".$meta['uri']."?auto_play=true&show_artwork=false&show_comments=false&color=000000&show_playcount=false&sharing=false&show_user=false&liking=false";// http://developers.soundcloud.com/docs/oembed -- https://github.com/soundcloud/Widget-JS-API/wiki/widget-options1434 $media['embed']= '<iframe width="100%" height="166" scrolling="no" frameborder="no" src="'.$media['iframe'].'"></iframe>';1435 $media['format']= $meta['original_format'];1436 $media['api'] = $meta;// mp3 in this case1437 } else {1438 return new WP_Error('missing', "Can't extract ID from soundcloud URL...");1439 }1440 break;1441 }1442 1443 if (empty($media)) return new WP_Error('missing', "Somehow we failed...");1444 // success1445 return $media;1446 }1447 1448 1449 // retrieves ID of attachment from given URL1450 // source: Rarst http://wordpress.stackexchange.com/questions/6645/turn-a-url-into-an-attachment-post-id1451 function get_attachment_id_from_url( $url ) {1452 1453 $dir = wp_upload_dir();1454 $dir = trailingslashit($dir['baseurl']);1455 1456 if( false === strpos( $url, $dir ) )1457 return new WP_Error('missing', "Something wrong with this url...");1458 1459 $file = basename($url);1460 1461 $query = array(1462 'post_type' => 'attachment',1463 'fields' => 'ids',1464 'meta_query' => array(1465 array(1466 'value' => $file,1467 'compare' => 'LIKE',1468 )1469 )1470 );1471 1472 $query['meta_query'][0]['key'] = '_wp_attached_file';1473 $ids = get_posts( $query );1474 1475 foreach( $ids as $id )1476 if ( $url == array_shift( wp_get_attachment_image_src($id, 'full') ) )1477 return $id;1478 1479 $query['meta_query'][0]['key'] = '_wp_attachment_metadata';1480 $ids = get_posts( $query );1481 1482 foreach( $ids as $id ) {1483 1484 $meta = wp_get_attachment_metadata($id);1485 1486 foreach( $meta['sizes'] as $size => $values )1487 if( $values['file'] == $file && $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) {1488 1489 return $id;1490 }1491 }1492 1493 return new WP_Error('missing', "Somehow we failed...");1494 }1495 1496 /**1497 * Download an image from the specified URL and attach it to a post.1498 * Modified version of core function media_sideload_image() in /wp-admin/includes/media.php (which returns an html img tag instead of attachment ID)1499 * Additional functionality: ability override actual filename, set as post thumbnail, and to pass $post_data to override values in wp_insert_attachment (original only allowed $desc)1500 *1501 * @since 1.41502 *1503 * @param string $url (required) The URL of the image to download1504 * @param int $post_id (required) The post ID the media is to be associated with1505 * @param bool $thumb (optional) Whether to make this attachment the Featured Image for the post1506 * @param string $filename (optional) Replacement filename for the URL filename (do not include extension)1507 * @param array $post_data (optional) Array of key => values for wp_posts table (ex: 'post_title' => 'foobar', 'post_status' => 'draft')1508 * @return int|object The ID of the attachment or a WP_Error on failure1509 */1510 function attach_external_image( $url = null, $post_id = null, $thumb = null, $filename = null, $post_data = array() ) {1511 if ( !$url || !$post_id ) return new WP_Error('missing', "Need a valid URL and post ID...");1512 if ( !self::array_is_associative( $post_data ) ) return new WP_Error('missing', "Must pass post data as associative array...");1513 1514 // Download file to temp location, returns full server path to temp file, ex; /home/somatics/public_html/mysite/wp-content/26192277_640.tmp MUST BE FOLLOWED WITH AN UNLINK AT SOME POINT1515 $tmp = download_url( $url );1516 1517 // If error storing temporarily, unlink1518 if ( is_wp_error( $tmp ) ) {1519 @unlink($file_array['tmp_name']);// clean up1520 $file_array['tmp_name'] = '';1521 return $tmp; // output wp_error1522 }1523 1524 preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $url, $matches);// fix file filename for query strings1525 $url_filename = basename($matches[0]);// extract filename from url for title1526 $url_type = wp_check_filetype($url_filename);// determine file type (ext and mime/type)1527 1528 // override filename if given, reconstruct server path1529 if ( !empty( $filename ) ) {1530 $filename = sanitize_file_name($filename);1531 $tmppath = pathinfo( $tmp );// extract path parts1532 $new = $tmppath['dirname'] . "/". $filename . "." . $tmppath['extension'];// build new path1533 rename($tmp, $new);// renames temp file on server1534 $tmp = $new;// push new filename (in path) to be used in file array later1535 }1536 1537 // assemble file data (should be built like $_FILES since wp_handle_sideload() will be using)1538 $file_array['tmp_name'] = $tmp;// full server path to temp file1539 1540 if ( !empty( $filename ) ) {1541 $file_array['name'] = $filename . "." . $url_type['ext'];// user given filename for title, add original URL extension1542 } else {1543 $file_array['name'] = $url_filename;// just use original URL filename1544 }1545 1546 // set additional wp_posts columns1547 if ( empty( $post_data['post_title'] ) ) {1548 $post_data['post_title'] = basename($url_filename, "." . $url_type['ext']);// just use the original filename (no extension)1549 }1550 1551 // make sure gets tied to parent1552 if ( empty( $post_data['post_parent'] ) ) {1553 $post_data['post_parent'] = $post_id;1554 }1555 1556 // required libraries for media_handle_sideload1557 require_once(ABSPATH . 'wp-admin/includes/file.php');1558 require_once(ABSPATH . 'wp-admin/includes/media.php');1559 require_once(ABSPATH . 'wp-admin/includes/image.php');1560 1561 // do the validation and storage stuff1562 $att_id = media_handle_sideload( $file_array, $post_id, null, $post_data );// $post_data can override the items saved to wp_posts table, like post_mime_type, guid, post_parent, post_title, post_content, post_status1563 1564 // If error storing permanently, unlink1565 if ( is_wp_error($att_id) ) {1566 @unlink($file_array['tmp_name']);// clean up1567 return $att_id; // output wp_error1568 }1569 1570 // set as post thumbnail if desired1571 if ($thumb) {1572 set_post_thumbnail($post_id, $att_id);1573 }1574 1575 return $att_id;1576 }1577 1578 /**1579 * Gets the excerpt of a specific post ID or object - if one doesn't exist, it will create one dynamically1580 * @since 1.7.31581 *1582 * @param - $post - object/int/string - the ID or object of the post to get the excerpt of1583 * @param - $length - int - the length of the excerpt in words1584 * @param - $tags - string - the allowed HTML tags. These will not be stripped out1585 * @param - $extra - string - text to append to the end of the excerpt1586 */1587 function fetch_excerpt($post, $length = 30, $tags = '<a><em><strong>', $extra = '…') {1588 1589 if (is_wp_error($post)) return $post;1590 if (empty($post)) return new WP_Error('missing', "must pass a post argument!");1591 if (!is_object($post)) {1592 $post = get_post(intval($post));1593 }1594 if (!is_object($post)) {1595 return new WP_Error('error', "Can't retrieve the requested post...");1596 }1597 1598 if (has_excerpt($post->ID)) {1599 $the_excerpt = $post->post_excerpt;1600 return apply_filters('the_content', $the_excerpt);1601 } else {1602 $the_excerpt = $post->post_content;1603 }1604 1605 $the_excerpt = strip_shortcodes(strip_tags($the_excerpt), $tags);1606 $the_excerpt = preg_split('/\b/', $the_excerpt, $length * 2+1);1607 $excerpt_waste = array_pop($the_excerpt);1608 $the_excerpt = implode($the_excerpt);1609 $the_excerpt .= $extra;1610 1611 return apply_filters('the_content', $the_excerpt);1612 }1613 1614 /**1615 * generates HTML link code in conjunction with the soma_go_redirect option1616 * won't work unless you've already hooked the soma_go_redirect_codes filter and added a slug/url pair1617 * @since 1.7.61618 *1619 * @param - $slug - string - properly formatted slug for the url: /go/[slug]1620 * @param - $text - string - text to be wrapped inside the <a> tags1621 * @return - string - HTML link code1622 */1623 function make_go_link($slug = null, $text = null) {1624 if (empty($slug) || empty($text)) return new WP_Error('missing', "must pass a slug and text argument!");1625 $slug = sanitize_title_with_dashes($slug);1626 $text = sanitize_title($text);1627 $codes = apply_filters('soma_go_redirect_codes', $codes);1628 if (array_key_exists($slug, $codes)) {1629 return "<a href='{$codes[$slug]}' rel='nofollow'>$text</a>";1630 } else {1631 return new WP_Error('error', "that slug hasn't been added yet, so I can't give you a URL ...");1632 }1633 1634 }1635 1636 // Returns array of details about a file (only works on attachments)1637 // -------------------------------------------------------------1638 function fetch_file($pid = null) {1639 if ( empty( $pid ) ) return false;1640 $type = get_post_type( intval( $pid ) );1641 if ( $type != "attachment" ) return false;1642 1643 $file_path = get_attached_file( $pid );1644 $file = pathinfo( $file_path );// returns array of dirname, basename, extension, filename1645 $file['mime'] = get_post_mime_type( $pid );// returns mime type1646 $file['url'] = wp_get_attachment_url( $pid );// returns full URL for downloading1647 $file['secure'] = self::build_request_link('legacy-download', $pid);// returns secure download URL1648 if ( is_file( SOMA_DIR . "images/file-icons/" . $file['extension'] . ".png" ) ) {1649 $file['icon'] = SOMA_IMG . 'file-icons/'. $file['extension'].'.png';1650 } else {1651 $file['icon'] = SOMA_IMG . 'file-icons/bin.png';1652 }1653 $file['time'] = get_post_time("U", true, $pid);1654 return $file;1655 }1656 1657 // Return all sub pages of a given post1658 // -------------------------------------------------------------1659 function fetch_sub_pages($pid = null) {1660 if (empty($pid)) return null;1661 $post_type = get_post_type($pid);1662 $args = array(1663 'post_type' => $post_type,1664 'child_of' => $pid,1665 'parent' => $pid,1666 'sort_order' => 'ASC',1667 'sort_column' => 'menu_order',1668 'numberposts' => -11669 );1670 return get_pages($args);1671 }1672 1673 // Return all root (top-level) posts of any given post type1674 // -------------------------------------------------------------1675 function fetch_root_pages($post_type = 'page') {1676 $args = array(1677 'post_type' => $post_type,1678 'parent' => 0,1679 'order' => 'ASC',1680 'orderby' => 'menu_order',1681 'numberposts' => -11682 );1683 return get_pages($args);1684 }1685 1686 /**1687 * Helps in use of dash and underscore in field ID's of richtext field types (dealing with wp_editor() finicky rules)1688 * @since 1.8.11689 *1690 * @param - $id - string - user defined ID for this field, anything that's not a lowercase letter or a dash or underscore will get trashed!!1691 * @return - $sanID - string - safe ID with obfuscations1692 */1693 1694 function sanitize_wpeditor_id($id) {1695 $sanID = preg_replace('/_+/', 'uuuuu', $id);// to preserve some backwards compatibility, we'll make special replacements for dashes and underscores, so they'll get preserved1696 $sanID = preg_replace('/-+/', 'ddddd', $sanID);1697 $sanID = preg_replace('/[^a-z]+/', '', $sanID);// final pass to eliminate all non-alpha characters1698 return $sanID;1699 }1700 1701 1702 function unsanitize_wpeditor_id($id) {1703 $unsanID = preg_replace('/uuuuu+/', '_', $id);// to preserve some backwards compatibility, we'll make special replacements for dashes and underscores, so they'll get preserved1704 $unsanID = preg_replace('/ddddd+/', '-', $unsanID);1705 return $unsanID;1706 }1707 1708 1709 /**1710 * Constructs URL string to be used to trigger the soma_request_ action hook of the somaRequest Class1711 * typically used to pass an array of data to a custom function1712 *1713 * @since 1.8.51714 *1715 * @param - $action - (string) identifier used to assemble the action hook1716 * @return - $data - (string/array) - stuff to be sent to the hooked function1717 */1718 1719 function build_request_link($action = null, $data = null) {1720 if (empty($action) || empty($data)) return new WP_Error('error', 'action or data missing for the request!');1721 $safedata = http_build_query(array('data' => $data));// prepare data contents (even associative or indexed arrays) for inclusion in the URL1722 $link = get_option('siteurl') . "?soma_request=$action&$safedata&security=" . wp_create_nonce( "soma-request" );1723 return $link;1724 }1052 $post_ids = $wpdb->get_col($wpdb->prepare($sql)); 1053 $post = get_post($post_id); 1054 $args = wp_parse_args($args,array( 1055 'post_type' => $post->post_type, 1056 'post__in' => $post_ids, 1057 )); 1058 var_dump($args); 1059 return new WP_Query($args); 1060 } 1061 1062 function get_posts_related_by_taxonomy($post_id,$taxonomy,$args=array()) { 1063 $query = new WP_Query(); 1064 $terms = wp_get_object_terms($post_id,$taxonomy); 1065 if (count($terms)) { 1066 // Assumes only one term for per post in this taxonomy 1067 $post_ids = get_objects_in_term($terms[0]->term_id,$taxonomy); 1068 $post = get_post($post_id); 1069 $args = wp_parse_args($args,array( 1070 'post_type' => $post->post_type, // The assumes the post types match 1071 'post__in' => $post_ids, 1072 'post__not_in' => $post->ID, 1073 'taxonomy' => $taxonomy, 1074 'term' => $terms[0]->slug, 1075 )); 1076 $query = new WP_Query($args); 1077 } 1078 return $query; 1079 } 1080 1081 // checks if date string is actually formatted as desired 1082 function check_datetime_format($date = null, $format = "Y-m-d H:i:s") { 1083 if ($date == null) return false; 1084 1085 $date = trim($date); 1086 $time = strtotime($date); 1087 1088 $is_valid = date($format, $time) == $date; 1089 1090 return $is_valid; 1091 } 1092 1093 function fetch_start_timestamp($pid) { 1094 $date = somaFunctions::asset_meta('get', $pid, 'start_date'); 1095 $time = somaFunctions::asset_meta('get', $pid, 'start_time'); 1096 $start = strtotime($date . " " . $time); 1097 return $start; 1098 } 1099 1100 function fetch_end_timestamp($pid) { 1101 $date = somaFunctions::asset_meta('get', $pid, 'end_date'); 1102 $time = somaFunctions::asset_meta('get', $pid, 'end_time'); 1103 $end = strtotime($date . " " . $time); 1104 return $end; 1105 } 1106 1107 // shows an indicator in the admin side menu for pending items 1108 function show_pending_number( $menu ) { 1109 // currently this function returns count for site-wide posts, not by author, so disable for non-staff 1110 if (!SOMA_STAFF) return $menu; 1111 // 1112 $status = "pending"; 1113 $types = get_post_types( array( '_builtin' => false ), 'names' ); 1114 foreach ($types as $type) { 1115 $num_posts = wp_count_posts( $type, 'readable' ); 1116 $pending_count = 0; 1117 if ( !empty($num_posts->$status) ) 1118 $pending_count = $num_posts->$status; 1119 1120 // build string to match in $menu array 1121 $menu_str = 'edit.php?post_type=' . $type; 1122 1123 // loop through $menu items, find match, add indicator 1124 foreach( $menu as $menu_key => $menu_data ) { 1125 if( $menu_str != $menu_data[2] ) 1126 continue; 1127 $menu[$menu_key][0] .= " <span class='update-plugins count-$pending_count'><span class='plugin-count'>" . number_format_i18n($pending_count) . '</span></span>'; 1128 } 1129 } 1130 return $menu; 1131 } 1132 1133 /** 1134 * Kill WordPress execution and display HTML message with error message. 1135 * 1136 * @since 3.0.0 1137 * @access private 1138 * 1139 * @param string $message Error message. 1140 * @param string $title Error title. 1141 * @param string|array $args Optional arguements to control behaviour. 1142 * inspired by JPB_User_Caps 1143 */ 1144 function soma_wp_die_handler( $message, $title = '', $args = array() ) { 1145 var_dump(func_get_args()); 1146 $defaults = array( 'response' => 500 ); 1147 $r = wp_parse_args($args, $defaults); 1148 1149 $have_gettext = function_exists('__'); 1150 1151 if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { 1152 if ( empty( $title ) ) { 1153 $error_data = $message->get_error_data(); 1154 if ( is_array( $error_data ) && isset( $error_data['title'] ) ) 1155 $title = $error_data['title']; 1156 } 1157 $errors = $message->get_error_messages(); 1158 switch ( count( $errors ) ) : 1159 case 0 : 1160 $message = ''; 1161 break; 1162 case 1 : 1163 $message = "<p>{$errors[0]}</p>"; 1164 break; 1165 default : 1166 $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>"; 1167 break; 1168 endswitch; 1169 } elseif ( is_string( $message ) ) { 1170 $message = "<p>$message</p>"; 1171 } 1172 1173 if ( isset( $r['back_link'] ) && $r['back_link'] ) { 1174 $back_text = $have_gettext? __('« Back') : '« Back'; 1175 $message .= "\n<p><a href='javascript:history.back()'>$back_text</p>"; 1176 } 1177 1178 if ( defined( 'WP_SITEURL' ) && '' != WP_SITEURL ) 1179 $admin_dir = WP_SITEURL . '/wp-admin/'; 1180 elseif ( function_exists( 'get_bloginfo' ) && '' != get_bloginfo( 'wpurl' ) ) 1181 $admin_dir = get_bloginfo( 'wpurl' ) . '/wp-admin/'; 1182 elseif ( strpos( $_SERVER['PHP_SELF'], 'wp-admin' ) !== false ) 1183 $admin_dir = ''; 1184 else 1185 $admin_dir = 'wp-admin/'; 1186 1187 if ( !function_exists( 'did_action' ) || !did_action( 'admin_head' ) ) : 1188 if ( !headers_sent() ) { 1189 status_header( $r['response'] ); 1190 nocache_headers(); 1191 header( 'Content-Type: text/html; charset=utf-8' ); 1192 } 1193 1194 if ( empty($title) ) 1195 $title = $have_gettext ? __('WordPress › Error') : 'WordPress › Error'; 1196 1197 $text_direction = 'ltr'; 1198 if ( isset($r['text_direction']) && 'rtl' == $r['text_direction'] ) 1199 $text_direction = 'rtl'; 1200 elseif ( function_exists( 'is_rtl' ) && is_rtl() ) 1201 $text_direction = 'rtl'; 1202 ?> 1203 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 1204 <!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono --> 1205 <html xmlns="http://www.w3.org/1999/xhtml" <?php if ( function_exists( 'language_attributes' ) ) language_attributes(); ?>> 1206 <head> 1207 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 1208 <title><?php echo $title ?></title> 1209 <link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install.css" type="text/css" /> 1210 <?php 1211 if ( 'rtl' == $text_direction ) : ?> 1212 <link rel="stylesheet" href="<?php echo $admin_dir; ?>css/install-rtl.css" type="text/css" /> 1213 <?php endif; ?> 1214 </head> 1215 <body id="error-page"> 1216 <?php endif; ?> 1217 <?php echo $message; ?> 1218 </body> 1219 </html> 1220 <?php 1221 die(); 1222 } 1223 1224 //** end soma_wp_die_handler 1225 1226 // Remove 'Administrator' from the list of roles if the current user is not an admin 1227 function editable_roles( $roles ){ 1228 if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){ 1229 unset( $roles['administrator']); 1230 } 1231 return $roles; 1232 } 1233 1234 // If someone is trying to edit or delete an admin and that user isn't an admin, don't allow it -- IS THIS STILL NEEDED? 1235 function admin_map_meta_cap( $caps, $cap, $user_id, $args ){ 1236 1237 switch( $cap ){ 1238 case 'edit_user': 1239 case 'remove_user': 1240 case 'promote_user': 1241 if( isset($args[0]) && $args[0] == $user_id ) 1242 break; 1243 elseif( !isset($args[0]) ) 1244 $caps[] = 'do_not_allow'; 1245 $other = new WP_User( absint($args[0]) ); 1246 if( $other->has_cap( 'administrator' ) ){ 1247 if(!current_user_can('administrator')){ 1248 $caps[] = 'do_not_allow'; 1249 } 1250 } 1251 break; 1252 case 'delete_user': 1253 case 'delete_users': 1254 if( !isset($args[0]) ) 1255 break; 1256 $other = new WP_User( absint($args[0]) ); 1257 if( $other->has_cap( 'administrator' ) ){ 1258 if(!current_user_can('administrator')){ 1259 $caps[] = 'do_not_allow'; 1260 } 1261 } 1262 break; 1263 default: 1264 break; 1265 } 1266 return $caps; 1267 } 1268 1269 // AJAX delete images on the fly. 1270 // can't use nonce checking because the elements calling this function are dynamically created in javascript 1271 function ajax_unlink_file() { 1272 $file = somaFunctions::fetch_index($_POST, 'data'); // retrieve file from ajax post 1273 if ($file && file_exists($file)) { // make sure it's there 1274 $delete = unlink($file); // kill it 1275 if ($delete) { 1276 $response = array( 'success' => true, 'msg' => 'Successfully deleted the uploaded file!' ); 1277 } else { 1278 $response = array( 'error' => true, 'msg' => 'Could not delete the uploaded file...' ); 1279 } 1280 } else { 1281 $response = array( 'error' => true, 'msg' => 'Could not find the file to delete...' ); 1282 } 1283 echo json_encode( $response ); 1284 exit; 1285 } 1286 1287 // AJAX delete attachments 1288 function ajax_delete_attachment() { 1289 $nonce = check_ajax_referer( 'soma-delete-attachment', 'nonce', false ); 1290 if (!$nonce) { 1291 $response = array( 'error' => true, 'msg' => 'nonce verification failed...' ); 1292 echo json_encode( $response ); 1293 exit; 1294 } 1295 $att_id = somaFunctions::fetch_index($_POST, 'data'); 1296 if ($att_id) { 1297 $result = wp_delete_attachment($att_id, true); 1298 $response = array( 'success' => true, 'msg' => $result ); 1299 } else { 1300 $response = array( 'error' => true, 'msg' => 'Could not find the attachment...' ); 1301 } 1302 echo json_encode( $response ); 1303 exit; 1304 } 1305 1306 1307 1308 // grabs metadata from public vimeo API, returns array 1309 function fetch_vimeo_meta( $link = null ) { 1310 if ( !$link ) return new WP_Error('missing', "Must specify a video ID"); 1311 // use the oembed API to parse the raw URL for us 1312 $oembed = json_decode(file_get_contents("http://vimeo.com/api/oembed.json?url=".urlencode($link)), true); 1313 $meta = array_shift(unserialize(file_get_contents("http://vimeo.com/api/v2/video/{$oembed['video_id']}.php"))); 1314 $meta = array_merge($oembed, $meta); 1315 return $meta; 1316 } 1317 1318 // grabs metadata from public youtube API, returns array 1319 function fetch_youtube_meta( $url = null ) { 1320 if ( !$url ) return new WP_Error('missing', "Must specify a video ID"); 1321 // extract ID 1322 if (preg_match('%(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match)) { 1323 $id = $match[1]; 1324 } 1325 $meta = json_decode(file_get_contents("http://gdata.youtube.com/feeds/api/videos/$id?v=2&alt=json"), true); // json_decode true returns data as array instead of object 1326 $meta = $meta['entry']; // isolate the single entry we requested 1327 return $meta; 1328 } 1329 1330 // grab metadata from external site URL 1331 // only supporting 3 media sites right now: youtube, vimeo, soundcloud 1332 function fetch_external_media($url = null, $width = null, $height = null) { 1333 if ( !$url ) return new WP_Error('missing', "Must specify a valid URL from a supported site"); 1334 1335 // in case user didn't include http 1336 if (!preg_match("~^(?:f|ht)tps?://~i", $url)) { 1337 $url = "http://" . $url; 1338 } 1339 1340 // identify which site 1341 switch (true) { 1342 case ( strpos( $url, 'youtube.com' ) > 0 || strpos ($url, 'youtu.be' ) > 0 ) : 1343 $site = 'youtube'; 1344 break; 1345 case ( strpos( $url, 'vimeo.com' ) > 0 ) : 1346 $site = 'vimeo'; 1347 break; 1348 case ( strpos( $url, 'soundcloud.com' ) > 0 ) : 1349 $site = 'soundcloud'; 1350 break; 1351 default: 1352 return new WP_Error('missing', "Problem with the URL. Can't figure out which site it's from (or it's not supported). Check to make sure you entered it correctly..."); 1353 break; 1354 } 1355 1356 1357 $media = array(); // init container 1358 $width = $width ? $width : "853"; // iframe default 1359 $height = $height ? $height : "480"; // iframe default 1360 1361 // extract ID, fetch meta, build output 1362 switch ($site) { 1363 case "youtube"; 1364 if (preg_match('%(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match)) { 1365 $id = $match[1]; 1366 ob_start(); 1367 ini_set('user_agent','Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17'); 1368 // $meta = file_get_contents("http://gdata.youtube.com/feeds/api/videos/".$id."?v=2&alt=json"); // old, don't work?? 1369 $meta = file_get_contents("https://www.youtube.com/oembed?url=".$url."&format=json"); 1370 $meta = json_decode($meta, true); // json_decode true returns data as array instead of object 1371 ob_end_clean(); 1372 1373 $media['url'] = "http://www.youtube.com/watch?v=$id"; // rebuild external url 1374 $media['id'] = $id; 1375 $media['site'] = $site; 1376 $media['thumb'] = $meta['thumbnail_url']; // grabs url of medium 360x480 image 1377 $media['title'] = $meta['title']; 1378 // $media['desc'] = stripslashes($meta['media$group']['media$description']['$t']); 1379 // $media['duration'] = $meta['media$group']['media$content'][0]['duration']; 1380 $media['mobile'] = "youtube:$id"; // launches youtube app, i think... 1381 $media['embed'] = "<iframe width=\"$width\" height=\"$height\" src=\"http://www.youtube.com/embed/$id?rel=0&hd=1\" frameborder=\"0\" allowfullscreen></iframe>"; 1382 $media['iframe'] = "http://www.youtube.com/embed/$id?rel=0&hd=1&autoplay=1"; // url to pass to iframe renderers 1383 // $media['api'] = $meta; // we include everything we got from the site API, just in case (each site formats differently) 1384 } else { 1385 return new WP_Error('missing', "Can't extract ID from youtube URL..."); 1386 } 1387 break; 1388 case "vimeo"; 1389 // try to get around 403 forbidden errors when using file_get_contents 1390 ob_start(); 1391 ini_set('user_agent','Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17'); 1392 $oembed = file_get_contents("https://vimeo.com/api/oembed.json?url=".urlencode($url)); 1393 $oembed = json_decode($oembed, true); 1394 ob_end_clean(); 1395 if (!empty($oembed)) { // get oembed metadata 1396 $id = $oembed['video_id']; // extract id from api response 1397 ob_start(); 1398 ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0)'); 1399 $meta = file_get_contents("https://vimeo.com/api/v2/video/$id.php"); 1400 ob_end_clean(); 1401 $meta = array_shift(unserialize($meta)); // get more metadata (note: we're making two distinct calls to API for vimeo) 1402 $meta = array_merge($oembed, $meta); // combine the two (including some overlapping keys) 1403 $media['url'] = "http://vimeo.com/$id"; // rebuild external url 1404 $media['id'] = $id; // store raw media ID 1405 $media['site'] = $site; // 1406 $media['thumb'] = $meta['thumbnail_url']; // grabs url of default image 640x360 1407 $media['title'] = stripslashes($meta['title']); // 1408 $media['desc'] = stripslashes($meta['description']); // 1409 $media['duration'] = $meta['duration']; // in seconds 1410 $media['mobile'] = $meta['mobile_url']; // mobile-friendly display url 1411 $media['embed'] = $meta['html']; // auto embed code (should be HTML5/ipad compatible) 1412 $media['iframe'] = "http://player.vimeo.com/video/$id?title=0&byline=0&portrait=0&&frameborder=0&autoplay=1"; // url to pass to iframe renderers (like colorbox) 1413 $media['api'] = $meta; // we include everything we got from the site API, just in case (each site formats differently) 1414 } else { 1415 return new WP_Error('missing', "Can't extract ID from vimeo URL..."); 1416 } 1417 break; 1418 case "soundcloud"; 1419 $clientid = "006b3d9b3bbd5bd6cc7d27ab05d9a11b"; // my soundcloud api id 1420 if ($meta = json_decode(file_get_contents("http://api.soundcloud.com/resolve?client_id=".$clientid."&format=json&url=".urlencode($url)), true)) { 1421 // $oembed = json_decode(file_get_contents("http://soundcloud.com/oembed?format=json&show_comments=false&auto_play=true&url=".urlencode($url)), true); 1422 $media['id'] = $meta['id']; 1423 $media['url'] = $meta['permalink_url']; 1424 $media['site'] = $site; 1425 if (empty($meta['artwork_url'])) { 1426 $media['thumb'] = $meta['waveform_url']; 1427 } else { 1428 $media['thumb'] = $meta['artwork_url']; 1429 } 1430 $media['title'] = $meta['title']; 1431 $media['desc'] = $meta['description']; 1432 $media['duration'] = $meta['duration']; 1433 $media['mobile'] = $meta['stream_url']."?client_id=006b3d9b3bbd5bd6cc7d27ab05d9a11b"; 1434 $media['direct'] = $meta['stream_url']."?client_id=006b3d9b3bbd5bd6cc7d27ab05d9a11b"; 1435 $media['iframe'] = "http://w.soundcloud.com/player/?url=".$meta['uri']."?auto_play=true&show_artwork=false&show_comments=false&color=000000&show_playcount=false&sharing=false&show_user=false&liking=false"; // http://developers.soundcloud.com/docs/oembed -- https://github.com/soundcloud/Widget-JS-API/wiki/widget-options 1436 $media['embed'] = '<iframe width="100%" height="166" scrolling="no" frameborder="no" src="'.$media['iframe'].'"></iframe>'; 1437 $media['format'] = $meta['original_format']; 1438 $media['api'] = $meta; // mp3 in this case 1439 } else { 1440 return new WP_Error('missing', "Can't extract ID from soundcloud URL..."); 1441 } 1442 break; 1443 } 1444 1445 if (empty($media)) return new WP_Error('missing', "Somehow we failed..."); 1446 // success 1447 return $media; 1448 } 1449 1450 1451 // retrieves ID of attachment from given URL 1452 // source: Rarst http://wordpress.stackexchange.com/questions/6645/turn-a-url-into-an-attachment-post-id 1453 function get_attachment_id_from_url( $url ) { 1454 1455 $dir = wp_upload_dir(); 1456 $dir = trailingslashit($dir['baseurl']); 1457 1458 if( false === strpos( $url, $dir ) ) 1459 return new WP_Error('missing', "Something wrong with this url..."); 1460 1461 $file = basename($url); 1462 1463 $query = array( 1464 'post_type' => 'attachment', 1465 'fields' => 'ids', 1466 'meta_query' => array( 1467 array( 1468 'value' => $file, 1469 'compare' => 'LIKE', 1470 ) 1471 ) 1472 ); 1473 1474 $query['meta_query'][0]['key'] = '_wp_attached_file'; 1475 $ids = get_posts( $query ); 1476 1477 foreach( $ids as $id ) 1478 if ( $url == array_shift( wp_get_attachment_image_src($id, 'full') ) ) 1479 return $id; 1480 1481 $query['meta_query'][0]['key'] = '_wp_attachment_metadata'; 1482 $ids = get_posts( $query ); 1483 1484 foreach( $ids as $id ) { 1485 1486 $meta = wp_get_attachment_metadata($id); 1487 1488 foreach( $meta['sizes'] as $size => $values ) 1489 if( $values['file'] == $file && $url == array_shift( wp_get_attachment_image_src($id, $size) ) ) { 1490 1491 return $id; 1492 } 1493 } 1494 1495 return new WP_Error('missing', "Somehow we failed..."); 1496 } 1497 1498 /** 1499 * Download an image from the specified URL and attach it to a post. 1500 * Modified version of core function media_sideload_image() in /wp-admin/includes/media.php (which returns an html img tag instead of attachment ID) 1501 * Additional functionality: ability override actual filename, set as post thumbnail, and to pass $post_data to override values in wp_insert_attachment (original only allowed $desc) 1502 * 1503 * @since 1.4 1504 * 1505 * @param string $url (required) The URL of the image to download 1506 * @param int $post_id (required) The post ID the media is to be associated with 1507 * @param bool $thumb (optional) Whether to make this attachment the Featured Image for the post 1508 * @param string $filename (optional) Replacement filename for the URL filename (do not include extension) 1509 * @param array $post_data (optional) Array of key => values for wp_posts table (ex: 'post_title' => 'foobar', 'post_status' => 'draft') 1510 * @return int|object The ID of the attachment or a WP_Error on failure 1511 */ 1512 function attach_external_image( $url = null, $post_id = null, $thumb = null, $filename = null, $post_data = array() ) { 1513 if ( !$url || !$post_id ) return new WP_Error('missing', "Need a valid URL and post ID..."); 1514 if ( !self::array_is_associative( $post_data ) ) return new WP_Error('missing', "Must pass post data as associative array..."); 1515 1516 // Download file to temp location, returns full server path to temp file, ex; /home/somatics/public_html/mysite/wp-content/26192277_640.tmp MUST BE FOLLOWED WITH AN UNLINK AT SOME POINT 1517 $tmp = download_url( $url ); 1518 1519 // If error storing temporarily, unlink 1520 if ( is_wp_error( $tmp ) ) { 1521 @unlink($file_array['tmp_name']); // clean up 1522 $file_array['tmp_name'] = ''; 1523 return $tmp; // output wp_error 1524 } 1525 1526 preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $url, $matches); // fix file filename for query strings 1527 $url_filename = basename($matches[0]); // extract filename from url for title 1528 $url_type = wp_check_filetype($url_filename); // determine file type (ext and mime/type) 1529 1530 // override filename if given, reconstruct server path 1531 if ( !empty( $filename ) ) { 1532 $filename = sanitize_file_name($filename); 1533 $tmppath = pathinfo( $tmp ); // extract path parts 1534 $new = $tmppath['dirname'] . "/". $filename . "." . $tmppath['extension']; // build new path 1535 rename($tmp, $new); // renames temp file on server 1536 $tmp = $new; // push new filename (in path) to be used in file array later 1537 } 1538 1539 // assemble file data (should be built like $_FILES since wp_handle_sideload() will be using) 1540 $file_array['tmp_name'] = $tmp; // full server path to temp file 1541 1542 if ( !empty( $filename ) ) { 1543 $file_array['name'] = $filename . "." . $url_type['ext']; // user given filename for title, add original URL extension 1544 } else { 1545 $file_array['name'] = $url_filename; // just use original URL filename 1546 } 1547 1548 // set additional wp_posts columns 1549 if ( empty( $post_data['post_title'] ) ) { 1550 $post_data['post_title'] = basename($url_filename, "." . $url_type['ext']); // just use the original filename (no extension) 1551 } 1552 1553 // make sure gets tied to parent 1554 if ( empty( $post_data['post_parent'] ) ) { 1555 $post_data['post_parent'] = $post_id; 1556 } 1557 1558 // required libraries for media_handle_sideload 1559 require_once(ABSPATH . 'wp-admin/includes/file.php'); 1560 require_once(ABSPATH . 'wp-admin/includes/media.php'); 1561 require_once(ABSPATH . 'wp-admin/includes/image.php'); 1562 1563 // do the validation and storage stuff 1564 $att_id = media_handle_sideload( $file_array, $post_id, null, $post_data ); // $post_data can override the items saved to wp_posts table, like post_mime_type, guid, post_parent, post_title, post_content, post_status 1565 1566 // If error storing permanently, unlink 1567 if ( is_wp_error($att_id) ) { 1568 @unlink($file_array['tmp_name']); // clean up 1569 return $att_id; // output wp_error 1570 } 1571 1572 // set as post thumbnail if desired 1573 if ($thumb) { 1574 set_post_thumbnail($post_id, $att_id); 1575 } 1576 1577 return $att_id; 1578 } 1579 1580 /** 1581 * Gets the excerpt of a specific post ID or object - if one doesn't exist, it will create one dynamically 1582 * @since 1.7.3 1583 * 1584 * @param - $post - object/int/string - the ID or object of the post to get the excerpt of 1585 * @param - $length - int - the length of the excerpt in words 1586 * @param - $tags - string - the allowed HTML tags. These will not be stripped out 1587 * @param - $extra - string - text to append to the end of the excerpt 1588 */ 1589 function fetch_excerpt($post, $length = 30, $tags = '<a><em><strong>', $extra = '…') { 1590 1591 if (is_wp_error($post)) return $post; 1592 if (empty($post)) return new WP_Error('missing', "must pass a post argument!"); 1593 if (!is_object($post)) { 1594 $post = get_post(intval($post)); 1595 } 1596 if (!is_object($post)) { 1597 return new WP_Error('error', "Can't retrieve the requested post..."); 1598 } 1599 1600 if (has_excerpt($post->ID)) { 1601 $the_excerpt = $post->post_excerpt; 1602 return apply_filters('the_content', $the_excerpt); 1603 } else { 1604 $the_excerpt = $post->post_content; 1605 } 1606 1607 $the_excerpt = strip_shortcodes(strip_tags($the_excerpt), $tags); 1608 $the_excerpt = preg_split('/\b/', $the_excerpt, $length * 2+1); 1609 $excerpt_waste = array_pop($the_excerpt); 1610 $the_excerpt = implode($the_excerpt); 1611 $the_excerpt .= $extra; 1612 1613 return apply_filters('the_content', $the_excerpt); 1614 } 1615 1616 /** 1617 * generates HTML link code in conjunction with the soma_go_redirect option 1618 * won't work unless you've already hooked the soma_go_redirect_codes filter and added a slug/url pair 1619 * @since 1.7.6 1620 * 1621 * @param - $slug - string - properly formatted slug for the url: /go/[slug] 1622 * @param - $text - string - text to be wrapped inside the <a> tags 1623 * @return - string - HTML link code 1624 */ 1625 function make_go_link($slug = null, $text = null) { 1626 if (empty($slug) || empty($text)) return new WP_Error('missing', "must pass a slug and text argument!"); 1627 $slug = sanitize_title_with_dashes($slug); 1628 $text = sanitize_title($text); 1629 $codes = apply_filters('soma_go_redirect_codes', $codes); 1630 if (array_key_exists($slug, $codes)) { 1631 return "<a href='{$codes[$slug]}' rel='nofollow'>$text</a>"; 1632 } else { 1633 return new WP_Error('error', "that slug hasn't been added yet, so I can't give you a URL ..."); 1634 } 1635 1636 } 1637 1638 // Returns array of details about a file (only works on attachments) 1639 // ------------------------------------------------------------- 1640 function fetch_file($pid = null) { 1641 if ( empty( $pid ) ) return false; 1642 $type = get_post_type( intval( $pid ) ); 1643 if ( $type != "attachment" ) return false; 1644 1645 $file_path = get_attached_file( $pid ); 1646 $file = pathinfo( $file_path ); // returns array of dirname, basename, extension, filename 1647 $file['mime'] = get_post_mime_type( $pid ); // returns mime type 1648 $file['url'] = wp_get_attachment_url( $pid ); // returns full URL for downloading 1649 $file['secure'] = self::build_request_link('legacy-download', $pid); // returns secure download URL 1650 if ( is_file( SOMA_DIR . "images/file-icons/" . $file['extension'] . ".png" ) ) { 1651 $file['icon'] = SOMA_IMG . 'file-icons/'. $file['extension'].'.png'; 1652 } else { 1653 $file['icon'] = SOMA_IMG . 'file-icons/bin.png'; 1654 } 1655 $file['time'] = get_post_time("U", true, $pid); 1656 return $file; 1657 } 1658 1659 // Return all sub pages of a given post 1660 // ------------------------------------------------------------- 1661 function fetch_sub_pages($pid = null) { 1662 if (empty($pid)) return null; 1663 $post_type = get_post_type($pid); 1664 $args = array( 1665 'post_type' => $post_type, 1666 'child_of' => $pid, 1667 'parent' => $pid, 1668 'sort_order' => 'ASC', 1669 'sort_column' => 'menu_order', 1670 'numberposts' => -1 1671 ); 1672 return get_pages($args); 1673 } 1674 1675 // Return all root (top-level) posts of any given post type 1676 // ------------------------------------------------------------- 1677 function fetch_root_pages($post_type = 'page') { 1678 $args = array( 1679 'post_type' => $post_type, 1680 'parent' => 0, 1681 'order' => 'ASC', 1682 'orderby' => 'menu_order', 1683 'numberposts' => -1 1684 ); 1685 return get_pages($args); 1686 } 1687 1688 /** 1689 * Helps in use of dash and underscore in field ID's of richtext field types (dealing with wp_editor() finicky rules) 1690 * @since 1.8.1 1691 * 1692 * @param - $id - string - user defined ID for this field, anything that's not a lowercase letter or a dash or underscore will get trashed!! 1693 * @return - $sanID - string - safe ID with obfuscations 1694 */ 1695 1696 function sanitize_wpeditor_id($id) { 1697 $sanID = preg_replace('/_+/', 'uuuuu', $id); // to preserve some backwards compatibility, we'll make special replacements for dashes and underscores, so they'll get preserved 1698 $sanID = preg_replace('/-+/', 'ddddd', $sanID); 1699 $sanID = preg_replace('/[^a-z]+/', '', $sanID); // final pass to eliminate all non-alpha characters 1700 return $sanID; 1701 } 1702 1703 1704 function unsanitize_wpeditor_id($id) { 1705 $unsanID = preg_replace('/uuuuu+/', '_', $id); // to preserve some backwards compatibility, we'll make special replacements for dashes and underscores, so they'll get preserved 1706 $unsanID = preg_replace('/ddddd+/', '-', $unsanID); 1707 return $unsanID; 1708 } 1709 1710 1711 /** 1712 * Constructs URL string to be used to trigger the soma_request_ action hook of the somaRequest Class 1713 * typically used to pass an array of data to a custom function 1714 * 1715 * @since 1.8.5 1716 * 1717 * @param - $action - (string) identifier used to assemble the action hook 1718 * @return - $data - (string/array) - stuff to be sent to the hooked function 1719 */ 1720 1721 function build_request_link($action = null, $data = null) { 1722 if (empty($action) || empty($data)) return new WP_Error('error', 'action or data missing for the request!'); 1723 $safedata = http_build_query(array('data' => $data)); // prepare data contents (even associative or indexed arrays) for inclusion in the URL 1724 $link = get_option('siteurl') . "?soma_request=$action&$safedata&security=" . wp_create_nonce( "soma-request" ); 1725 return $link; 1726 } 1725 1727 1726 1728 } -
somatic-framework/trunk/inc/somaMetaboxes.php
r1131509 r1962318 268 268 $meta = somaFunctions::fetch_post_author($post->ID, 'link'); 269 269 } else { 270 $meta = $post-> $field['id'];270 $meta = $post->{$field['id']}; 271 271 } 272 272 // gotta make our own field ID that won't conflict with core ID's, which otherwise might get hijacked (confused for the actual core metabox data) during save -
somatic-framework/trunk/inc/somaOptions.php
r1317256 r1962318 280 280 function add_pages() { 281 281 add_menu_page( 'Somatic Framework Options', 'Somatic', 'update_core', 'somatic-framework-options', null, 'dashicons-admin-generic', '91' ); 282 add_submenu_page( 'somatic-framework-options', 'Framework Options', 'Options', 'update_core', 'somatic-framework-options', create_function( null, 'somaOptions::soma_options_page("options");' ) ); 283 add_submenu_page( 'somatic-framework-options', 'Advanced', 'Advanced', 'update_core', 'somatic-framework-advanced', create_function( null, 'somaOptions::soma_options_page("advanced");' ) ); 284 add_submenu_page( 'somatic-framework-options', 'System Reports', 'Reports', 'update_core', 'somatic-framework-reports', create_function( null, 'somaOptions::soma_options_page("reports");' ) ); 282 add_submenu_page( 'somatic-framework-options', 'Framework Options', 'Options', 'update_core', 'somatic-framework-options', 283 function() { somaOptions::soma_options_page("options"); } 284 ); 285 add_submenu_page( 'somatic-framework-options', 'Advanced', 'Advanced', 'update_core', 'somatic-framework-advanced', 286 function() { somaOptions::soma_options_page("advanced"); } 287 ); 288 add_submenu_page( 'somatic-framework-options', 'System Reports', 'Reports', 'update_core', 'somatic-framework-reports', 289 function() { somaOptions::soma_options_page("reports"); } 290 ); 285 291 // add_submenu_page('options-general.php', 'Help Text', 'Help Text', 'update_core', 'soma-help-editor', array(__CLASS__,'soma_help_page'), SOMA_IMG.'soma-downloads-menu.png'); 286 292 } … … 390 396 function soma_help_validate( $input ) { 391 397 // strip html 392 array_walk( $input, create_function( '&$v,$k', '$v = wp_filter_nohtml_kses($v);' ));398 array_walk( $input, function( &$v,$k ) { $v = wp_filter_nohtml_kses($v); } ); 393 399 return $input; 394 400 } -
somatic-framework/trunk/inc/somaSave.php
r789047 r1962318 44 44 // metadata fields complete? 45 45 if ( has_term( 'incomplete', 'metadata', $pid ) ) { 46 add_filter('redirect_post_location', create_function('$location','return add_query_arg("meta_missing", true, $location);')); 46 add_filter('redirect_post_location', function($location) { return add_query_arg("meta_missing", true, $location); } 47 ); 47 48 $meta_missing = true; 48 49 } … … 55 56 $wpdb->update( $wpdb->posts, array( 'post_status' => 'draft' ), array( 'ID' => $pid ) ); 56 57 // filter the query URL to change the published message 57 add_filter('redirect_post_location', create_function('$location','return add_query_arg("message", "4", $location);'));58 add_filter('redirect_post_location', function($location) { return add_query_arg("message", "4", $location); } ); 58 59 // filter the query URL to display failure notice 59 add_filter('redirect_post_location', create_function('$location','return add_query_arg("validation", "fail", $location);'));60 add_filter('redirect_post_location', function($location) { return add_query_arg("validation", "fail", $location); } ); 60 61 } else { 61 62 // filter the query URL to display success notice 62 add_filter('redirect_post_location', create_function('$location','return add_query_arg("validation", "submitted", $location);'));63 add_filter('redirect_post_location', function($location) { return add_query_arg("validation", "submitted", $location); } ); 63 64 } 64 65 } … … 71 72 $wpdb->update( $wpdb->posts, array( 'post_status' => 'pending' ), array( 'ID' => $pid ) ); 72 73 // filter the query URL to change the published message 73 add_filter('redirect_post_location', create_function('$location','return add_query_arg("message", "4", $location);'));74 add_filter('redirect_post_location', function($location) { return add_query_arg("message", "4", $location); } ); 74 75 // filter the query URL to display failure notice 75 add_filter('redirect_post_location', create_function('$location','return add_query_arg("validation", "fail", $location);'));76 add_filter('redirect_post_location', function($location) { return add_query_arg("validation", "fail", $location); } ); 76 77 } else { 77 78 if ( isset($_POST['publish']) && $_POST['post_status'] == 'publish' ) { 78 79 // filter the query URL to display success notice (only if we're publishing, not just updating a published item) 79 add_filter('redirect_post_location', create_function('$location','return add_query_arg("validation", "success", $location);'));80 add_filter('redirect_post_location', function($location) { return add_query_arg("validation", "success", $location); } ); 80 81 } 81 82 } … … 223 224 // 224 225 if ($field['data'] == 'core') { 225 $old = $post-> $field['id'];226 $old = $post->{$field['id']}; 226 227 } 227 228 -
somatic-framework/trunk/inc/somaTypes.php
r1597748 r1962318 286 286 // remove for each post type 287 287 foreach ( $types as $type ) { 288 add_action( 'add_meta_boxes', create_function( '', " 289 remove_meta_box( \"$box\", \"$type\", \"side\" ); 290 " ) ); 288 add_action( 'add_meta_boxes', function() { remove_meta_box( $box, $type, side ); } ); 291 289 } 292 290 } -
somatic-framework/trunk/readme.txt
r1597763 r1962318 5 5 Requires at least: 4.0 6 6 Tested up to: 4.7 7 Stable tag: 1.8.1 27 Stable tag: 1.8.13 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 32 32 33 33 == Changelog == 34 35 = 1.8.13 = 36 * tweaks for PHP 7.2 compatibility 34 37 35 38 = 1.8.12 = -
somatic-framework/trunk/somaticFramework.php
r1598280 r1962318 4 4 Plugin URI: http://wordpress.org/extend/plugins/somatic-framework/ 5 5 Description: Adds useful classes for getting the most out of Wordpress' advanced CMS features 6 Version: 1.8.1 26 Version: 1.8.13 7 7 Author: Israel Curtis 8 8 Author URI: mailto:[email protected]
Note: See TracChangeset
for help on using the changeset viewer.