コード例 #1
0
ファイル: option.py プロジェクト: wordpy/wordpy
def wp_load_core_site_options(site_id=None):
    ''' Loads and caches certain often requested site options if WpC.WB.Wj.is_multisite() and a persistent cache is not being used.
  @global wpdb wpdb WordPress database abstraction object.
  @param int site_id Optional site ID for which to query the options. Defaults to the current site.
  '''
    wpdb = WpC.WB.Wj.wpdb  # global wpdb

    if WpC.WB.Wj.is_multisite() or wp_using_ext_object_cache(
    ) or wp_installing():
        return

    if Php.empty(locals(), 'site_id'):
        site_id = wpdb.siteid

    core_options = array('site_name', 'siteurl', 'active_sitewide_plugins',
                         '_site_transient_timeout_theme_roots',
                         '_site_transient_theme_roots', 'site_admins',
                         'can_compress_scripts', 'global_terms_enabled',
                         'ms_files_rewriting')

    core_options_in = "'" + Php.implode("', '", core_options) + "'"
    options = wpdb.get_results(
        wpdb.prepare(
            "SELECT meta_key, meta_value FROM {} WHERE meta_key IN ({}) AND site_id = %d"
            .format(wpdb.sitemeta, core_options_in), site_id))

    for option in options:
        key = option.meta_key
        cache_key = site_id + ":" + key
        option.meta_value = maybe_unserialize(option.meta_value)

        WiCa.wp_cache_set(cache_key, option.meta_value, 'site-options')
コード例 #2
0
ファイル: term_query.py プロジェクト: wordpy/wordpy
    def parse_orderby(self, orderby_raw):
        ''' Parse and sanitize 'orderby' keys passed to the term query.
    @global wpdb wpdb WordPress database abstraction object.
    @param string orderby_raw Alias for the field to order by.
    @return string|False Value to used in the ORDER clause. False otherwise.
    '''
        _orderby = Php.strtolower(orderby_raw)
        maybe_orderby_meta = False

        if Php.in_array(_orderby, array('term_id', 'name', 'slug',
                                        'term_group'), True):
            orderby = "t.$_orderby"
        elif Php.in_array(
                _orderby,
                array('count', 'parent', 'taxonomy', 'term_taxonomy_id',
                      'description'), True):
            orderby = "tt." + _orderby
        elif 'term_order' == _orderby:
            orderby = 'tr.term_order'
        if 'count' == _orderby:
            orderby = 'tt.count'
        elif 'name' == _orderby:
            orderby = 't.name'
        elif 'slug' == _orderby:
            orderby = 't.slug'

        elif 'include' == _orderby and not Php.empty(self.query_vars,
                                                     'include'):
            include = Php.implode(
                ',', WiFc.wp_parse_id_list(self.query_vars['include']))
            orderby = "FIELD( t.term_id, {} )".format(include)
        elif 'none' == _orderby:
            orderby = ''  # elif Php.empty(locals(), '_orderby') or ...
        elif not _orderby or 'id' == _orderby or 'term_id' == _orderby:
            orderby = 't.term_id'
        else:
            orderby = 't.name'

            # This may be a value of orderby related to meta.
            maybe_orderby_meta = True

        # Filters the ORDERBY clause of the terms query.
        # @param string orderby    `ORDERBY` clause of the terms query.
        # @param array  args       An array of terms query arguments.
        # @param array  taxonomies An array of taxonomies.
        orderby = WiPg.apply_filters('get_terms_orderby', orderby,
                                     self.query_vars,
                                     self.query_vars['taxonomy'])

        # Run after the 'get_terms_orderby' filter for backward compatibility.
        if maybe_orderby_meta:
            maybe_orderby_meta = self.parse_orderby_meta(_orderby)
            if maybe_orderby_meta:
                orderby = maybe_orderby_meta

        return orderby
コード例 #3
0
ファイル: term_query.py プロジェクト: wordpy/wordpy
    def get_terms(self):
        ''' Get terms, based on query_vars.
    @global wpdb wpdb WordPress database abstraction object.
    @return array
    '''
        import wp.i.taxonomy as WiTx
        wpdb = WpC.WB.Wj.wpdb  # global wpdb

        self.parse_query(self.query_vars)
        args = self.query_vars
        #pprint(self.query_vars)  # TypeError: unhashable type: 'instancemethod'
        # userdata is array, inspect.ismethod(A.__repr__) is True
        print('WP_Term_Query.get_terms: self.query_vars=', self.query_vars)

        # Set up meta_query so it's available to 'pre_get_terms'.
        self.meta_query = WcMQ.WP_Meta_Query()
        self.meta_query.parse_query_vars(args)

        # Fires before terms are retrieved.
        # @param WP_Term_Query self Current instance of WP_Term_Query.
        WiPg.do_action('pre_get_terms', self)

        taxonomies = args['taxonomy']
        print("WcTQ.get_terms: taxonomies=", taxonomies)

        # Save queries by not crawling the tree in the case of multiple taxes or a flat tax.
        has_hierarchical_tax = False
        if taxonomies:
            for _tax in taxonomies:
                if WiTx.is_taxonomy_hierarchical(_tax):
                    has_hierarchical_tax = True

        if not has_hierarchical_tax:
            args['hierarchical'] = False
            args['pad_counts'] = False

        # 'parent' overrides 'child_of'.
        if 0 < Php.intval(args['parent']):
            args['child_of'] = False

        if 'all' == args['get']:
            args['childless'] = False
            args['child_of'] = 0
            args['hide_empty'] = 0
            args['hierarchical'] = False
            args['pad_counts'] = False

        # Filters the terms query arguments.
        # @param array args       An array of get_terms() arguments.
        # @param array taxonomies An array of taxonomies.
        args = WiPg.apply_filters('get_terms_args', args, taxonomies)
        #pprint(args)  # TypeError: unhashable type: 'instancemethod'
        # userdata is array, inspect.ismethod(A.__repr__) is True
        print('WP_Term_Query.get_terms: args=', args)

        # Avoid the query if the queried parent/child_of term has no descendants.
        child_of = args['child_of']
        parent = args['parent']

        if child_of:
            _parent = child_of
        elif parent:
            _parent = parent
        else:
            _parent = False

        if _parent:
            in_hierarchy = False
            for _tax in taxonomies:
                hierarchy = WiTx._get_term_hierarchy(_tax)

                if Php.isset(hierarchy, _parent):
                    in_hierarchy = True

            if not in_hierarchy:
                return array()

        # 'term_order' is a legal sort order only when joining the relationship
        #    table.
        _orderby = self.query_vars['orderby']
        if 'term_order' == _orderby and Php.empty(self.query_vars,
                                                  'object_ids'):
            _orderby = 'term_id'
        orderby = self.parse_orderby(_orderby)

        if orderby:
            orderby = "ORDER BY " + orderby

        order = self.parse_order(self.query_vars['order'])

        if taxonomies:
            self.sql_clauses['where']['taxonomy'] = (
                "tt.taxonomy IN ('" +
                Php.implode("', '", Php.array_map(WiF.esc_sql, taxonomies)) +
                "')")

        exclude = args['exclude']
        exclude_tree = args['exclude_tree']
        include = args['include']

        inclusions = ''
        if include:  # if not Php.empty(locals(), 'include'):
            exclude = ''
            exclude_tree = ''
            inclusions = Php.implode(',', WiFc.wp_parse_id_list(include))

        if inclusions:  # if not Php.empty(locals(), 'inclusions'):
            self.sql_clauses['where']['inclusions'] = ('t.term_id IN ( ' +
                                                       inclusions + ' )')

        exclusions = array()  # Php.array_map( int, exclusions=List)
        if exclude_tree:  # if not Php.empty(locals(), 'exclude_tree'):
            exclude_tree = WiFc.wp_parse_id_list(exclude_tree)
            excluded_children = exclude_tree
            for extrunk in exclude_tree:
                excluded_children = Php.array_merge(
                    excluded_children,
                    Php.Array(
                        get_terms(
                            taxonomies[0],
                            array(
                                ('child_of', Php.intval(extrunk)),
                                ('fields', 'ids'),
                                ('hide_empty', 0),
                            ))))
            exclusions = Php.array_merge(excluded_children, exclusions)

        if exclude:  # if not Php.empty(locals(), 'exclude'):
            exclusions = Php.array_merge(WiFc.wp_parse_id_list(exclude),
                                         exclusions)

        # 'childless' terms are those without an entry in the flattened term hierarchy.
        childless = bool(args['childless'])
        if childless:
            for _tax in taxonomies:
                term_hierarchy = WiTx._get_term_hierarchy(_tax)
                exclusions = Php.array_merge(Php.array_keys(term_hierarchy),
                                             exclusions)

        if exclusions:  # if not Php.empty(locals(), 'exclusions'):
            exclusions = 't.term_id NOT IN (' + Php.implode(
                ',', Php.array_map(Php.intval, exclusions)) + ')'
        else:
            exclusions = ''

        # Filters the terms to exclude from the terms query.
        # @param string exclusions `NOT IN` clause of the terms query.
        # @param array  args       An array of terms query arguments.
        # @param array  taxonomies An array of taxonomies.
        exclusions = WiPg.apply_filters('list_terms_exclusions', exclusions,
                                        args, taxonomies)

        if exclusions:  # if not Php.empty(locals(), 'exclusions'):
            # Must do string manipulation here for backward compatibility with filter.
            self.sql_clauses['where']['exclusions'] = preg_replace(
                '/^\s*AND\s*/', '', exclusions)

        print("\n WcTQ.get_terms: args['name'] =", args['name'])

        print("WcTQ.get_terms: taxonomies=", taxonomies)
        if not Php.empty(args, 'name'):
            names = Php.Array(args['name'])
            print("WcTQ.get_terms: names=", names, taxonomies)
            #foreach ( names as &_name ) {
            #modify list entries during for loop stackoverflow.com/questions/4081217
            for k, _name in names.items(
            ):  #use enumerate(names) if type(names)=list
                # `sanitize_term_field()` returns slashed data.
                #_name = Php.stripslashes( WiTx.sanitize_term_field(
                #                      'name', _name, 0, Php.reset(taxonomies), 'db'))
                names[k] = Php.stripslashes(
                    WiTx.sanitize_term_field('name', _name, 0,
                                             Php.reset(taxonomies), 'db'))

            print("WcTQ.get_terms: names=", names, taxonomies)
            self.sql_clauses['where']['name'] = "t.name IN ('" + Php.implode(
                "', '", Php.array_map(WiF.esc_sql, names)) + "')"

        if not Php.empty(args, 'slug'):
            if Php.is_array(args['slug']):
                slug = Php.array_map(WiF.sanitize_title, args['slug'])
                self.sql_clauses['where'][
                    'slug'] = "t.slug IN ('" + Php.implode("', '", slug) + "')"
            else:
                slug = WiF.sanitize_title(args['slug'])
                self.sql_clauses['where']['slug'] = "t.slug = 'slug'"

        if not Php.empty(args, 'term_taxonomy_id'):
            if Php.is_array(args['term_taxonomy_id']):
                tt_ids = Php.implode(
                    ',', Php.array_map(Php.intval, args['term_taxonomy_id']))
                self.sql_clauses['where']['term_taxonomy_id'] = \
                                            "tt.term_taxonomy_id IN ({})".format(tt_ids)
            else:
                self.sql_clauses['where']['term_taxonomy_id'] = wpdb.prepare(
                    "tt.term_taxonomy_id = %s",
                    args['term_taxonomy_id'])  # PyMySQL %d->%s

        if not Php.empty(args, 'name__like'):
            self.sql_clauses['where']['name__like'] = wpdb.prepare(
                "t.name LIKE %s",
                '%' + wpdb.esc_like(args['name__like']) + '%')

        if not Php.empty(args, 'description__like'):
            self.sql_clauses['where']['description__like'] = wpdb.prepare(
                "tt.description LIKE %s",
                '%' + wpdb.esc_like(args['description__like']) + '%')

        if not Php.empty(args, 'object_ids'):
            object_ids = args['object_ids']
            if not Php.is_array(object_ids):
                object_ids = array(object_ids)

            object_ids = Php.implode(', ',
                                     Php.array_map(Php.intval, object_ids))
            self.sql_clauses['where'][
                'object_ids'] = "tr.object_id IN ({})".format(object_ids)

        # When querying for object relationships, the 'count > 0' check
        # added by 'hide_empty' is superfluous.
        if not Php.empty(args['object_ids']):
            args['hide_empty'] = False

        if '' != parent:
            parent = Php.intval(parent)
            self.sql_clauses['where']['parent'] = "tt.parent = 'parent'"

        hierarchical = args['hierarchical']
        if 'count' == args['fields']:
            hierarchical = False
        if args['hide_empty'] and not hierarchical:
            self.sql_clauses['where']['count'] = 'tt.count > 0'

        number = args['number']
        offset = args['offset']

        # Don't limit the query results when we have to descend the family tree.
        if number and not hierarchical and not child_of and '' == parent:
            if offset:
                limits = 'LIMIT ' + offset + ',' + number
            else:
                limits = 'LIMIT ' + number
        else:
            limits = ''

        if not Php.empty(args, 'search'):
            self.sql_clauses['where']['search'] = self.get_search_sql(
                args['search'])

        # Meta query support.
        join = ''
        distinct = ''

        # Reparse meta_query query_vars, in case they were modified in a 'pre_get_terms' callback.
        self.meta_query.parse_query_vars(self.query_vars)
        mq_sql = self.meta_query.get_sql('term', 't', 'term_id')
        meta_clauses = self.meta_query.get_clauses()

        if not Php.empty(args, 'meta_clauses'):
            join += mq_sql['join']
            self.sql_clauses['where']['meta_query'] = preg_replace(
                '/^\s*AND\s*/', '', mq_sql['where'])
            distinct += "DISTINCT"

        selects = array()
        #switch ( args['fields'] ) {
        #  case 'all':
        AF = args['fields']
        if AF in ('all', 'all_with_object_id', 'tt_ids', 'slugs'):
            selects = array('t.*', 'tt.*')
            if ('all_with_object_id' == args['fields']
                    and not Php.empty(args, 'object_ids')):
                selects[None] = 'tr.object_id'

        #elif AF in ('ids', 'id=>parent'):
        elif AF in ('ids', 'id=>parent', 'id.parent'):
            selects = array('t.term_id', 'tt.parent', 'tt.count',
                            'tt.taxonomy')
        elif AF == 'names':
            selects = array('t.term_id', 'tt.parent', 'tt.count', 't.name',
                            'tt.taxonomy')
        elif AF == 'count':
            orderby = ''
            order = ''
            selects = array('COUNT(*)', )
        #elif AF == 'id=>name':
        elif AF in ('id=>name', 'id.name'):
            selects = array('t.term_id', 't.name', 'tt.count', 'tt.taxonomy')
        #elif AF == 'id=>slug':
        elif AF in ('id=>slug', 'id.slug'):
            selects = array('t.term_id', 't.slug', 'tt.count', 'tt.taxonomy')

        _fields = args['fields']

        # Filters the fields to select in the terms query.
        # Field lists modified using this filter will only modify the term fields returned
        # by the function when the `fields` parameter set to 'count' or 'all'. In all other
        # cases, the term fields in the results array will be determined by the `fields`
        # parameter alone.
        # Use of this filter can result in unpredictable behavior, and is not recommended.
        # @param array selects    An array of fields to select for the terms query.
        # @param array args       An array of term query arguments.
        # @param array taxonomies An array of taxonomies.
        fields = Php.implode(
            ', ',
            WiPg.apply_filters('get_terms_fields', selects, args, taxonomies))
        join += (" INNER JOIN " + wpdb.term_taxonomy +
                 " AS tt ON t.term_id = tt.term_id")

        if not Php.empty(self.query_vars, 'object_ids'):
            join += (" INNER JOIN {} AS tr ON tr.term_taxonomy_id = "
                     "tt.term_taxonomy_id".format(wpdb.term_relationships))
        where = Php.implode(' AND ', self.sql_clauses['where'])

        # Filters the terms query SQL clauses.
        # @param array pieces     Terms query SQL clauses.
        # @param array taxonomies An array of taxonomies.
        # @param array args       An array of terms query arguments.
        pieces = ('fields', 'join', 'where', 'distinct', 'orderby', 'order',
                  'limits')
        clauses = WiPg.apply_filters('terms_clauses',
                                     Php.compact(locals(), pieces), taxonomies,
                                     args)

        #fields = isset( clauses[ 'fields' ] ) ? clauses[ 'fields' ] : ''
        fields = clauses.get('fields', '')
        join = clauses.get('join', '')
        where = clauses.get('where', '')
        distinct = clauses.get('distinct', '')
        orderby = clauses.get('orderby', '')
        order = clauses.get('order', '')
        limits = clauses.get('limits', '')

        if where:
            where = "WHERE " + where

        self.sql_clauses['select'] = "SELECT {} {}".format(distinct, fields)
        self.sql_clauses['from'] = "FROM {} AS t {}".format(wpdb.terms, join)
        self.sql_clauses['orderby'] = orderby + " " + order if orderby else ''
        self.sql_clauses['limits'] = limits

        #self.request = "{self.sql_clauses['select']} {self.sql_clauses['from']} {where} {self.sql_clauses['orderby']} {self.sql_clauses['limits']}"
        self.request = "{} {} {} {} {}".format(self.sql_clauses['select'],
                                               self.sql_clauses['from'], where,
                                               self.sql_clauses['orderby'],
                                               self.sql_clauses['limits'])

        # args can be anything. Only use the args defined in defaults to compute the key.
        key = Php.md5(
            Php.serialize(
                WiFc.wp_array_slice_assoc(
                    args, Php.array_keys(self.query_var_defaults))) +
            Php.serialize(taxonomies) + self.request)
        last_changed = WiFc.wp_cache_get_last_changed('terms')
        cache_key = "get_terms:{}:{}".format(key, last_changed)
        cache = WiCa.wp_cache_get(cache_key, 'terms')
        if False != cache:
            if 'all' == _fields:
                cache = Php.array_map(WiTx.get_term, cache)

            self.terms = cache
            print("WcTQ get_terms 1 self.terms=", self.terms)
            return self.terms

        if 'count' == _fields:
            count = wpdb.get_var(self.request)
            WiCa.wp_cache_set(cache_key, count, 'terms')
            return count

        terms = wpdb.get_results(self.request)
        print("WcTQ get_terms 2 terms=", terms)
        if 'all' == _fields or 'all_with_object_id' == _fields:
            WiTx.update_term_cache(terms)
        print("WcTQ get_terms 3 terms=", terms)

        # Prime termmeta cache.
        if args['update_term_meta_cache']:
            term_ids = WiFc.wp_list_pluck(terms, 'term_id')
            WiTx.update_termmeta_cache(term_ids)

        print("WcTQ get_terms 4 terms=", terms)
        if not terms:  # if Php.empty(locals(), 'terms'):
            WiCa.wp_cache_add(cache_key, array(), 'terms',
                              WpC.WB.Wj.DAY_IN_SECONDS)
            return array()

        print("WcTQ get_terms 5 terms=", terms)
        if child_of:
            for _tax in taxonomies:
                children = WiTx._get_term_hierarchy(_tax)
                if children:  # if not Php.empty(locals(), 'children'):
                    terms = _get_term_children(child_of, terms, _tax)
                    print("WcTQ get_terms 6 terms=", terms)

        # Update term counts to include children.
        if args['pad_counts'] and 'all' == _fields:
            for _tax in taxonomies:
                _pad_term_counts(terms, _tax)

        # Make sure we show empty categories that have children.
        if hierarchical and args['hide_empty'] and Php.is_array(terms):
            for k, term in terms.items():
                Continue2 = False  #VT added to translate php: continue 2
                if not term.count:
                    children = get_term_children(term.term_id, term.taxonomy)
                    if Php.is_array(children):
                        for child_id in children:
                            child = WiTx.get_term(child_id, term.taxonomy)
                            if child.count:
                                #continue 2
                                Continue2 = True  #VT added to translate php: continue 2
                                continue  #VT added to translate php: continue 2
                    # It really is empty.
                    del terms[k]
                if Continue2:  #VT added to translate php: continue 2
                    continue  #VT added to translate php: continue 2

        print("WcTQ get_terms 7 terms=", terms)

        # When querying for terms connected to objects, we may get
        # duplicate results. The duplicates should be preserved if
        # `fields` is 'all_with_object_id', but should otherwise be
        # removed.
        if not Php.empty(args,
                         'object_ids') and 'all_with_object_id' != _fields:
            _tt_ids = array()  # need to be sperate mutable obj
            _terms = array()  # need to be sperate mutable obj
            for term in terms:
                if Php.isset(_tt_ids, getattr(term, 'term_id', None)):
                    continue
                _tt_ids[term.term_id] = 1
                _terms[None] = term

            terms = _terms

        _terms = array()  # array()
        #if 'id=>parent' == _fields:
        if _fields in ('id=>parent', 'id.parent'):
            for term in terms:
                _terms[term.term_id] = term.parent
        elif 'ids' == _fields:
            #for i,term in enumerate(terms):
            #  _terms[i] = int(term.term_id)
            for term in terms:
                _terms[None] = int(term.term_id)
        elif 'tt_ids' == _fields:
            for term in terms:
                _terms[None] = int(term.term_taxonomy_id)
        elif 'names' == _fields:
            #for i,term in enumerate(terms):
            #  _terms[i] = term.name
            for term in terms:
                _terms[None] = term.name
        elif 'slug' == _fields:
            for term in terms:
                _terms[None] = term.slug
        #elif 'id=>name' == _fields:
        elif _fields in ('id=>name', 'id.name'):
            for term in terms:
                _terms[term.term_id] = term.name
        #elif 'id=>slug' == _fields:
        elif _fields in ('id=>slug', 'id.slug'):
            for term in terms:
                _terms[term.term_id] = term.slug

        if _terms:  # if not Php.empty(locals(), '_terms'):
            terms = _terms

        # Hierarchical queries are not limited, so 'offset' and 'number' must be handled now.
        if hierarchical and number and Php.is_array(terms):
            if offset >= len(terms):
                terms = array()  # array()
            else:
                terms = Php.array_slice(terms, offset, number, True)

        WiCa.wp_cache_add(cache_key, terms, 'terms', WpC.WB.Wj.DAY_IN_SECONDS)

        if 'all' == _fields or 'all_with_object_id' == _fields:
            terms = Php.array_map(WiTx.get_term, terms)

        self.terms = terms
        return self.terms
コード例 #4
0
    def get_sql_for_clause(self, clause, parent_query, clause_key=''):
        ''' Generate SQL JOIN and WHERE clauses for a first-order query clause.
    "First-order" means that it's an array with a 'key' or 'value'.
    @global wpdb wpdb WordPress database abstraction object.
    @param array  clause       Query clause, passed by reference.
    @param array  parent_query Parent query array.
    @param string clause_key   Optional. The array key used to name the clause
                               in the original `meta_query` parameters. If not
                               provided, a key will be generated automatically
    @return array {
      Array containing JOIN & WHERE SQL clauses to append to a 1st-order query
      @type string join  SQL fragment to append to the main JOIN clause.
      @type string where SQL fragment to append to the main WHERE clause.
    }
    @return array clause    since clause passed by ref, need to return clause
    '''
        wpdb = WpC.WB.Wj.wpdb  # global wpdb

        sql_chunks = array(
            ('where', array()),
            ('join', array()),
        )

        if Php.isset(clause, 'compare'):
            clause['compare'] = clause['compare'].upper()
        else:
            clause['compare'] = 'IN' if (Php.isset(
                clause, 'value') and Php.is_array(clause['value'])) else '='

        if (not Php.in_array(
                clause['compare'],
                array('=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE',
                      'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'EXISTS',
                      'NOT EXISTS', 'REGEXP', 'NOT REGEXP', 'RLIKE'))):
            clause['compare'] = '='

        meta_compare = clause['compare']

        # First build the JOIN clause, if one is required.
        join = ''

        # We prefer to avoid joins if possible. Look for an existing join compatible with this clause.
        alias = self.find_compatible_table_alias(clause, parent_query)
        if False is alias:
            i = len(self.table_aliases)
            alias = 'mt' + i if i else self.meta_table

            # JOIN clauses for NOT EXISTS have their own syntax.
            if 'NOT EXISTS' == meta_compare:
                join += " LEFT JOIN self.meta_table"
                join += " AS " + alias if i else ''
                join += wpdb.prepare(
                    " ON (self.primary_table.self.primary_id_column = {} AND {} = %s )"
                    .format(alias.self.meta_id_column,
                            alias.meta_key), clause['key'])

            # All other JOIN clauses.
            else:
                join += " INNER JOIN self.meta_table"
                join += " AS alias" if i else ''
                join += " ON ( self.primary_table.self.primary_id_column = {} )".format(
                    alias.self.meta_id_column)

            self.table_aliases[None] = alias
            sql_chunks['join'][None] = join

        # Save the alias to this clause, for future siblings to find.
        clause['alias'] = alias

        # Determine the data type.
        _meta_type = clause['type'] if Php.isset(clause, 'type') else ''
        meta_type = self.get_cast_for_type(_meta_type)
        clause['cast'] = meta_type

        # Fallback for clause keys is the table alias. Key must be a string.
        if is_int(clause_key) or not clause_key:
            clause_key = clause['alias']

        # Ensure unique clause keys, so none are overwritten.
        iterator = 1
        clause_key_base = clause_key
        while Php.isset(self.clauses, clause_key):
            clause_key = clause_key_base + '-' + iterator
            iterator += 1

        # Store the clause in our flat array.
        #self.clauses[ clause_key ] =& clause
        # =& is assignment by reference, "means that both vars pointing at the
        #    same data, and nothing is copied anywhere"
        self.clauses[
            clause_key] = clause  # py array or {} are mutable same obj

        # Next, build the WHERE clause.

        # meta_key.
        if 'key' in clause:
            if 'NOT EXISTS' == meta_compare:
                sql_chunks['where'][
                    None] = alias + '.' + self.meta_id_column + ' IS NULL'
            else:
                sql_chunks['where'][None] = wpdb.prepare(
                    "alias.meta_key = %s", trim(clause['key']))

        # meta_value.
        if 'value' in clause:
            meta_value = clause['value']

            if meta_compare in ('IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'):
                if not Php.is_array(meta_value):
                    meta_value = preg_split('/[,\s]+/', meta_value)
            else:
                meta_value = trim(meta_value)

            #switch ( meta_compare ) {
            if meta_compare in ('IN', 'NOT IN'):
                meta_compare_string = '(' + substr(
                    str_repeat(',%s', len(meta_value)), 1) + ')'
                where = wpdb.prepare(meta_compare_string, meta_value)

            elif meta_compare in ('BETWEEN', 'NOT BETWEEN'):
                meta_value = Php.array_slice(meta_value, 0, 2)
                where = wpdb.prepare('%s AND %s', meta_value)

            elif meta_compare in ('LIKE', 'NOT LIKE'):
                meta_value = '%' + wpdb.esc_like(meta_value) + '%'
                where = wpdb.prepare('%s', meta_value)

            # EXISTS with a value is interpreted as '='.
            elif meta_compare == 'EXISTS':
                meta_compare = '='
                where = wpdb.prepare('%s', meta_value)

            # 'value' is ignored for NOT EXISTS.
            elif meta_compare == 'NOT EXISTS':
                where = ''

            else:
                where = wpdb.prepare('%s', meta_value)

            if where:
                if 'CHAR' == meta_type:
                    sql_chunks['where'][None] = "{} {} {}".format(
                        alias.meta_value, meta_compare, where)
                else:
                    sql_chunks['where'][None] = "CAST({} AS {}) {} {}".format(
                        alias.meta_value, meta_type, meta_compare, where)

        # Multiple WHERE clauses (for meta_key and meta_value) should
        # be joined in parentheses.
        if 1 < len(sql_chunks['where']):
            sql_chunks['where'] = array(
                '( ' + Php.implode(' AND ', sql_chunks['where']) + ' )')

        #return sql_chunks
        return sql_chunks, clause  #since clause passed by ref, need to return
コード例 #5
0
    def get_sql_for_query(self, query, depth=0):
        ''' Generate SQL clauses for a single query array.
    If nested subqueries are found, this method recurses the tree to
    produce the properly nested SQL.
    @param array query Query to parse, passed by reference.
    @param int   depth Optional. Number of tree levels deep we currently are.
                        Used to calculate indentation. Default 0.
    @return array {
        Array containing JOIN and WHERE SQL clauses to append to a single query array.
        @type string join  SQL fragment to append to the main JOIN clause.
        @type string where SQL fragment to append to the main WHERE clause.
    } '''
        sql_chunks = array(
            ('join', array()),
            ('where', array()),
        )

        sql = array(
            ('join', ''),
            ('where', ''),
        )

        indent = ''
        #for ( i = 0; i < depth; i++ ) {
        for i in range(depth):
            indent += "  "

        for key, clause in query.items():
            if 'relation' == key:
                relation = query['relation']
            elif Php.is_array(clause):

                # This is a first-order clause.
                if self.is_first_order_clause(clause):
                    clause_sql = self.get_sql_for_clause(clause, query, key)

                    where_count = len(clause_sql['where'])
                    if not where_count:
                        sql_chunks['where'][None] = ''
                    elif 1 is where_count:
                        sql_chunks['where'][None] = clause_sql['where'][0]
                    else:
                        sql_chunks['where'][None] = '( ' + Php.implode(
                            ' AND ', clause_sql['where']) + ' )'

                    sql_chunks['join'] = Php.array_merge(
                        sql_chunks['join'], clause_sql['join'])
                # This is a subquery, so we recurse.
                else:
                    clause_sql = self.get_sql_for_query(clause, depth + 1)

                    sql_chunks['where'][None] = clause_sql['where']
                    sql_chunks['join'][None] = clause_sql['join']

        # Filter to remove empties.
        sql_chunks['join'] = Php.array_filter(sql_chunks['join'])
        sql_chunks['where'] = Php.array_filter(sql_chunks['where'])

        if Php.empty(locals(), 'relation'):
            relation = 'AND'

        # Filter duplicate JOIN clauses and combine into a single string.
        if not Php.empty(sql_chunks, 'join'):
            sql['join'] = Php.implode(' ',
                                      Php.array_unique(sql_chunks['join']))

        # Generate a single WHERE clause with proper brackets and indentation.
        if not Php.empty(sql_chunks, 'where'):
            sql['where'] = '( ' + "\n  " + indent + Php.implode(
                ' ' + "\n  " + indent + relation + ' ' + "\n  " + indent,
                sql_chunks['where']) + "\n" + indent + ')'

        return sql