1<?php
2/**
3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13namespace ComboStrap;
14
15/**
16 * Class PipelineUtility
17 * @package ComboStrap
18 * A pipeline to perform filter transformation
19 *
20 * See also
21 * https://getbootstrap.com/docs/5.0/helpers/text-truncation/
22 */
23class PipelineUtility
24{
25
26    /**
27     * @param $input
28     * @return string
29     */
30    static public function execute($input)
31    {
32
33        /**
34         * Get the value
35         */
36        $firstQuoteChar = strpos($input, '"');
37        $input = substr($input, $firstQuoteChar + 1);
38        $secondQuoteChar = strpos($input, '"');
39        $value = substr($input, 0, $secondQuoteChar);
40        $input = substr($input, $secondQuoteChar + 1);
41
42        /**
43         * Go to the first | and delete it from the input
44         */
45        $pipeChar = strpos($input, '|');
46        $input = substr($input, $pipeChar + 1);
47
48        /**
49         * Get the command and applies them
50         */
51        $commands = preg_split("/\|/", $input);
52        foreach ($commands as $command) {
53            $command = trim($command, " )");
54            $leftParenthesis = strpos($command, "(");
55            $commandName = substr($command, 0, $leftParenthesis);
56            $signature = substr($command, $leftParenthesis + 1);
57            $commandArgs = preg_split("/,/", $signature);
58            $commandArgs = array_map(
59                'trim',
60                $commandArgs,
61                array_fill(0, sizeof($commandArgs), "\"")
62            );
63            $commandName = trim($commandName);
64            if (!empty($commandName)) {
65                switch ($commandName) {
66                    case "replace":
67                        $value = self::replace($commandArgs, $value);
68                        break;
69                    case "head":
70                        $value = self::head($commandArgs, $value);
71                        break;
72                    case "tail":
73                        $value = self::tail($commandArgs, $value);
74                        break;
75                    case "rconcat":
76                        $value = self::concat($commandArgs, $value, "right");
77                        break;
78                    case "lconcat":
79                        $value = self::concat($commandArgs, $value, "left");
80                        break;
81                    case "cut":
82                        $value = self::cut($commandArgs, $value);
83                        break;
84                    case "trim":
85                        $value = trim($value);
86                        break;
87                    case "capitalize":
88                        $value=ucwords($value);
89                        break;
90                    default:
91                        LogUtility::msg("command ($commandName) is unknown", LogUtility::LVL_MSG_ERROR, "pipeline");
92                }
93            }
94        }
95        return $value;
96    }
97
98    private static function replace(array $commandArgs, $value)
99    {
100        $search = $commandArgs[0];
101        $replace = $commandArgs[1];
102        return str_replace($search, $replace, $value);
103    }
104
105    /**
106     * @param array $commandArgs
107     * @param $value
108     * @return false|string
109     * See also: https://getbootstrap.com/docs/5.0/helpers/text-truncation/
110     */
111    private static function head(array $commandArgs, $value)
112    {
113        $length = $commandArgs[0];
114        return substr($value, 0, $length);
115    }
116
117    private static function concat(array $commandArgs, $value, $side)
118    {
119        $string = $commandArgs[0];
120        switch ($side) {
121            case "left":
122                return $string . $value;
123            case "right":
124                return $value . $string;
125            default:
126                LogUtility::msg("The side value ($side) is unknown", LogUtility::LVL_MSG_ERROR, "pipeline");
127        }
128
129
130    }
131
132    private static function tail(array $commandArgs, $value)
133    {
134        $length = $commandArgs[0];
135        return substr($value, strlen($value) - $length);
136    }
137
138    private static function cut(array $commandArgs, $value)
139    {
140        $pattern = $commandArgs[0];
141        $words = preg_split("/$pattern/i", $value);
142        if ($words !== false) {
143            $selector = $commandArgs[1];
144            $startEndSelector = preg_split("/-/i", $selector);
145            $start = $startEndSelector[0] - 1;
146            $end = null;
147            if (isset($startEndSelector[1])) {
148                $end = $startEndSelector[1];
149                if (empty($end)) {
150                    $end = sizeof($words);
151                }
152                $end = $end - 1;
153            }
154            if ($end == null) {
155                if (isset($words[$start])) {
156                    return $words[$start];
157                } else {
158                    return $value;
159                }
160            } else {
161                $result = "";
162                for ($i = $start; $i <= $end; $i++) {
163                    if (isset($words[$i])) {
164                        if (!empty($result)) {
165                            $result .= $pattern;
166                        }
167                        $result .= $words[$i];
168                    }
169                }
170                return $result;
171            }
172
173        } else {
174            return "An error occurred: could not split with the pattern `$pattern`, the value `$value`.";
175        }
176    }
177
178}
179