1<?php
2
3if (!defined('DOKU_INC')) die();
4
5class helper_plugin_conform extends DokuWiki_Plugin
6{
7    function getInfo()
8    {
9        return array(
10            'author' => 'William Fletcher',
11            'email'  => 'uiriamu.furecchaa@gmail.com',
12            'date'   => '2008-09-08',
13            'name'   => 'conform',
14            'desc'   => 'Creates HTML forms properly',
15            'url'    => 'http://http://thirdforces.internationalconspiracy.org/~ultraviolet/software/conform/',
16        );
17    }
18
19    function getMethods()
20    {
21        $result = array();
22        $result[] = array(
23                'name'   => 'conformExtract',
24                'desc'   => 'Absorbs the raw form information, syntax checks it and places it in a neat array for further processing',
25                );
26        return $result;
27    }
28
29    function conformExtract ( $data )
30    {
31        $lines = explode(';', $data);
32        $errors = array();
33        $argcheck = array(
34                            'MailTo'      => 2,
35			    'MailSubject' => 2,
36                            'Textbox'     => 4,
37                            'Constraint'  => 4,
38                            'Select'      => 5,
39                            'Textarea'    => 5,
40                            'Radio'       => 4,
41                            'Checkbox'    => 4,
42                            'Line'        => 1,
43                            'Static'      => 2,
44                            'Submit'      => 3,
45                            'RowsStart'   => 2,
46                            'RowsEnd'     => 1
47                         );
48        $linecount               = 0;
49        $tablemode               = 0;
50        $tables                  = array();
51        $tablecount              = 0;
52        $attrs                   = array();
53        $required                = array();
54        $attributes              = array();
55        $constraints             = array();
56	$constraintargs          = array();
57        $maxcolumns              = 0;
58        $required['MailTo']      = 0;
59        $required['Submit']      = 0;
60	$required['MailSubject'] = 0;
61        foreach ($lines as $line)
62        {
63            $linecount++;
64            if (empty($line) || preg_match("/^\s*$/", $line)) continue;
65            $args = $this->conformTemplateLineParse($line);
66            if ( ! array_key_exists($args[0], $argcheck) )
67            {
68                array_push($errors, "Line: $linecount --> Keyword '$args[0]' doesn't exist!");
69                continue;
70            }
71            else
72            {
73                if ( count($args) != $argcheck[$args[0]] )
74                {
75                    array_push($errors, "Line: $linecount --> Keyword '$args[0]' has the wrong number (".count($args).") of arguments!");
76                }
77                else if ( count($args) > 1 )
78                {
79                    $lowerattribute = strtolower($args[1]);
80                    switch ( $args[0] )
81                    {
82                        case 'MailTo':
83			case 'MailSubject':
84			    if ( $required[$args[0]] == 1 )
85			    {
86				array_push($errors, "Line: $linecount --> Keyword '$args[0]' is repeated!");
87			    }
88                            break;
89
90			case 'RowsStart':
91			case 'Static':
92			    break;
93
94                        case 'Constraint':
95                            if ( ! is_array($constraints[$lowerattribute]) ) $constraints[$lowerattribute] = array();
96                            array_push($constraints[$lowerattribute], $linecount);
97                            break;
98
99                        default:
100                            if ( preg_match("/_/", $lowerattribute) )
101                            {
102                                array_push($errors, "Line: $linecount --> Attribute '$args[1]' isn't allowed to contain a _ character!");
103                            }
104                            if ( in_array($lowerattribute, $attributes) )
105                            {
106                                array_push($errors, "Line: $linecount --> Attribute '$args[1]' is repeated!");
107                            }
108                            else
109                            {
110                                array_push($attributes, $lowerattribute);
111                            }
112                    }
113                }
114            }
115            switch ( $args[0] )
116            {
117                case 'MailTo':
118		    $emailtoallow       = $this->conformList($this->getConf('conformEmailAllow'));
119		    $emailto            = $args[1];
120		    $emailtolist        = $this->conformList($args[1]);
121		    foreach ( $emailtolist as $mailto )
122		    {
123			if ( ! in_array($mailto, $emailtoallow) )
124			{
125			    array_push($errors, "Line: $linecount --> E-mail address $mailto not in allowlist!");
126			}
127		    }
128                    $required[$args[0]] = 1;
129                    break;
130		case 'MailSubject':
131		    $required[$args[0]] = 1;
132		    $emailsubject       = $args[1];
133		    break;
134                case 'RowsStart':
135                    if ( count($tables) != 0 ) $tablecount++;
136                    $tablemode = 1;
137                    $this->conformTablesCreate($tables, $tablecount, $tablemode);
138                    if ( ! is_numeric($args[1]) ) $args[1] = 1;
139                    $tables[$tablecount]['rows']     = $args[1];
140                    $tables[$tablecount]['complete'] = 0;
141                    break;
142                case 'RowsEnd':
143                    $columns = count($tables[$tablecount]['args']);
144                    if ( $columns > $maxcolumns ) $maxcolumns = $columns;
145                    $tables[$tablecount]['columns'] = ($columns - 1);
146                    $tables[$tablecount]['complete'] = 1;
147                    $tablemode = 0;
148                    $tablecount++;
149                    $this->conformTablesCreate($tables, $tablecount, $tablemode);
150                    break;
151		case 'Constraint':
152		    $check = explode("=", $args[3], 2);
153		    switch($check[0])
154		    {
155			case 'maxLength':
156			case 'minLength':
157			    break;
158			default:
159			    array_push($errors, "Constraint '$args[1]' isn't contains incorrect check $check[0]!");
160		    }
161		    array_push( $constraintargs, $args );
162		    break;
163                case 'Submit':
164                    $required[$args[0]] = 1;
165		case 'Radio':
166		case 'Select':
167		    $args[3] = $this->conformList($args[3]);
168                default:
169                    if ( count($tables) == 0 && $tablecount == 0 )
170                    {
171                        $this->conformTablesCreate($tables, $tablecount, $tablemode);
172                    }
173                    array_push( $tables[$tablecount]['args'], $args );
174                    break;
175            }
176        }
177        foreach ( $required as $requiredcheck => $requiredvalue )
178        {
179            if ( $requiredvalue != 1 ) array_push($errors, "$requiredcheck keyword is required to exist!");
180        }
181        foreach ( $constraints as $constraint => $constraintlines )
182        {
183            if ( ! in_array($constraint, $attributes) )
184            {
185                foreach ( $constraintlines as $constraintline )
186                {
187                    array_push($errors, "Line: $constraintline --> Attribute '$constraint' doesn't exist!");
188                }
189            }
190        }
191        $batch = array();
192	$batch['to']          = $emailto;
193	$batch['subject']     = $emailsubject;
194        $batch['maxcolumns']  = $maxcolumns;
195	$batch['constraints'] = $constraintargs;
196        $batch['errors']      = $errors;
197        $batch['tables']      = $tables;
198        $batch['tablecount']  = $tablecount;
199	$batch['idallow']     = $this->conformList($this->getConf('conformAllow'));
200        return $batch;
201    }
202
203    function conformTemplateLineParse($line)
204    {
205        $args = array();
206        $inQuote = FALSE;
207        for(  $i = 1 ; $i <= strlen($line); $i++  )
208        {
209            if( $line{$i} == '"' )
210            {
211                if($inQuote)
212                {
213                    array_push($args, htmlspecialchars($arg));
214                    $inQuote = FALSE;
215                    $arg = "";
216                    continue;
217                }
218                else
219                {
220                    $inQuote = TRUE;
221                    continue;
222                }
223            }
224            else if ( $line{$i} == ' ' )
225            {
226                if($inQuote)
227                {
228                    $arg .= ' ';
229                    continue;
230                }
231                else
232                {
233                    if ( strlen($arg) < 1 ) continue;
234                    array_push($args, htmlspecialchars($arg));
235                    $arg = "";
236                    continue;
237                }
238            }
239            $arg .= $line{$i};
240        }
241        if ( strlen($arg) > 0 ) array_push($args, htmlspecialchars($arg));
242        return $args;
243    }
244
245    function conformTablesCreate(&$tables, $tablecount, $tablemode)
246    {
247        $tables[$tablecount]['mode'] = $tablemode;
248        $tables[$tablecount]['args'] = array();
249    }
250
251    function conformList($list)
252    {
253        $values      = explode(',', $list);
254        $cleanvalues = array();
255        foreach ( $values as $value )
256        {
257            array_push($cleanvalues, trim($value));
258        }
259        return $cleanvalues;
260    }
261
262}
263