Jyxo\Mail\Parser::setStructure PHP 메소드

setStructure() 개인적인 메소드

Creates message structure.
private setStructure ( array $subparts = null, string $parentPartId = null, boolean $skipPart = false, boolean $lastWasSigned = false )
$subparts array Subparts
$parentPartId string Parent Id
$skipPart boolean Skip parts
$lastWasSigned boolean Was the pared signed
    private function setStructure(array $subparts = null, string $parentPartId = null, bool $skipPart = false, bool $lastWasSigned = false)
    {
        // First call - an object returned by the imap_fetchstructure function is returned
        if (null === $subparts) {
            $this->structure['obj'] = imap_fetchstructure($this->connection, $this->uid, FT_UID);
            if (!$this->structure['obj']) {
                throw new Parser\EmailNotExistException('Email does not exist');
            }
        }
        // Sometimes (especially in spams) the type is missing
        if (empty($this->structure['obj']->type)) {
            $this->structure['obj']->type = TYPETEXT;
        }
        // For situations when the body is missing but we have attachments
        if ($this->structure['obj']->type != TYPETEXT && $this->structure['obj']->type != TYPEMULTIPART) {
            $temp = $this->structure['obj'];
            // Don't add a body just create the multipart container because the body wouldn't have an Id
            $this->structure['obj'] = new \stdClass();
            $this->structure['obj']->type = TYPEMULTIPART;
            $this->structure['obj']->ifsubtype = 1;
            $this->structure['obj']->subtype = 'MIXED';
            $this->structure['obj']->ifdescription = 0;
            $this->structure['obj']->ifid = '0';
            $this->structure['obj']->bytes = isset($temp->bytes) ? $temp->bytes : 0;
            $this->structure['obj']->ifdisposition = 1;
            $this->structure['obj']->disposition = 'inline';
            $this->structure['obj']->ifdparameters = 0;
            $this->structure['obj']->dparameters = [];
            $this->structure['obj']->ifparameters = 0;
            $this->structure['obj']->parameters = [];
            $this->structure['obj']->parts = [$temp];
        }
        // Deals a multipart/alternative or multipart/report problem when they are as the first part
        if (null === $subparts && null === $parentPartId) {
            $ftype = empty($this->structure['obj']->type) ? $this->getMajorMimeType(0) . '/' . strtolower($this->structure['obj']->subtype) : $this->getMajorMimeType($this->structure['obj']->type) . '/' . strtolower($this->structure['obj']->subtype);
            // As first they do not have any actual Id, assign a fake one 0
            $this->structure['pid'][0] = '0';
            $this->structure['ftype'][0] = $ftype;
            $this->structure['encoding'][0] = !empty($this->structure['obj']->encoding) ? self::$encodingTypes[$this->structure['obj']->encoding] : self::$encodingTypes[0];
            $this->structure['fsize'][0] = !empty($this->structure['obj']->bytes) ? $this->structure['obj']->bytes : 0;
            $this->structure['disposition'][0] = 'inline';
        }
        // Subparts
        if (isset($this->structure['obj']->parts) || is_array($subparts)) {
            if (is_array($subparts)) {
                $parts = $subparts;
            } else {
                $parts = $this->structure['obj']->parts;
            }
            $count = 1;
            foreach ($parts as $part) {
                // Skips multipart/mixed, following multipart/alternative or multipart/report (if this part is message/rfc822), multipart/related
                // There are more problematic parts but we haven't tested them yet
                $ftype = empty($part->type) ? $this->getMajorMimeType(0) . '/' . strtolower($part->subtype) : $this->getMajorMimeType($part->type) . '/' . strtolower($part->subtype);
                $thisIsSigned = 'multipart/signed' == $ftype;
                $skipNext = 'message/rfc822' == $ftype;
                $no = isset($this->structure['pid']) ? count($this->structure['pid']) : 0;
                // Skip parts fulfilling certain conditions
                if ('multipart/mixed' == $ftype && ($lastWasSigned || $skipPart) || 'multipart/signed' == $ftype || $skipPart && 'multipart/alternative' == $ftype || $skipPart && 'multipart/report' == $ftype || 'multipart/related' == $ftype && 1 === count($parts)) {
                    $skipped = true;
                    // Although this part is skipped, save is for later use (as Id we use the parent Id)
                    $this->structure['pid'][$no] = $parentPartId;
                    $this->structure['ftype'][$no] = $ftype;
                    $this->structure['encoding'][$no] = !empty($this->structure['obj']->encoding) ? self::$encodingTypes[$this->structure['obj']->encoding] : self::$encodingTypes[0];
                    $this->structure['fsize'][$no] = !empty($this->structure['obj']->bytes) ? $this->structure['obj']->bytes : 0;
                    $this->structure['disposition'][$no] = 'inline';
                } else {
                    $skipped = false;
                    $this->structure['pid'][$no] = !is_array($subparts) ? strval($count) : $parentPartId . '.' . $count;
                    $this->structure['ftype'][$no] = $ftype;
                    $this->structure['encoding'][$no] = !empty($part->encoding) ? self::$encodingTypes[$part->encoding] : self::$encodingTypes[0];
                    $this->structure['fsize'][$no] = !empty($part->bytes) ? $part->bytes : 0;
                    // Loads parameters
                    if ($part->ifdparameters) {
                        foreach ($part->dparameters as $param) {
                            $this->structure[strtolower($param->attribute)][$no] = strtolower($param->value);
                        }
                    }
                    if ($part->ifparameters) {
                        foreach ($part->parameters as $param) {
                            $this->structure[strtolower($param->attribute)][$no] = strtolower($param->value);
                        }
                    }
                    // Builds a part name (can be split into multiple lines)
                    if ($part->ifparameters) {
                        foreach ($part->parameters as $param) {
                            if (0 === stripos($param->attribute, 'name')) {
                                if (!isset($this->structure['fname'][$no])) {
                                    $this->structure['fname'][$no] = $param->value;
                                } else {
                                    $this->structure['fname'][$no] .= $param->value;
                                }
                            }
                        }
                    }
                    if ($part->ifdparameters && (!isset($this->structure['fname'][$no]) || empty($this->structure['fname'][$no]))) {
                        foreach ($part->dparameters as $param) {
                            if (0 === stripos($param->attribute, 'filename')) {
                                if (!isset($this->structure['fname'][$no])) {
                                    $this->structure['fname'][$no] = $param->value;
                                } else {
                                    $this->structure['fname'][$no] .= $param->value;
                                }
                            }
                        }
                    }
                    // If a name exists, decode it
                    if (isset($this->structure['fname'][$no])) {
                        $this->structure['fname'][$no] = $this->decodeFilename($this->structure['fname'][$no]);
                    }
                    // If the given part is message/rfc822, load its headers and use the subject as its name
                    if ('message/rfc822' == $ftype) {
                        $rfcHeader = $this->getHeaders($this->structure['pid'][$no]);
                        $this->structure['fname'][$no] = !empty($rfcHeader['subject']) ? $rfcHeader['subject'] . '.eml' : '';
                    }
                    // Part Id
                    if ($part->ifid) {
                        $this->structure['cid'][$no] = substr($part->id, 1, -1);
                    }
                    // Attachment or inline part (sometimes we do not get the required information from the message or it's nonsense)
                    list($type, $subtype) = explode('/', $ftype);
                    if ($part->ifdisposition && 'attachment' == strtolower($part->disposition)) {
                        $this->structure['disposition'][$no] = 'attachment';
                    } elseif (isset($this->structure['cid'][$no]) && 'image' == $type) {
                        $this->structure['disposition'][$no] = 'inline';
                    } elseif ('message' == $type || 'application' == $type || 'image' == $type || 'audio' == $type || 'video' == $type || 'model' == $type || 'other' == $type) {
                        $this->structure['disposition'][$no] = 'attachment';
                    } elseif ('text' == $type && ('html' != $subtype && 'plain' != $subtype)) {
                        $this->structure['disposition'][$no] = 'attachment';
                    } elseif ('text' == $type && isset($this->structure['fname'][$no])) {
                        $this->structure['disposition'][$no] = 'attachment';
                    } else {
                        $this->structure['disposition'][$no] = 'inline';
                    }
                }
                if (isset($part->parts) && is_array($part->parts)) {
                    if (!$skipped) {
                        $this->structure['hasAttach'][$no] = true;
                    }
                    $this->setStructure($part->parts, end($this->structure['pid']), $skipNext, $thisIsSigned);
                } elseif (!$skipped) {
                    $this->structure['hasAttach'][$no] = false;
                }
                $count++;
            }
        } else {
            // No subparts
            $this->structure['pid'][0] = '1';
            $this->structure['ftype'][0] = $this->getMajorMimeType($this->structure['obj']->type) . '/' . strtolower($this->structure['obj']->subtype);
            // If the message has only one part it should be text/plain or text/html
            if ($this->structure['ftype'][0] != 'text/plain' && $this->structure['ftype'][0] != 'text/html') {
                $this->structure['ftype'][0] = 'text/plain';
            }
            if (empty($this->structure['obj']->encoding)) {
                $this->structure['obj']->encoding = 0;
            }
            $this->structure['encoding'][0] = self::$encodingTypes[$this->structure['obj']->encoding];
            if (isset($this->structure['obj']->bytes)) {
                $this->structure['fsize'][0] = $this->structure['obj']->bytes;
            }
            $this->structure['disposition'][0] = 'inline';
            $this->structure['hasAttach'][0] = false;
            // Walks through next parameters
            if (isset($this->structure['obj']->ifparameters) && $this->structure['obj']->ifparameters) {
                foreach ($this->structure['obj']->parameters as $param) {
                    $this->structure[strtolower($param->attribute)][0] = $param->value;
                }
            }
        }
    }