Horde_Imap_Client_Socket::_fetchCmd PHP Method

_fetchCmd() protected method

Add a FETCH command to the given pipeline.
protected _fetchCmd ( Horde_Imap_Client_Interaction_Pipeline $pipeline, array $options )
$pipeline Horde_Imap_Client_Interaction_Pipeline Pipeline object.
$options array Fetch query options
    protected function _fetchCmd(Horde_Imap_Client_Interaction_Pipeline $pipeline, $options)
    {
        $fetch = new Horde_Imap_Client_Data_Format_List();
        $sequence = $options['ids']->sequence;
        /* Build an IMAP4rev1 compliant FETCH query. We handle the following
         * criteria:
         *   BINARY[.PEEK][<section #>]<<partial>> (RFC 3516)
         *     see BODY[] response
         *   BINARY.SIZE[<section #>] (RFC 3516)
         *   BODY[.PEEK][<section>]<<partial>>
         *     <section> = HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME,
         *                 TEXT, empty
         *     <<partial>> = 0.# (# of bytes)
         *   BODYSTRUCTURE
         *   ENVELOPE
         *   FLAGS
         *   INTERNALDATE
         *   MODSEQ (RFC 7162)
         *   RFC822.SIZE
         *   UID
         *
         * No need to support these (can be built from other queries):
         * ===========================================================
         *   ALL macro => (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE)
         *   BODY => Use BODYSTRUCTURE instead
         *   FAST macro => (FLAGS INTERNALDATE RFC822.SIZE)
         *   FULL macro => (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY)
         *   RFC822 => BODY[]
         *   RFC822.HEADER => BODY[HEADER]
         *   RFC822.TEXT => BODY[TEXT]
         */
        foreach ($options['_query'] as $type => $c_val) {
            switch ($type) {
                case Horde_Imap_Client::FETCH_STRUCTURE:
                    $fetch->add('BODYSTRUCTURE');
                    break;
                case Horde_Imap_Client::FETCH_FULLMSG:
                    if (empty($c_val['peek'])) {
                        $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE);
                    }
                    $fetch->add('BODY' . (!empty($c_val['peek']) ? '.PEEK' : '') . '[]' . $this->_partialAtom($c_val));
                    break;
                case Horde_Imap_Client::FETCH_HEADERTEXT:
                case Horde_Imap_Client::FETCH_BODYTEXT:
                case Horde_Imap_Client::FETCH_MIMEHEADER:
                case Horde_Imap_Client::FETCH_BODYPART:
                case Horde_Imap_Client::FETCH_HEADERS:
                    foreach ($c_val as $key => $val) {
                        $cmd = $key == 0 ? '' : $key . '.';
                        $main_cmd = 'BODY';
                        switch ($type) {
                            case Horde_Imap_Client::FETCH_HEADERTEXT:
                                $cmd .= 'HEADER';
                                break;
                            case Horde_Imap_Client::FETCH_BODYTEXT:
                                $cmd .= 'TEXT';
                                break;
                            case Horde_Imap_Client::FETCH_MIMEHEADER:
                                $cmd .= 'MIME';
                                break;
                            case Horde_Imap_Client::FETCH_BODYPART:
                                // Remove the last dot from the string.
                                $cmd = substr($cmd, 0, -1);
                                if (!empty($val['decode']) && $this->_capability('BINARY')) {
                                    $main_cmd = 'BINARY';
                                    $pipeline->data['binaryquery'][$key] = $val;
                                }
                                break;
                            case Horde_Imap_Client::FETCH_HEADERS:
                                $cmd .= 'HEADER.FIELDS';
                                if (!empty($val['notsearch'])) {
                                    $cmd .= '.NOT';
                                }
                                $cmd .= ' (' . implode(' ', array_map('Horde_String::upper', $val['headers'])) . ')';
                                // Maintain a command -> label lookup so we can put
                                // the results in the proper location.
                                $pipeline->data['fetch_lookup'][$cmd] = $key;
                        }
                        if (empty($val['peek'])) {
                            $this->openMailbox($this->_selected, Horde_Imap_Client::OPEN_READWRITE);
                        }
                        $fetch->add($main_cmd . (!empty($val['peek']) ? '.PEEK' : '') . '[' . $cmd . ']' . $this->_partialAtom($val));
                    }
                    break;
                case Horde_Imap_Client::FETCH_BODYPARTSIZE:
                    if ($this->_capability('BINARY')) {
                        foreach ($c_val as $val) {
                            $fetch->add('BINARY.SIZE[' . $val . ']');
                        }
                    }
                    break;
                case Horde_Imap_Client::FETCH_ENVELOPE:
                    $fetch->add('ENVELOPE');
                    break;
                case Horde_Imap_Client::FETCH_FLAGS:
                    $fetch->add('FLAGS');
                    break;
                case Horde_Imap_Client::FETCH_IMAPDATE:
                    $fetch->add('INTERNALDATE');
                    break;
                case Horde_Imap_Client::FETCH_SIZE:
                    $fetch->add('RFC822.SIZE');
                    break;
                case Horde_Imap_Client::FETCH_UID:
                    /* A UID FETCH will always return UID information (RFC 3501
                     * [6.4.8]). Don't add to query as it just creates a longer
                     * FETCH command. */
                    if ($sequence) {
                        $fetch->add('UID');
                    }
                    break;
                case Horde_Imap_Client::FETCH_SEQ:
                    /* Nothing we need to add to fetch request unless sequence is
                     * the only criteria (see below). */
                    break;
                case Horde_Imap_Client::FETCH_MODSEQ:
                    /* The 'changedsince' modifier implicitly adds the MODSEQ
                     * FETCH item (RFC 7162 [3.1.4.1]). Don't add to query as it
                     * just creates a longer FETCH command. */
                    if (empty($options['changedsince'])) {
                        $fetch->add('MODSEQ');
                    }
                    break;
            }
        }
        /* If empty fetch, add UID to make command valid. */
        if (!count($fetch)) {
            $fetch->add('UID');
        }
        /* Add changedsince parameters. */
        if (empty($options['changedsince'])) {
            $fetch_cmd = $fetch;
        } else {
            /* We might just want the list of UIDs changed since a given
             * modseq. In that case, we don't have any other FETCH attributes,
             * but RFC 3501 requires at least one specified attribute. */
            $fetch_cmd = array($fetch, new Horde_Imap_Client_Data_Format_List(array('CHANGEDSINCE', new Horde_Imap_Client_Data_Format_Number($options['changedsince']))));
        }
        /* The FETCH command should be the only command issued by this library
         * that should ever approach the command length limit.
         * @todo Move this check to a more centralized location (_command()?).
         * For simplification, assume that the UID list is the limiting factor
         * and split this list at a sequence comma delimiter if it exceeds
         * the character limit. */
        foreach ($options['ids']->split($this->_capability()->cmdlength) as $val) {
            $cmd = $this->_command($sequence ? 'FETCH' : 'UID FETCH')->add(array($val, $fetch_cmd));
            $pipeline->add($cmd);
        }
    }