{"id":20244281,"url":"https://github.com/protonmail/libsieve-php","last_synced_at":"2025-04-06T10:12:18.984Z","repository":{"id":7835726,"uuid":"56619014","full_name":"ProtonMail/libsieve-php","owner":"ProtonMail","description":"libsieve-php is a library to manage and modify sieve (RFC5228) scripts. It contains a parser for the sieve language (including extensions) and a client for the managesieve protocol. It is written entirely in PHP 8+.","archived":false,"fork":false,"pushed_at":"2025-02-10T09:39:23.000Z","size":421,"stargazers_count":23,"open_issues_count":5,"forks_count":8,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-03-30T09:06:32.790Z","etag":null,"topics":["rfc5228","sieve","sieve-parsing"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/protonlabs/libsieve-php","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ProtonMail.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-19T17:53:06.000Z","updated_at":"2025-02-28T19:46:27.000Z","dependencies_parsed_at":"2025-02-10T10:27:34.727Z","dependency_job_id":"95652f82-6437-465f-b5ba-e08224cace4e","html_url":"https://github.com/ProtonMail/libsieve-php","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProtonMail%2Flibsieve-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProtonMail%2Flibsieve-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProtonMail%2Flibsieve-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ProtonMail%2Flibsieve-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ProtonMail","download_url":"https://codeload.github.com/ProtonMail/libsieve-php/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247464222,"owners_count":20942970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rfc5228","sieve","sieve-parsing"],"created_at":"2024-11-14T09:14:01.863Z","updated_at":"2025-04-06T10:12:18.951Z","avatar_url":"https://github.com/ProtonMail.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libsieve-php\n\n[![Build Status](https://img.shields.io/travis/ProtonMail/libsieve-php.svg?style=flat-square)](https://travis-ci.org/ProtonMail/libsieve-php)\n[![Coverage](https://img.shields.io/codecov/c/github/ProtonMail/libsieve-php.svg?style=flat-square)](https://codecov.io/gh/ProtonMail/libsieve-php)\n[![License](https://img.shields.io/github/license/ProtonMail/libsieve-php.svg?style=flat-square)](https://github.com/ProtonMail/libsieve-php/blob/master/LICENSE)\n\nlibsieve-php is a library to manage and modify sieve (RFC5228) scripts. It contains a parser for the sieve language (including extensions).\n\nThis project is adopted from the discontinued PHP sieve library available at https://sourceforge.net/projects/libsieve-php.\n\n## Changes from the RFC\n\n - The `date` and the `currentdate` both allow for `zone` parameter any string to be passed.\n   This allows the user to enter zone names like `Europe/Zurich` instead of `+0100`. \n   The reason we allow this is because offsets like `+0100` don't encode information about the\n   daylight saving time, which is often needed.\n\n## Usage examples\n\nThe libsieve parses a sieve script into a tree. This tree can then be used to interpret its meaning.\n\nTwo example will be provided: one basic and one more complex.\n### Basic Example: Check if an extension is loaded\nIn this first example, we will check if a specific extension was loaded through a require node:\n\n```php\n\u003c?php\nuse Sieve\\SieveParser;\n\nclass ExtensionCheckExample\n{\n    /** @var \\Sieve\\SieveTree the tree, obtained from the SieveParser */\n    protected $tree;\n\n    /**\n     * Parser constructor.\n     *\n     * @param string $sieve the sieve script to read.\n     */\n    public function __construct(string $sieve)\n    {\n        $parser = new SieveParser();\n        try {\n            $parser-\u003eparse($sieve);\n        } catch (\\Sieve\\SieveException $se) {\n            throw new \\Exception(\"The provided sieve script is invalid!\");\n        }\n\n        // we store the tree, because it contains all the information.\n        $this-\u003etree = $parser-\u003eGetParseTree();\n    }\n\n    /**\n     * Checks if an extension is loaded.\n     *\n     * @param string $extension\n     * @return bool\n     */\n    public function isLoaded(string $extension)\n    {\n        /** @var int $root_node_id */\n        $root_node_id = $this-\u003etree-\u003egetRoot();\n        // The root is not a node, we can only access its children\n        $children = $this-\u003etree-\u003egetChildren($root_node_id);\n        foreach ($children as $child) {\n            // The child is an id to a node, which can be access using the following:\n            $node = $this-\u003etree-\u003egetNode($child);\n\n            // is can be used to check the type of node.\n            if ($node-\u003eis(\\Sieve\\SieveToken::IDENTIFIER) \u0026\u0026 $node-\u003etext === \"require\") {\n                if ($this-\u003echeckChildren($this-\u003etree-\u003egetChildren($child), $extension)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Checks the arguments given to a require node, to know if it includes\n     *\n     * @param $children\n     * @param string $extension\n     * @return bool\n     */\n    private function checkChildren($children, string $extension): bool\n    {\n        if (is_array($children)) {\n            // it's a string list, let's loop over them.\n            foreach ($children as $child) {\n                if ($this-\u003echeckChildren($child, $extension)) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        $node = $this-\u003etree-\u003egetNode($children);\n        return $node-\u003eis(\\Sieve\\SieveToken::QUOTED_STRING) \u0026\u0026 $extension === trim($node-\u003etext, '\"');\n    }\n}\n\n// load a script, from the tests folder.\n$sieve = file_get_contents(__DIR__ . './tests/good/currentdate.siv');\n\n$runner = new ExtensionCheckExample($sieve);\nvar_dump($runner-\u003eisLoaded(\"variables\"));\n```\n\n### Complex Example: Dumping the tree\n\nThis second example will print back the sieve script from a parsed tree (note this could simply be done through\nthe method `$tree-\u003edump()`).\n\n```php\n\u003c?php\nuse Sieve\\SieveParser;\nuse Sieve;\n\nclass UsageExample\n{\n    /** @var \\Sieve\\SieveTree the tree, obtained from the SieveParser */\n    protected $tree;\n\n    /**\n     * Parser constructor.\n     *\n     * @param string $sieve the sieve script to read.\n     */\n    public function __construct(string $sieve)\n    {\n        $parser = new SieveParser();\n        try {\n            $parser-\u003eparse($sieve);\n        } catch (\\Sieve\\SieveException $se) {\n            throw new \\Exception(\"The provided sieve script is invalid!\");\n        }\n\n        // we store the tree, because it contains all the information.\n        $this-\u003etree = $parser-\u003eGetParseTree();\n    }\n\n    /**\n     * Displays the tree\n     */\n    public function display()\n    {\n        /** @var int $root_node_id */\n        $root_node_id = $this-\u003etree-\u003egetRoot();\n        // The root is not a node, we can only access its children\n        $children = $this-\u003etree-\u003egetChildren($root_node_id);\n        $this-\u003edisplayNodeList($children);\n    }\n\n    /**\n     * Loop over a list of nodes, and display them.\n     *\n     * @param int[] $nodes a list of node ids.\n     * @param string $indent\n     */\n    private function displayNodeList(array $nodes, string $indent = '')\n    {\n        foreach ($nodes as $node) {\n            $this-\u003edisplayNode($node, $indent);\n        }\n    }\n\n    /**\n     * Display a node and its children.\n     *\n     * @param int $node_id the current node id.\n     * @param string $indent\n     */\n    private function displayNode(int $node_id, string $indent)\n    {\n        /**\n         * @var \\Sieve\\SieveToken $node can be used to get info about a specific node.\n         */\n        $node = $this-\u003etree-\u003egetNode($node_id);\n\n        // All the possible node types are listed as constants in the class SieveToken...\n        switch ($node-\u003etype) {\n            case \\Sieve\\SieveToken::SCRIPT_END:\n                printf($indent . \"EOS\");\n                break;\n            case Sieve\\SieveToken::WHITESPACE:\n            case Sieve\\SieveToken::COMMENT:\n                break;\n            default:\n                // the $node-\u003etype is a integer. It can be turned into an explicit string this way...\n                $type = \\Sieve\\SieveToken::typeString($node-\u003etype);\n\n                $open_color = '';\n                $end_color = '';\n\n                // The type of a node can be checked with the is method. Mask can be used to match several types.\n                if ($node-\u003eis(\\Sieve\\SieveToken::QUOTED_STRING | Sieve\\SieveToken::MULTILINE_STRING)) {\n                    // we want to put a specific color arround strings...\n                    $open_color = \"\\e[1;32;47m\";\n                    $end_color = \"\\e[0m\";\n                }\n\n                // The children of a node can be obtain through this method:\n                $children = $this-\u003etree-\u003egetChildren($node_id);\n\n                // do whatever you want with a node and its children :) Here we are going to display them.\n                printf(\"[%4d, %-10.10s (%5d) ]%s ${open_color}%s$end_color\" . PHP_EOL, $node-\u003eline, $type, $node-\u003etype, $indent, $node-\u003etext);\n                $this-\u003edisplayNodeList($children, $indent . \"\\t\");\n        }\n    }\n}\n\n$sieve = file_get_contents(__DIR__ . '/tests/good/currentdate.siv');\n\n$parser = new UsageExample($sieve);\n$parser-\u003edisplay();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotonmail%2Flibsieve-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprotonmail%2Flibsieve-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprotonmail%2Flibsieve-php/lists"}