CallMeAndy Posted August 20, 2012 Share Posted August 20, 2012 Hi I realise this is not the normal way to override functions but as I understand PHP does not have support for such mechanism. I am looking to modify functions in wordpress but in a way that protects my modified code from the inevitable upgrades that will be coming along. What I have done to date and whilst there will be a bit of an overhead (time) when there is an upgrade is to immediately call my version of the same function and then return - so blocking the wordpress code and routing to mine instead. n.b function suffusion_get_image($options = array()) { include_once ABSPATH.'wp-content/themes/suffusion-child/functions/media.php'; return childtheme_overide_suffusion_get_image($options = array()); .... } I have only done this with child theme functions before and do not know why doing the same with a function in wp-includes (a core part of the architecture) would have different effect. This may not be an issue merely coincidence. The function does have a recursive aspect if this is relevent. However I am getting an error spring from overriding the get_terms taxonomy function. project adventurebod raised error E_COMPILE_ERROR with message "cannot redeclare AB_overrides_get_terms() (previously declared in (file spec - THIS IS ITS OWN FILE):103)" at AB_overrides.php, line 380. Execution cannot continue. My file: AB_wp-includes_overrides.php is empty save for this function (For the moment to make sure it was working I have not changed anything in the override function as I wanted to make sure it was working in the virgin unaltered state before beginning) line 103 is the function openeing line line 380 is the final closing bracket of the function. If anybody can provide some light in here I would appreciate it, as I dont seem to be able to find the lightswitch! I wont show the whole overridden function unless someone thinks it particularly relevent as it is not in the execution path, but I have: function &get_terms($taxonomies, $args = '') { include ABSPATH.'ab_wp-includes_overrides/ab_wp-includes_overrides.php'; return AB_overrides_get_terms($taxonomies, $args = ''); ... } function &AB_overrides_get_terms($taxonomies, $args = '') { global $wpdb; $empty_array = array(); $single_taxonomy = false; if ( !is_array($taxonomies) ) { $single_taxonomy = true; $taxonomies = array($taxonomies); } foreach ( $taxonomies as $taxonomy ) { if ( ! taxonomy_exists($taxonomy) ) { $error = new WP_Error('invalid_taxonomy', __('Invalid taxonomy')); return $error; } } $defaults = array('orderby' => 'name', 'order' => 'ASC', 'hide_empty' => true, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(), 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '', 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '', 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core' ); $args = wp_parse_args( $args, $defaults ); $args['number'] = absint( $args['number'] ); $args['offset'] = absint( $args['offset'] ); if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' !== $args['parent'] ) { $args['child_of'] = 0; $args['hierarchical'] = false; $args['pad_counts'] = false; } if ( 'all' == $args['get'] ) { $args['child_of'] = 0; $args['hide_empty'] = 0; $args['hierarchical'] = false; $args['pad_counts'] = false; } $args = apply_filters( 'get_terms_args', $args, $taxonomies ); extract($args, EXTR_SKIP); if ( $child_of ) { $hierarchy = _get_term_hierarchy($taxonomies[0]); if ( !isset($hierarchy[$child_of]) ) return $empty_array; } if ( $parent ) { $hierarchy = _get_term_hierarchy($taxonomies[0]); if ( !isset($hierarchy[$parent]) ) return $empty_array; } // $args can be whatever, only use the args defined in defaults to compute the key $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : ''; $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key ); $last_changed = wp_cache_get('last_changed', 'terms'); if ( !$last_changed ) { $last_changed = time(); wp_cache_set('last_changed', $last_changed, 'terms'); } $cache_key = "get_terms:$key:$last_changed"; $cache = wp_cache_get( $cache_key, 'terms' ); if ( false !== $cache ) { $cache = apply_filters('get_terms', $cache, $taxonomies, $args); return $cache; } $_orderby = strtolower($orderby); if ( 'count' == $_orderby ) $orderby = 'tt.count'; else if ( 'name' == $_orderby ) $orderby = 't.name'; else if ( 'slug' == $_orderby ) $orderby = 't.slug'; else if ( 'term_group' == $_orderby ) $orderby = 't.term_group'; else if ( 'none' == $_orderby ) $orderby = ''; elseif ( empty($_orderby) || 'id' == $_orderby ) $orderby = 't.term_id'; else $orderby = 't.name'; $orderby = apply_filters( 'get_terms_orderby', $orderby, $args ); if ( !empty($orderby) ) $orderby = "ORDER BY $orderby"; else $order = ''; $order = strtoupper( $order ); if ( '' !== $order && !in_array( $order, array( 'ASC', 'DESC' ) ) ) $order = 'ASC'; $where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')"; $inclusions = ''; if ( !empty($include) ) { $exclude = ''; $exclude_tree = ''; $interms = wp_parse_id_list($include); foreach ( $interms as $interm ) { if ( empty($inclusions) ) $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' '; else $inclusions .= ' OR t.term_id = ' . intval($interm) . ' '; } } if ( !empty($inclusions) ) $inclusions .= ')'; $where .= $inclusions; $exclusions = ''; if ( !empty( $exclude_tree ) ) { $excluded_trunks = wp_parse_id_list($exclude_tree); foreach ( $excluded_trunks as $extrunk ) { $excluded_children = (array) AB_overrides_get_terms($taxonomies[0], array('child_of' => intval($extrunk), 'fields' => 'ids', 'hide_empty' => 0)); $excluded_children[] = $extrunk; foreach( $excluded_children as $exterm ) { if ( empty($exclusions) ) $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; else $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; } } } if ( !empty($exclude) ) { $exterms = wp_parse_id_list($exclude); foreach ( $exterms as $exterm ) { if ( empty($exclusions) ) $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; else $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' '; } } if ( !empty($exclusions) ) $exclusions .= ')'; $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args ); $where .= $exclusions; if ( !empty($slug) ) { $slug = sanitize_title($slug); $where .= " AND t.slug = '$slug'"; } if ( !empty($name__like) ) { $name__like = like_escape( $name__like ); $where .= $wpdb->prepare( " AND t.name LIKE %s", $name__like . '%' ); } if ( '' !== $parent ) { $parent = (int) $parent; $where .= " AND tt.parent = '$parent'"; } if ( $hide_empty && !$hierarchical ) $where .= ' AND tt.count > 0'; // don't limit the query results when we have to descend the family tree if ( ! empty($number) && ! $hierarchical && empty( $child_of ) && '' === $parent ) { if ( $offset ) $limits = 'LIMIT ' . $offset . ',' . $number; else $limits = 'LIMIT ' . $number; } else { $limits = ''; } if ( !empty($search) ) { $search = like_escape($search); $where .= $wpdb->prepare( " AND (t.name LIKE %s)", '%' . $search . '%'); } $selects = array(); switch ( $fields ) { case 'all': $selects = array('t.*', 'tt.*'); break; case 'ids': case 'id=>parent': $selects = array('t.term_id', 'tt.parent', 'tt.count'); break; case 'names': $selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name'); break; case 'count': $orderby = ''; $order = ''; $selects = array('COUNT(*)'); } $_fields = $fields; $fields = implode(', ', apply_filters( 'get_terms_fields', $selects, $args )); $join = "INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id"; $pieces = array( 'fields', 'join', 'where', 'orderby', 'order', 'limits' ); $clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args ); foreach ( $pieces as $piece ) $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; $query = "SELECT $fields FROM $wpdb->terms AS t $join WHERE $where $orderby $order $limits"; $fields = $_fields; if ( 'count' == $fields ) { $term_count = $wpdb->get_var($query); return $term_count; } $terms = $wpdb->get_results($query); if ( 'all' == $fields ) { update_term_cache($terms); } if ( empty($terms) ) { wp_cache_add( $cache_key, array(), 'terms', 86400 ); // one day $terms = apply_filters('get_terms', array(), $taxonomies, $args); return $terms; } if ( $child_of ) { $children = _get_term_hierarchy($taxonomies[0]); if ( ! empty($children) ) $terms = & _get_term_children($child_of, $terms, $taxonomies[0]); } // Update term counts to include children. if ( $pad_counts && 'all' == $fields ) _pad_term_counts($terms, $taxonomies[0]); // Make sure we show empty categories that have children. if ( $hierarchical && $hide_empty && is_array($terms) ) { foreach ( $terms as $k => $term ) { if ( ! $term->count ) { $children = _get_term_children($term->term_id, $terms, $taxonomies[0]); if ( is_array($children) ) foreach ( $children as $child ) if ( $child->count ) continue 2; // It really is empty unset($terms[$k]); } } } reset ( $terms ); $_terms = array(); if ( 'id=>parent' == $fields ) { while ( $term = array_shift($terms) ) $_terms[$term->term_id] = $term->parent; $terms = $_terms; } elseif ( 'ids' == $fields ) { while ( $term = array_shift($terms) ) $_terms[] = $term->term_id; $terms = $_terms; } elseif ( 'names' == $fields ) { while ( $term = array_shift($terms) ) $_terms[] = $term->name; $terms = $_terms; } if ( 0 < $number && intval(@count($terms)) > $number ) { $terms = array_slice($terms, $offset, $number); } wp_cache_add( $cache_key, $terms, 'terms', 86400 ); // one day $terms = apply_filters('get_terms', $terms, $taxonomies, $args); return $terms; } Quote Link to comment https://forums.phpfreaks.com/topic/267332-function-pseudo-overriding/ Share on other sites More sharing options...
spiderwell Posted August 20, 2012 Share Posted August 20, 2012 why cant you use override_function ()?? or how about if its in a class, extend the class, and use polymorphism to overwrite it? Quote Link to comment https://forums.phpfreaks.com/topic/267332-function-pseudo-overriding/#findComment-1370789 Share on other sites More sharing options...
CallMeAndy Posted August 20, 2012 Author Share Posted August 20, 2012 I have to confess I never knew of this function however according to the manual it is for built-in functions or class functions. In my case the function is niether, assuming it means functions built-in to to PHP. Quote Link to comment https://forums.phpfreaks.com/topic/267332-function-pseudo-overriding/#findComment-1370796 Share on other sites More sharing options...
ManiacDan Posted August 20, 2012 Share Posted August 20, 2012 It's only available in PECL (which I don't have installed) so you'll have to check the behavior of it yourself for user-defined functions. There is also rename_function, which may work for you. Quote Link to comment https://forums.phpfreaks.com/topic/267332-function-pseudo-overriding/#findComment-1370808 Share on other sites More sharing options...
CallMeAndy Posted August 20, 2012 Author Share Posted August 20, 2012 From what I understand the PECL extension for either Runkit or APD is not currently unavailable. This worries me for either of these routes as I need to use a managed hosting provider and have concerns should I build a dll myself that they will want to install it. Even were they to install it, I am nervous about unforseen development time as it would be virgin territory for me. Consequently I am now considering workarounds but please guys any ideas on this and I am all ears. Quote Link to comment https://forums.phpfreaks.com/topic/267332-function-pseudo-overriding/#findComment-1370820 Share on other sites More sharing options...
Mahngiel Posted August 21, 2012 Share Posted August 21, 2012 I am looking to modify functions in wordpress but in a way that protects my modified code from the inevitable upgrades that will be coming along. I never bothered with WP, but it would seem strange to me that a) you can't just install hooks that modify the core without having to hack the core and b)that you cannot just disable automatic updates - it would seem crazy to me to disallow THAT Quote Link to comment https://forums.phpfreaks.com/topic/267332-function-pseudo-overriding/#findComment-1371065 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.