@@ -85,8 +85,7 @@ discard block |
||
85 | 85 | if ($this->markDepth>=sizeof($this->markers)) { |
86 | 86 | $state = new CharStreamState(); |
87 | 87 | $this->markers[] = $state; |
88 | - } |
|
89 | - else { |
|
88 | + } else { |
|
90 | 89 | $state = $this->markers[$this->markDepth]; |
91 | 90 | } |
92 | 91 | $state->p = $this->p; |
@@ -99,7 +98,7 @@ discard block |
||
99 | 98 | public function rewind($m=null) { |
100 | 99 | if($m===null){ |
101 | 100 | $this->rewind((int)$this->lastMarker); |
102 | - }else{ |
|
101 | + } else{ |
|
103 | 102 | $state = $this->markers[$m]; |
104 | 103 | // restore stream state |
105 | 104 | $this->seek($state->p); |
@@ -28,18 +28,18 @@ discard block |
||
28 | 28 | $this->markDepth = 0; |
29 | 29 | } |
30 | 30 | |
31 | - public function consume() { |
|
32 | - if ( $this->p < $this->n ) { |
|
31 | + public function consume() { |
|
32 | + if ( $this->p < $this->n ) { |
|
33 | 33 | $this->charPositionInLine++; |
34 | 34 | if ( $this->data[$this->p]==ord("\n") ) { |
35 | 35 | $this->line++; |
36 | 36 | $this->charPositionInLine=0; |
37 | 37 | } |
38 | - $this->p++; |
|
39 | - } |
|
40 | - } |
|
38 | + $this->p++; |
|
39 | + } |
|
40 | + } |
|
41 | 41 | |
42 | - public function LA($i) { |
|
42 | + public function LA($i) { |
|
43 | 43 | if ( $i==0 ) { |
44 | 44 | return 0; // undefined |
45 | 45 | } |
@@ -51,36 +51,36 @@ discard block |
||
51 | 51 | } |
52 | 52 | |
53 | 53 | if ( ($this->p+$i-1) >= $this->n ) { |
54 | - //System.out.println("char LA("+i+")=EOF; p="+p); |
|
55 | - return CharStreamConst::$EOF; |
|
56 | - } |
|
57 | - //System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p); |
|
54 | + //System.out.println("char LA("+i+")=EOF; p="+p); |
|
55 | + return CharStreamConst::$EOF; |
|
56 | + } |
|
57 | + //System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p); |
|
58 | 58 | //System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length); |
59 | 59 | return $this->data[$this->p+$i-1]; |
60 | - } |
|
60 | + } |
|
61 | 61 | |
62 | 62 | public function LT($i) { |
63 | 63 | return $this->LA($i); |
64 | 64 | } |
65 | 65 | |
66 | 66 | /** Return the current input symbol index 0..n where n indicates the |
67 | - * last symbol has been read. The index is the index of char to |
|
67 | + * last symbol has been read. The index is the index of char to |
|
68 | 68 | * be returned from LA(1). |
69 | - */ |
|
70 | - public function index() { |
|
71 | - return $this->p; |
|
72 | - } |
|
69 | + */ |
|
70 | + public function index() { |
|
71 | + return $this->p; |
|
72 | + } |
|
73 | 73 | |
74 | 74 | public function size() { |
75 | 75 | return $this->n; |
76 | 76 | } |
77 | 77 | |
78 | 78 | public function mark() { |
79 | - if ( $this->markers === null) { |
|
80 | - $this->markers = array(); |
|
81 | - $this->markers[] = null; // depth 0 means no backtracking, leave blank |
|
82 | - } |
|
83 | - $this->markDepth++; |
|
79 | + if ( $this->markers === null) { |
|
80 | + $this->markers = array(); |
|
81 | + $this->markers[] = null; // depth 0 means no backtracking, leave blank |
|
82 | + } |
|
83 | + $this->markDepth++; |
|
84 | 84 | $state = null; |
85 | 85 | if ($this->markDepth>=sizeof($this->markers)) { |
86 | 86 | $state = new CharStreamState(); |
@@ -94,9 +94,9 @@ discard block |
||
94 | 94 | $state->charPositionInLine = $this->charPositionInLine; |
95 | 95 | $this->lastMarker = $this->markDepth; |
96 | 96 | return $this->markDepth; |
97 | - } |
|
97 | + } |
|
98 | 98 | |
99 | - public function rewind($m=null) { |
|
99 | + public function rewind($m=null) { |
|
100 | 100 | if($m===null){ |
101 | 101 | $this->rewind((int)$this->lastMarker); |
102 | 102 | }else{ |
@@ -5,13 +5,13 @@ discard block |
||
5 | 5 | |
6 | 6 | /** Copy data in string to a local char array */ |
7 | 7 | public function __construct($input) { |
8 | - $this->p=0; |
|
8 | + $this->p = 0; |
|
9 | 9 | $this->line = 1; |
10 | 10 | $this->charPositionInLine = 0; |
11 | 11 | $this->markDepth = 0; |
12 | 12 | $this->markers = null; |
13 | - $this->lastMarker=0; |
|
14 | - $this->name=null; |
|
13 | + $this->lastMarker = 0; |
|
14 | + $this->name = null; |
|
15 | 15 | |
16 | 16 | $this->data = strToIntArray($input); |
17 | 17 | $this->n = strlen($input); |
@@ -29,34 +29,34 @@ discard block |
||
29 | 29 | } |
30 | 30 | |
31 | 31 | public function consume() { |
32 | - if ( $this->p < $this->n ) { |
|
32 | + if ($this->p < $this->n) { |
|
33 | 33 | $this->charPositionInLine++; |
34 | - if ( $this->data[$this->p]==ord("\n") ) { |
|
34 | + if ($this->data[$this->p] == ord("\n")) { |
|
35 | 35 | $this->line++; |
36 | - $this->charPositionInLine=0; |
|
36 | + $this->charPositionInLine = 0; |
|
37 | 37 | } |
38 | 38 | $this->p++; |
39 | 39 | } |
40 | 40 | } |
41 | 41 | |
42 | 42 | public function LA($i) { |
43 | - if ( $i==0 ) { |
|
43 | + if ($i == 0) { |
|
44 | 44 | return 0; // undefined |
45 | 45 | } |
46 | - if ( $i<0 ) { |
|
46 | + if ($i < 0) { |
|
47 | 47 | $i++; // e.g., translate LA(-1) to use offset i=0; then data[p+0-1] |
48 | - if ( ($this->p+$i-1) < 0 ) { |
|
48 | + if (($this->p + $i - 1) < 0) { |
|
49 | 49 | return CharStreamConst::$EOF; // invalid; no char before first char |
50 | 50 | } |
51 | 51 | } |
52 | 52 | |
53 | - if ( ($this->p+$i-1) >= $this->n ) { |
|
53 | + if (($this->p + $i - 1) >= $this->n) { |
|
54 | 54 | //System.out.println("char LA("+i+")=EOF; p="+p); |
55 | 55 | return CharStreamConst::$EOF; |
56 | 56 | } |
57 | 57 | //System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p); |
58 | 58 | //System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length); |
59 | - return $this->data[$this->p+$i-1]; |
|
59 | + return $this->data[$this->p + $i - 1]; |
|
60 | 60 | } |
61 | 61 | |
62 | 62 | public function LT($i) { |
@@ -76,13 +76,13 @@ discard block |
||
76 | 76 | } |
77 | 77 | |
78 | 78 | public function mark() { |
79 | - if ( $this->markers === null) { |
|
79 | + if ($this->markers === null) { |
|
80 | 80 | $this->markers = array(); |
81 | 81 | $this->markers[] = null; // depth 0 means no backtracking, leave blank |
82 | 82 | } |
83 | 83 | $this->markDepth++; |
84 | 84 | $state = null; |
85 | - if ($this->markDepth>=sizeof($this->markers)) { |
|
85 | + if ($this->markDepth >= sizeof($this->markers)) { |
|
86 | 86 | $state = new CharStreamState(); |
87 | 87 | $this->markers[] = $state; |
88 | 88 | } |
@@ -96,10 +96,10 @@ discard block |
||
96 | 96 | return $this->markDepth; |
97 | 97 | } |
98 | 98 | |
99 | - public function rewind($m=null) { |
|
100 | - if($m===null){ |
|
101 | - $this->rewind((int)$this->lastMarker); |
|
102 | - }else{ |
|
99 | + public function rewind($m = null) { |
|
100 | + if ($m === null) { |
|
101 | + $this->rewind((int) $this->lastMarker); |
|
102 | + } else { |
|
103 | 103 | $state = $this->markers[$m]; |
104 | 104 | // restore stream state |
105 | 105 | $this->seek($state->p); |
@@ -120,18 +120,18 @@ discard block |
||
120 | 120 | * update line and charPositionInLine. |
121 | 121 | */ |
122 | 122 | public function seek($index) { |
123 | - if ( $index<=$this->p ) { |
|
123 | + if ($index <= $this->p) { |
|
124 | 124 | $this->p = $index; // just jump; don't update stream state (line, ...) |
125 | 125 | return; |
126 | 126 | } |
127 | 127 | // seek forward, consume until p hits index |
128 | - while ( $this->p<$index ) { |
|
128 | + while ($this->p < $index) { |
|
129 | 129 | $this->consume(); |
130 | 130 | } |
131 | 131 | } |
132 | 132 | |
133 | 133 | public function substring($start, $stop) { |
134 | - return implode(array_map('chr', array_slice($this->data, $start, $stop-$start+1))); |
|
134 | + return implode(array_map('chr', array_slice($this->data, $start, $stop - $start + 1))); |
|
135 | 135 | } |
136 | 136 | |
137 | 137 | public function getLine() { |
@@ -36,7 +36,7 @@ |
||
36 | 36 | } |
37 | 37 | |
38 | 38 | public function __toString() { |
39 | - return "MismatchedSetException(".$this->getUnexpectedType()."!=".$this->expecting.")"; |
|
39 | + return "MismatchedSetException(" . $this->getUnexpectedType() . "!=" . $this->expecting . ")"; |
|
40 | 40 | } |
41 | 41 | } |
42 | 42 |
@@ -59,7 +59,7 @@ discard block |
||
59 | 59 | */ |
60 | 60 | class RecognitionException extends Exception { |
61 | 61 | |
62 | - public $line=0; |
|
62 | + public $line = 0; |
|
63 | 63 | |
64 | 64 | |
65 | 65 | public function __construct($input) { |
@@ -72,41 +72,41 @@ discard block |
||
72 | 72 | * can retrieve the ith Token, we have to track the Token object. |
73 | 73 | * For parsers. Even when it's a tree parser, token might be set. |
74 | 74 | */ |
75 | - $this->token=null; |
|
75 | + $this->token = null; |
|
76 | 76 | |
77 | 77 | /** If this is a tree parser exception, node is set to the node with |
78 | 78 | * the problem. |
79 | 79 | */ |
80 | - $this->node=null; |
|
80 | + $this->node = null; |
|
81 | 81 | |
82 | 82 | /** The current char when an error occurred. For lexers. */ |
83 | - $this->c=0; |
|
83 | + $this->c = 0; |
|
84 | 84 | |
85 | 85 | /** Track the line at which the error occurred in case this is |
86 | 86 | * generated from a lexer. We need to track this since the |
87 | 87 | * unexpected char doesn't carry the line info. |
88 | 88 | */ |
89 | - $this->line=0; |
|
89 | + $this->line = 0; |
|
90 | 90 | |
91 | - $this->charPositionInLine=0; |
|
91 | + $this->charPositionInLine = 0; |
|
92 | 92 | |
93 | 93 | /** If you are parsing a tree node stream, you will encounter som |
94 | 94 | * imaginary nodes w/o line/col info. We now search backwards looking |
95 | 95 | * for most recent token with line/col info, but notify getErrorHeader() |
96 | 96 | * that info is approximate. |
97 | 97 | */ |
98 | - $this->approximateLineInfo=false; |
|
98 | + $this->approximateLineInfo = false; |
|
99 | 99 | |
100 | 100 | |
101 | - if ( $this->input instanceof TokenStream ) { |
|
101 | + if ($this->input instanceof TokenStream) { |
|
102 | 102 | $this->token = $input->LT(1); |
103 | 103 | $this->line = $this->token->getLine(); |
104 | 104 | $this->charPositionInLine = $this->token->getCharPositionInLine(); |
105 | 105 | } |
106 | - if ( $this->input instanceof TreeNodeStream ) { |
|
106 | + if ($this->input instanceof TreeNodeStream) { |
|
107 | 107 | $this->extractInformationFromTreeNodeStream($input); |
108 | 108 | } |
109 | - else if ( $input instanceof CharStream ) { |
|
109 | + else if ($input instanceof CharStream) { |
|
110 | 110 | $this->c = $input->LA(1); |
111 | 111 | $this->line = $input->getLine(); |
112 | 112 | $this->charPositionInLine = $input->getCharPositionInLine(); |
@@ -121,15 +121,15 @@ discard block |
||
121 | 121 | $this->node = $nodes->LT(1); |
122 | 122 | $adaptor = $nodes->getTreeAdaptor(); |
123 | 123 | $payload = $adaptor->getToken($this->node); |
124 | - if ( $payload!=null ) { |
|
124 | + if ($payload != null) { |
|
125 | 125 | $this->token = $payload; |
126 | - if ( $payload->getLine()<= 0 ) { |
|
126 | + if ($payload->getLine() <= 0) { |
|
127 | 127 | // imaginary node; no line/pos info; scan backwards |
128 | 128 | $i = -1; |
129 | 129 | $priorNode = $nodes->LT($i); |
130 | - while ( $priorNode!=null ) { |
|
130 | + while ($priorNode != null) { |
|
131 | 131 | $priorPayload = $adaptor->getToken($priorNode); |
132 | - if ( $priorPayload!=null && $priorPayload->getLine()>0 ) { |
|
132 | + if ($priorPayload != null && $priorPayload->getLine() > 0) { |
|
133 | 133 | // we found the most recent real line / pos info |
134 | 134 | $this->line = $priorPayload->getLine(); |
135 | 135 | $this->charPositionInLine = $priorPayload->getCharPositionInLine(); |
@@ -145,10 +145,10 @@ discard block |
||
145 | 145 | $this->charPositionInLine = $payload->getCharPositionInLine(); |
146 | 146 | } |
147 | 147 | } |
148 | - else if ( $this->node instanceof Tree) { |
|
148 | + else if ($this->node instanceof Tree) { |
|
149 | 149 | $this->line = $this->node->getLine(); |
150 | 150 | $this->charPositionInLine = $this->node->getCharPositionInLine(); |
151 | - if ( $this->node instanceof CommonTree) { |
|
151 | + if ($this->node instanceof CommonTree) { |
|
152 | 152 | $this->token = $this->node->token; |
153 | 153 | } |
154 | 154 | } |
@@ -161,10 +161,10 @@ discard block |
||
161 | 161 | |
162 | 162 | /** Return the token type or char of the unexpected input element */ |
163 | 163 | public function getUnexpectedType() { |
164 | - if ( $this->input instanceof TokenStream ) { |
|
164 | + if ($this->input instanceof TokenStream) { |
|
165 | 165 | return $this->token->getType(); |
166 | 166 | } |
167 | - else if ( $this->input instanceof TreeNodeStream ) { |
|
167 | + else if ($this->input instanceof TreeNodeStream) { |
|
168 | 168 | $nodes = $this->input; |
169 | 169 | $adaptor = $nodes->getTreeAdaptor(); |
170 | 170 | return $adaptor->getType($this->node); |
@@ -105,13 +105,11 @@ discard block |
||
105 | 105 | } |
106 | 106 | if ( $this->input instanceof TreeNodeStream ) { |
107 | 107 | $this->extractInformationFromTreeNodeStream($input); |
108 | - } |
|
109 | - else if ( $input instanceof CharStream ) { |
|
108 | + } else if ( $input instanceof CharStream ) { |
|
110 | 109 | $this->c = $input->LA(1); |
111 | 110 | $this->line = $input->getLine(); |
112 | 111 | $this->charPositionInLine = $input->getCharPositionInLine(); |
113 | - } |
|
114 | - else { |
|
112 | + } else { |
|
115 | 113 | $this->c = $input->LA(1); |
116 | 114 | } |
117 | 115 | } |
@@ -139,20 +137,17 @@ discard block |
||
139 | 137 | --$i; |
140 | 138 | $priorNode = $nodes->LT($i); |
141 | 139 | } |
142 | - } |
|
143 | - else { // node created from real token |
|
140 | + } else { // node created from real token |
|
144 | 141 | $this->line = $payload->getLine(); |
145 | 142 | $this->charPositionInLine = $payload->getCharPositionInLine(); |
146 | 143 | } |
147 | - } |
|
148 | - else if ( $this->node instanceof Tree) { |
|
144 | + } else if ( $this->node instanceof Tree) { |
|
149 | 145 | $this->line = $this->node->getLine(); |
150 | 146 | $this->charPositionInLine = $this->node->getCharPositionInLine(); |
151 | 147 | if ( $this->node instanceof CommonTree) { |
152 | 148 | $this->token = $this->node->token; |
153 | 149 | } |
154 | - } |
|
155 | - else { |
|
150 | + } else { |
|
156 | 151 | $type = $adaptor->getType($this->node); |
157 | 152 | $text = $adaptor->getText($this->node); |
158 | 153 | $this->token = CommonToken::forTypeAndText($type, $text); |
@@ -163,13 +158,11 @@ discard block |
||
163 | 158 | public function getUnexpectedType() { |
164 | 159 | if ( $this->input instanceof TokenStream ) { |
165 | 160 | return $this->token->getType(); |
166 | - } |
|
167 | - else if ( $this->input instanceof TreeNodeStream ) { |
|
161 | + } else if ( $this->input instanceof TreeNodeStream ) { |
|
168 | 162 | $nodes = $this->input; |
169 | 163 | $adaptor = $nodes->getTreeAdaptor(); |
170 | 164 | return $adaptor->getType($this->node); |
171 | - } |
|
172 | - else { |
|
165 | + } else { |
|
173 | 166 | return $this->c; |
174 | 167 | } |
175 | 168 | } |
@@ -339,15 +339,15 @@ |
||
339 | 339 | } |
340 | 340 | if ($this->options['autooptimize']) { |
341 | 341 | switch($this->db->phptype) { |
342 | - case 'mysql': |
|
343 | - $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); |
|
344 | - break; |
|
345 | - case 'pgsql': |
|
346 | - $query = sprintf("VACUUM %s", $this->options['table']); |
|
347 | - break; |
|
348 | - default: |
|
349 | - $query = null; |
|
350 | - break; |
|
342 | + case 'mysql': |
|
343 | + $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); |
|
344 | + break; |
|
345 | + case 'pgsql': |
|
346 | + $query = sprintf("VACUUM %s", $this->options['table']); |
|
347 | + break; |
|
348 | + default: |
|
349 | + $query = null; |
|
350 | + break; |
|
351 | 351 | } |
352 | 352 | if (isset($query)) { |
353 | 353 | $result = $this->db->query($query); |
@@ -338,7 +338,7 @@ |
||
338 | 338 | return false; |
339 | 339 | } |
340 | 340 | if ($this->options['autooptimize']) { |
341 | - switch($this->db->phptype) { |
|
341 | + switch ($this->db->phptype) { |
|
342 | 342 | case 'mysql': |
343 | 343 | $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); |
344 | 344 | break; |
@@ -59,306 +59,306 @@ |
||
59 | 59 | */ |
60 | 60 | class HTTP_Session_Container_MDB2 extends HTTP_Session_Container |
61 | 61 | { |
62 | - /** |
|
63 | - * MDB2 connection object |
|
64 | - * |
|
65 | - * @var object MDB2 |
|
66 | - * @access private |
|
67 | - */ |
|
68 | - public $db = null; |
|
62 | + /** |
|
63 | + * MDB2 connection object |
|
64 | + * |
|
65 | + * @var object MDB2 |
|
66 | + * @access private |
|
67 | + */ |
|
68 | + public $db = null; |
|
69 | 69 | |
70 | - /** |
|
71 | - * Session data cache id |
|
72 | - * |
|
73 | - * @var mixed |
|
74 | - * @access private |
|
75 | - */ |
|
76 | - public $crc = false; |
|
70 | + /** |
|
71 | + * Session data cache id |
|
72 | + * |
|
73 | + * @var mixed |
|
74 | + * @access private |
|
75 | + */ |
|
76 | + public $crc = false; |
|
77 | 77 | |
78 | - /** |
|
79 | - * Constructor method |
|
80 | - * |
|
81 | - * $options is an array with the options.<br> |
|
82 | - * The options are: |
|
83 | - * <ul> |
|
84 | - * <li>'dsn' - The DSN string</li> |
|
85 | - * <li>'table' - Table with session data, default is 'sessiondata'</li> |
|
86 | - * <li>'autooptimize' - Boolean, 'true' to optimize |
|
87 | - * the table on garbage collection, default is 'false'.</li> |
|
88 | - * </ul> |
|
89 | - * |
|
90 | - * @param array $options Options |
|
91 | - * |
|
92 | - * @access public |
|
93 | - * @return void |
|
94 | - */ |
|
95 | - public function HTTP_Session_Container_MDB2($options) |
|
96 | - { |
|
97 | - $this->_setDefaults(); |
|
98 | - if (is_array($options)) { |
|
99 | - $this->_parseOptions($options); |
|
100 | - } else { |
|
101 | - $this->options['dsn'] = $options; |
|
102 | - } |
|
103 | - } |
|
78 | + /** |
|
79 | + * Constructor method |
|
80 | + * |
|
81 | + * $options is an array with the options.<br> |
|
82 | + * The options are: |
|
83 | + * <ul> |
|
84 | + * <li>'dsn' - The DSN string</li> |
|
85 | + * <li>'table' - Table with session data, default is 'sessiondata'</li> |
|
86 | + * <li>'autooptimize' - Boolean, 'true' to optimize |
|
87 | + * the table on garbage collection, default is 'false'.</li> |
|
88 | + * </ul> |
|
89 | + * |
|
90 | + * @param array $options Options |
|
91 | + * |
|
92 | + * @access public |
|
93 | + * @return void |
|
94 | + */ |
|
95 | + public function HTTP_Session_Container_MDB2($options) |
|
96 | + { |
|
97 | + $this->_setDefaults(); |
|
98 | + if (is_array($options)) { |
|
99 | + $this->_parseOptions($options); |
|
100 | + } else { |
|
101 | + $this->options['dsn'] = $options; |
|
102 | + } |
|
103 | + } |
|
104 | 104 | |
105 | - /** |
|
106 | - * Connect to database by using the given DSN string |
|
107 | - * |
|
108 | - * @param string $dsn DSN string |
|
109 | - * |
|
110 | - * @access private |
|
111 | - * @return mixed Object on error, otherwise bool |
|
112 | - */ |
|
113 | - public function _connect($dsn) |
|
114 | - { |
|
115 | - if (is_string($dsn) || is_array($dsn)) { |
|
116 | - $this->db = MDB2::connect($dsn); |
|
117 | - } else if (is_object($dsn) && is_a($dsn, 'MDB2_Driver_Common')) { |
|
118 | - $this->db = $dsn; |
|
119 | - } else if (is_object($dsn) && MDB2::isError($dsn)) { |
|
120 | - return $dsn; |
|
121 | - } else { |
|
122 | - return new PEAR_Error("The given dsn was not valid in file " . __FILE__ |
|
123 | - . " at line " . __LINE__, |
|
124 | - 41, |
|
125 | - PEAR_ERROR_RETURN, |
|
126 | - null, |
|
127 | - null |
|
128 | - ); |
|
105 | + /** |
|
106 | + * Connect to database by using the given DSN string |
|
107 | + * |
|
108 | + * @param string $dsn DSN string |
|
109 | + * |
|
110 | + * @access private |
|
111 | + * @return mixed Object on error, otherwise bool |
|
112 | + */ |
|
113 | + public function _connect($dsn) |
|
114 | + { |
|
115 | + if (is_string($dsn) || is_array($dsn)) { |
|
116 | + $this->db = MDB2::connect($dsn); |
|
117 | + } else if (is_object($dsn) && is_a($dsn, 'MDB2_Driver_Common')) { |
|
118 | + $this->db = $dsn; |
|
119 | + } else if (is_object($dsn) && MDB2::isError($dsn)) { |
|
120 | + return $dsn; |
|
121 | + } else { |
|
122 | + return new PEAR_Error("The given dsn was not valid in file " . __FILE__ |
|
123 | + . " at line " . __LINE__, |
|
124 | + 41, |
|
125 | + PEAR_ERROR_RETURN, |
|
126 | + null, |
|
127 | + null |
|
128 | + ); |
|
129 | 129 | |
130 | - } |
|
130 | + } |
|
131 | 131 | |
132 | - if (MDB2::isError($this->db)) { |
|
133 | - return new MDB2_Error($this->db->code, PEAR_ERROR_DIE); |
|
134 | - } |
|
132 | + if (MDB2::isError($this->db)) { |
|
133 | + return new MDB2_Error($this->db->code, PEAR_ERROR_DIE); |
|
134 | + } |
|
135 | 135 | |
136 | - return true; |
|
137 | - } |
|
136 | + return true; |
|
137 | + } |
|
138 | 138 | |
139 | - /** |
|
140 | - * Set some default options |
|
141 | - * |
|
142 | - * @access private |
|
143 | - * @return void |
|
144 | - */ |
|
145 | - public function _setDefaults() |
|
146 | - { |
|
147 | - $this->options['dsn'] = null; |
|
148 | - $this->options['table'] = 'sessiondata'; |
|
149 | - $this->options['autooptimize'] = false; |
|
150 | - } |
|
139 | + /** |
|
140 | + * Set some default options |
|
141 | + * |
|
142 | + * @access private |
|
143 | + * @return void |
|
144 | + */ |
|
145 | + public function _setDefaults() |
|
146 | + { |
|
147 | + $this->options['dsn'] = null; |
|
148 | + $this->options['table'] = 'sessiondata'; |
|
149 | + $this->options['autooptimize'] = false; |
|
150 | + } |
|
151 | 151 | |
152 | - /** |
|
153 | - * Establish connection to a database |
|
154 | - * |
|
155 | - * @param string $save_path Save path |
|
156 | - * @param string $session_name Session name |
|
157 | - * |
|
158 | - * @return bool |
|
159 | - */ |
|
160 | - public function open($save_path, $session_name) |
|
161 | - { |
|
162 | - if (MDB2::isError($this->_connect($this->options['dsn']))) { |
|
163 | - return false; |
|
164 | - } else { |
|
165 | - return true; |
|
166 | - } |
|
167 | - } |
|
152 | + /** |
|
153 | + * Establish connection to a database |
|
154 | + * |
|
155 | + * @param string $save_path Save path |
|
156 | + * @param string $session_name Session name |
|
157 | + * |
|
158 | + * @return bool |
|
159 | + */ |
|
160 | + public function open($save_path, $session_name) |
|
161 | + { |
|
162 | + if (MDB2::isError($this->_connect($this->options['dsn']))) { |
|
163 | + return false; |
|
164 | + } else { |
|
165 | + return true; |
|
166 | + } |
|
167 | + } |
|
168 | 168 | |
169 | - /** |
|
170 | - * Free resources |
|
171 | - * |
|
172 | - * @return bool |
|
173 | - */ |
|
174 | - public function close() |
|
175 | - { |
|
176 | - return true; |
|
177 | - } |
|
169 | + /** |
|
170 | + * Free resources |
|
171 | + * |
|
172 | + * @return bool |
|
173 | + */ |
|
174 | + public function close() |
|
175 | + { |
|
176 | + return true; |
|
177 | + } |
|
178 | 178 | |
179 | - /** |
|
180 | - * Read session data |
|
181 | - * |
|
182 | - * @param string $id Session id |
|
183 | - * |
|
184 | - * @return mixed |
|
185 | - */ |
|
186 | - public function read($id) |
|
187 | - { |
|
188 | - $query = sprintf("SELECT data FROM %s WHERE id = %s && expiry >= %d", |
|
189 | - $this->options['table'], |
|
190 | - $this->db->quote(md5($id), 'text'), |
|
191 | - time()); |
|
192 | - $result = $this->db->queryOne($query); |
|
193 | - if (MDB2::isError($result)) { |
|
194 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
195 | - return false; |
|
196 | - } |
|
197 | - $this->crc = strlen($result) . crc32($result); |
|
198 | - return $result; |
|
199 | - } |
|
179 | + /** |
|
180 | + * Read session data |
|
181 | + * |
|
182 | + * @param string $id Session id |
|
183 | + * |
|
184 | + * @return mixed |
|
185 | + */ |
|
186 | + public function read($id) |
|
187 | + { |
|
188 | + $query = sprintf("SELECT data FROM %s WHERE id = %s && expiry >= %d", |
|
189 | + $this->options['table'], |
|
190 | + $this->db->quote(md5($id), 'text'), |
|
191 | + time()); |
|
192 | + $result = $this->db->queryOne($query); |
|
193 | + if (MDB2::isError($result)) { |
|
194 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
195 | + return false; |
|
196 | + } |
|
197 | + $this->crc = strlen($result) . crc32($result); |
|
198 | + return $result; |
|
199 | + } |
|
200 | 200 | |
201 | - /** |
|
202 | - * Write session data |
|
203 | - * |
|
204 | - * @param string $id Session id |
|
205 | - * @param mixed $data Data |
|
206 | - * |
|
207 | - * @return bool |
|
208 | - */ |
|
209 | - public function write($id, $data) |
|
210 | - { |
|
211 | - if ((false !== $this->crc) && |
|
212 | - ($this->crc === strlen($data) . crc32($data))) { |
|
213 | - // $_SESSION hasn't been touched, no need to update the blob column |
|
214 | - $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s", |
|
215 | - $this->options['table'], |
|
216 | - time() + ini_get('session.gc_maxlifetime'), |
|
217 | - $this->db->quote(md5($id), 'text')); |
|
218 | - } else { |
|
219 | - // Check if table row already exists |
|
220 | - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", |
|
221 | - $this->options['table'], |
|
222 | - $this->db->quote(md5($id), 'text')); |
|
223 | - $result = $this->db->queryOne($query); |
|
224 | - if (MDB2::isError($result)) { |
|
225 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
226 | - return false; |
|
227 | - } |
|
228 | - if (0 == intval($result)) { |
|
229 | - // Insert new row into table |
|
230 | - $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)", |
|
231 | - $this->options['table'], |
|
232 | - $this->db->quote(md5($id), 'text'), |
|
233 | - time() + ini_get('session.gc_maxlifetime'), |
|
234 | - $this->db->quote($data, 'text')); |
|
235 | - } else { |
|
236 | - // Update existing row |
|
237 | - $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s", |
|
238 | - $this->options['table'], |
|
239 | - time() + ini_get('session.gc_maxlifetime'), |
|
240 | - $this->db->quote($data, 'text'), |
|
241 | - $this->db->quote(md5($id), 'text')); |
|
242 | - } |
|
243 | - } |
|
244 | - $result = $this->db->query($query); |
|
245 | - if (MDB2::isError($result)) { |
|
246 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
247 | - return false; |
|
248 | - } |
|
201 | + /** |
|
202 | + * Write session data |
|
203 | + * |
|
204 | + * @param string $id Session id |
|
205 | + * @param mixed $data Data |
|
206 | + * |
|
207 | + * @return bool |
|
208 | + */ |
|
209 | + public function write($id, $data) |
|
210 | + { |
|
211 | + if ((false !== $this->crc) && |
|
212 | + ($this->crc === strlen($data) . crc32($data))) { |
|
213 | + // $_SESSION hasn't been touched, no need to update the blob column |
|
214 | + $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s", |
|
215 | + $this->options['table'], |
|
216 | + time() + ini_get('session.gc_maxlifetime'), |
|
217 | + $this->db->quote(md5($id), 'text')); |
|
218 | + } else { |
|
219 | + // Check if table row already exists |
|
220 | + $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", |
|
221 | + $this->options['table'], |
|
222 | + $this->db->quote(md5($id), 'text')); |
|
223 | + $result = $this->db->queryOne($query); |
|
224 | + if (MDB2::isError($result)) { |
|
225 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
226 | + return false; |
|
227 | + } |
|
228 | + if (0 == intval($result)) { |
|
229 | + // Insert new row into table |
|
230 | + $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)", |
|
231 | + $this->options['table'], |
|
232 | + $this->db->quote(md5($id), 'text'), |
|
233 | + time() + ini_get('session.gc_maxlifetime'), |
|
234 | + $this->db->quote($data, 'text')); |
|
235 | + } else { |
|
236 | + // Update existing row |
|
237 | + $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s", |
|
238 | + $this->options['table'], |
|
239 | + time() + ini_get('session.gc_maxlifetime'), |
|
240 | + $this->db->quote($data, 'text'), |
|
241 | + $this->db->quote(md5($id), 'text')); |
|
242 | + } |
|
243 | + } |
|
244 | + $result = $this->db->query($query); |
|
245 | + if (MDB2::isError($result)) { |
|
246 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
247 | + return false; |
|
248 | + } |
|
249 | 249 | |
250 | - return true; |
|
251 | - } |
|
250 | + return true; |
|
251 | + } |
|
252 | 252 | |
253 | - /** |
|
254 | - * Destroy session data |
|
255 | - * |
|
256 | - * @param string $id Session id |
|
257 | - * |
|
258 | - * @return bool |
|
259 | - */ |
|
260 | - public function destroy($id) |
|
261 | - { |
|
262 | - $query = sprintf("DELETE FROM %s WHERE id = %s", |
|
263 | - $this->options['table'], |
|
264 | - $this->db->quote(md5($id), 'text')); |
|
265 | - $result = $this->db->query($query); |
|
266 | - if (MDB2::isError($result)) { |
|
267 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
268 | - return false; |
|
269 | - } |
|
253 | + /** |
|
254 | + * Destroy session data |
|
255 | + * |
|
256 | + * @param string $id Session id |
|
257 | + * |
|
258 | + * @return bool |
|
259 | + */ |
|
260 | + public function destroy($id) |
|
261 | + { |
|
262 | + $query = sprintf("DELETE FROM %s WHERE id = %s", |
|
263 | + $this->options['table'], |
|
264 | + $this->db->quote(md5($id), 'text')); |
|
265 | + $result = $this->db->query($query); |
|
266 | + if (MDB2::isError($result)) { |
|
267 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
268 | + return false; |
|
269 | + } |
|
270 | 270 | |
271 | - return true; |
|
272 | - } |
|
271 | + return true; |
|
272 | + } |
|
273 | 273 | |
274 | - /** |
|
275 | - * Replicate session data to table specified in option 'replicateBeforeDestroy' |
|
276 | - * |
|
277 | - * @param string $targetTable Table to replicate to |
|
278 | - * @param string $id Id of record to replicate |
|
279 | - * |
|
280 | - * @access private |
|
281 | - * @return bool |
|
282 | - */ |
|
283 | - public function replicate($targetTable, $id = null) |
|
284 | - { |
|
285 | - if (is_null($id)) { |
|
286 | - $id = HTTP_Session::id(); |
|
287 | - } |
|
274 | + /** |
|
275 | + * Replicate session data to table specified in option 'replicateBeforeDestroy' |
|
276 | + * |
|
277 | + * @param string $targetTable Table to replicate to |
|
278 | + * @param string $id Id of record to replicate |
|
279 | + * |
|
280 | + * @access private |
|
281 | + * @return bool |
|
282 | + */ |
|
283 | + public function replicate($targetTable, $id = null) |
|
284 | + { |
|
285 | + if (is_null($id)) { |
|
286 | + $id = HTTP_Session::id(); |
|
287 | + } |
|
288 | 288 | |
289 | - // Check if table row already exists |
|
290 | - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", |
|
291 | - $targetTable, |
|
292 | - $this->db->quote(md5($id), 'text')); |
|
293 | - $result = $this->db->queryOne($query); |
|
294 | - if (MDB2::isError($result)) { |
|
295 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
296 | - return false; |
|
297 | - } |
|
289 | + // Check if table row already exists |
|
290 | + $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", |
|
291 | + $targetTable, |
|
292 | + $this->db->quote(md5($id), 'text')); |
|
293 | + $result = $this->db->queryOne($query); |
|
294 | + if (MDB2::isError($result)) { |
|
295 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
296 | + return false; |
|
297 | + } |
|
298 | 298 | |
299 | - // Insert new row into dest table |
|
300 | - if (0 == intval($result)) { |
|
301 | - $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s", |
|
302 | - $targetTable, |
|
303 | - $this->options['table'], |
|
304 | - $this->db->quote(md5($id), 'text')); |
|
299 | + // Insert new row into dest table |
|
300 | + if (0 == intval($result)) { |
|
301 | + $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s", |
|
302 | + $targetTable, |
|
303 | + $this->options['table'], |
|
304 | + $this->db->quote(md5($id), 'text')); |
|
305 | 305 | |
306 | - } else { |
|
307 | - // Update existing row |
|
308 | - $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id && src.id = %s", |
|
309 | - $targetTable, |
|
310 | - $this->options['table'], |
|
311 | - $this->db->quote(md5($id), 'text')); |
|
312 | - } |
|
306 | + } else { |
|
307 | + // Update existing row |
|
308 | + $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id && src.id = %s", |
|
309 | + $targetTable, |
|
310 | + $this->options['table'], |
|
311 | + $this->db->quote(md5($id), 'text')); |
|
312 | + } |
|
313 | 313 | |
314 | - $result = $this->db->query($query); |
|
315 | - if (MDB2::isError($result)) { |
|
316 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
317 | - return false; |
|
318 | - } |
|
314 | + $result = $this->db->query($query); |
|
315 | + if (MDB2::isError($result)) { |
|
316 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
317 | + return false; |
|
318 | + } |
|
319 | 319 | |
320 | - return true; |
|
321 | - } |
|
320 | + return true; |
|
321 | + } |
|
322 | 322 | |
323 | - /** |
|
324 | - * Garbage collection |
|
325 | - * |
|
326 | - * @param int $maxlifetime Maximum lifetime |
|
327 | - * |
|
328 | - * @return bool |
|
329 | - */ |
|
330 | - public function gc($maxlifetime) |
|
331 | - { |
|
332 | - $query = sprintf("DELETE FROM %s WHERE expiry < %d", |
|
333 | - $this->options['table'], |
|
334 | - time()); |
|
335 | - $result = $this->db->query($query); |
|
336 | - if (MDB2::isError($result)) { |
|
337 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
338 | - return false; |
|
339 | - } |
|
340 | - if ($this->options['autooptimize']) { |
|
341 | - switch($this->db->phptype) { |
|
342 | - case 'mysql': |
|
343 | - $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); |
|
344 | - break; |
|
345 | - case 'pgsql': |
|
346 | - $query = sprintf("VACUUM %s", $this->options['table']); |
|
347 | - break; |
|
348 | - default: |
|
349 | - $query = null; |
|
350 | - break; |
|
351 | - } |
|
352 | - if (isset($query)) { |
|
353 | - $result = $this->db->query($query); |
|
354 | - if (MDB2::isError($result)) { |
|
355 | - $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
356 | - return false; |
|
357 | - } |
|
358 | - } |
|
359 | - } |
|
323 | + /** |
|
324 | + * Garbage collection |
|
325 | + * |
|
326 | + * @param int $maxlifetime Maximum lifetime |
|
327 | + * |
|
328 | + * @return bool |
|
329 | + */ |
|
330 | + public function gc($maxlifetime) |
|
331 | + { |
|
332 | + $query = sprintf("DELETE FROM %s WHERE expiry < %d", |
|
333 | + $this->options['table'], |
|
334 | + time()); |
|
335 | + $result = $this->db->query($query); |
|
336 | + if (MDB2::isError($result)) { |
|
337 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
338 | + return false; |
|
339 | + } |
|
340 | + if ($this->options['autooptimize']) { |
|
341 | + switch($this->db->phptype) { |
|
342 | + case 'mysql': |
|
343 | + $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); |
|
344 | + break; |
|
345 | + case 'pgsql': |
|
346 | + $query = sprintf("VACUUM %s", $this->options['table']); |
|
347 | + break; |
|
348 | + default: |
|
349 | + $query = null; |
|
350 | + break; |
|
351 | + } |
|
352 | + if (isset($query)) { |
|
353 | + $result = $this->db->query($query); |
|
354 | + if (MDB2::isError($result)) { |
|
355 | + $this->db->raiseError($result->code, PEAR_ERROR_DIE); |
|
356 | + return false; |
|
357 | + } |
|
358 | + } |
|
359 | + } |
|
360 | 360 | |
361 | - return true; |
|
362 | - } |
|
361 | + return true; |
|
362 | + } |
|
363 | 363 | } |
364 | 364 | ?> |
365 | 365 | \ No newline at end of file |
@@ -11,9 +11,9 @@ |
||
11 | 11 | */ |
12 | 12 | class Version { |
13 | 13 | |
14 | - /** |
|
15 | - * Full version number |
|
16 | - */ |
|
17 | - const VERSION = '3.1.3'; |
|
14 | + /** |
|
15 | + * Full version number |
|
16 | + */ |
|
17 | + const VERSION = '3.1.3'; |
|
18 | 18 | |
19 | 19 | } |
@@ -284,7 +284,9 @@ |
||
284 | 284 | } |
285 | 285 | } |
286 | 286 | // Removing the 404's for multi-status requests. |
287 | - if ($this->requestType === self::ALLPROPS) unset($r[404]); |
|
287 | + if ($this->requestType === self::ALLPROPS) { |
|
288 | + unset($r[404]); |
|
289 | + } |
|
288 | 290 | return $r; |
289 | 291 | |
290 | 292 | } |
@@ -10,338 +10,338 @@ |
||
10 | 10 | */ |
11 | 11 | class PropFind { |
12 | 12 | |
13 | - /** |
|
14 | - * A normal propfind |
|
15 | - */ |
|
16 | - const NORMAL = 0; |
|
17 | - |
|
18 | - /** |
|
19 | - * An allprops request. |
|
20 | - * |
|
21 | - * While this was originally intended for instructing the server to really |
|
22 | - * fetch every property, because it was used so often and it's so heavy |
|
23 | - * this turned into a small list of default properties after a while. |
|
24 | - * |
|
25 | - * So 'all properties' now means a hardcoded list. |
|
26 | - */ |
|
27 | - const ALLPROPS = 1; |
|
28 | - |
|
29 | - /** |
|
30 | - * A propname request. This just returns a list of properties that are |
|
31 | - * defined on a node, without their values. |
|
32 | - */ |
|
33 | - const PROPNAME = 2; |
|
34 | - |
|
35 | - /** |
|
36 | - * Creates the PROPFIND object |
|
37 | - * |
|
38 | - * @param string $path |
|
39 | - * @param array $properties |
|
40 | - * @param int $depth |
|
41 | - * @param int $requestType |
|
42 | - */ |
|
43 | - public function __construct($path, array $properties, $depth = 0, $requestType = self::NORMAL) { |
|
44 | - |
|
45 | - $this->path = $path; |
|
46 | - $this->properties = $properties; |
|
47 | - $this->depth = $depth; |
|
48 | - $this->requestType = $requestType; |
|
49 | - |
|
50 | - if ($requestType === self::ALLPROPS) { |
|
51 | - $this->properties = [ |
|
52 | - '{DAV:}getlastmodified', |
|
53 | - '{DAV:}getcontentlength', |
|
54 | - '{DAV:}resourcetype', |
|
55 | - '{DAV:}quota-used-bytes', |
|
56 | - '{DAV:}quota-available-bytes', |
|
57 | - '{DAV:}getetag', |
|
58 | - '{DAV:}getcontenttype', |
|
59 | - ]; |
|
60 | - } |
|
61 | - |
|
62 | - foreach ($this->properties as $propertyName) { |
|
63 | - |
|
64 | - // Seeding properties with 404's. |
|
65 | - $this->result[$propertyName] = [404, null]; |
|
66 | - |
|
67 | - } |
|
68 | - $this->itemsLeft = count($this->result); |
|
69 | - |
|
70 | - } |
|
71 | - |
|
72 | - /** |
|
73 | - * Handles a specific property. |
|
74 | - * |
|
75 | - * This method checks wether the specified property was requested in this |
|
76 | - * PROPFIND request, and if so, it will call the callback and use the |
|
77 | - * return value for it's value. |
|
78 | - * |
|
79 | - * Example: |
|
80 | - * |
|
81 | - * $propFind->handle('{DAV:}displayname', function() { |
|
82 | - * return 'hello'; |
|
83 | - * }); |
|
84 | - * |
|
85 | - * Note that handle will only work the first time. If null is returned, the |
|
86 | - * value is ignored. |
|
87 | - * |
|
88 | - * It's also possible to not pass a callback, but immediately pass a value |
|
89 | - * |
|
90 | - * @param string $propertyName |
|
91 | - * @param mixed $valueOrCallBack |
|
92 | - * @return void |
|
93 | - */ |
|
94 | - public function handle($propertyName, $valueOrCallBack) { |
|
95 | - |
|
96 | - if ($this->itemsLeft && isset($this->result[$propertyName]) && $this->result[$propertyName][0] === 404) { |
|
97 | - if (is_callable($valueOrCallBack)) { |
|
98 | - $value = $valueOrCallBack(); |
|
99 | - } else { |
|
100 | - $value = $valueOrCallBack; |
|
101 | - } |
|
102 | - if (!is_null($value)) { |
|
103 | - $this->itemsLeft--; |
|
104 | - $this->result[$propertyName] = [200, $value]; |
|
105 | - } |
|
106 | - } |
|
107 | - |
|
108 | - } |
|
109 | - |
|
110 | - /** |
|
111 | - * Sets the value of the property |
|
112 | - * |
|
113 | - * If status is not supplied, the status will default to 200 for non-null |
|
114 | - * properties, and 404 for null properties. |
|
115 | - * |
|
116 | - * @param string $propertyName |
|
117 | - * @param mixed $value |
|
118 | - * @param int $status |
|
119 | - * @return void |
|
120 | - */ |
|
121 | - public function set($propertyName, $value, $status = null) { |
|
122 | - |
|
123 | - if (is_null($status)) { |
|
124 | - $status = is_null($value) ? 404 : 200; |
|
125 | - } |
|
126 | - // If this is an ALLPROPS request and the property is |
|
127 | - // unknown, add it to the result; else ignore it: |
|
128 | - if (!isset($this->result[$propertyName])) { |
|
129 | - if ($this->requestType === self::ALLPROPS) { |
|
130 | - $this->result[$propertyName] = [$status, $value]; |
|
131 | - } |
|
132 | - return; |
|
133 | - } |
|
134 | - if ($status !== 404 && $this->result[$propertyName][0] === 404) { |
|
135 | - $this->itemsLeft--; |
|
136 | - } elseif ($status === 404 && $this->result[$propertyName][0] !== 404) { |
|
137 | - $this->itemsLeft++; |
|
138 | - } |
|
139 | - $this->result[$propertyName] = [$status, $value]; |
|
140 | - |
|
141 | - } |
|
142 | - |
|
143 | - /** |
|
144 | - * Returns the current value for a property. |
|
145 | - * |
|
146 | - * @param string $propertyName |
|
147 | - * @return mixed |
|
148 | - */ |
|
149 | - public function get($propertyName) { |
|
150 | - |
|
151 | - return isset($this->result[$propertyName]) ? $this->result[$propertyName][1] : null; |
|
152 | - |
|
153 | - } |
|
154 | - |
|
155 | - /** |
|
156 | - * Returns the current status code for a property name. |
|
157 | - * |
|
158 | - * If the property does not appear in the list of requested properties, |
|
159 | - * null will be returned. |
|
160 | - * |
|
161 | - * @param string $propertyName |
|
162 | - * @return int|null |
|
163 | - */ |
|
164 | - public function getStatus($propertyName) { |
|
165 | - |
|
166 | - return isset($this->result[$propertyName]) ? $this->result[$propertyName][0] : null; |
|
167 | - |
|
168 | - } |
|
169 | - |
|
170 | - /** |
|
171 | - * Updates the path for this PROPFIND. |
|
172 | - * |
|
173 | - * @param string $path |
|
174 | - * @return void |
|
175 | - */ |
|
176 | - public function setPath($path) { |
|
177 | - |
|
178 | - $this->path = $path; |
|
179 | - |
|
180 | - } |
|
181 | - |
|
182 | - /** |
|
183 | - * Returns the path this PROPFIND request is for. |
|
184 | - * |
|
185 | - * @return string |
|
186 | - */ |
|
187 | - public function getPath() { |
|
188 | - |
|
189 | - return $this->path; |
|
190 | - |
|
191 | - } |
|
192 | - |
|
193 | - /** |
|
194 | - * Returns the depth of this propfind request. |
|
195 | - * |
|
196 | - * @return int |
|
197 | - */ |
|
198 | - public function getDepth() { |
|
199 | - |
|
200 | - return $this->depth; |
|
201 | - |
|
202 | - } |
|
203 | - |
|
204 | - /** |
|
205 | - * Updates the depth of this propfind request. |
|
206 | - * |
|
207 | - * @param int $depth |
|
208 | - * @return void |
|
209 | - */ |
|
210 | - public function setDepth($depth) { |
|
211 | - |
|
212 | - $this->depth = $depth; |
|
213 | - |
|
214 | - } |
|
215 | - |
|
216 | - /** |
|
217 | - * Returns all propertynames that have a 404 status, and thus don't have a |
|
218 | - * value yet. |
|
219 | - * |
|
220 | - * @return array |
|
221 | - */ |
|
222 | - public function get404Properties() { |
|
223 | - |
|
224 | - if ($this->itemsLeft === 0) { |
|
225 | - return []; |
|
226 | - } |
|
227 | - $result = []; |
|
228 | - foreach ($this->result as $propertyName => $stuff) { |
|
229 | - if ($stuff[0] === 404) { |
|
230 | - $result[] = $propertyName; |
|
231 | - } |
|
232 | - } |
|
233 | - return $result; |
|
234 | - |
|
235 | - } |
|
236 | - |
|
237 | - /** |
|
238 | - * Returns the full list of requested properties. |
|
239 | - * |
|
240 | - * This returns just their names, not a status or value. |
|
241 | - * |
|
242 | - * @return array |
|
243 | - */ |
|
244 | - public function getRequestedProperties() { |
|
245 | - |
|
246 | - return $this->properties; |
|
247 | - |
|
248 | - } |
|
249 | - |
|
250 | - /** |
|
251 | - * Returns true if this was an '{DAV:}allprops' request. |
|
252 | - * |
|
253 | - * @return bool |
|
254 | - */ |
|
255 | - public function isAllProps() { |
|
256 | - |
|
257 | - return $this->requestType === self::ALLPROPS; |
|
258 | - |
|
259 | - } |
|
260 | - |
|
261 | - /** |
|
262 | - * Returns a result array that's often used in multistatus responses. |
|
263 | - * |
|
264 | - * The array uses status codes as keys, and property names and value pairs |
|
265 | - * as the value of the top array.. such as : |
|
266 | - * |
|
267 | - * [ |
|
268 | - * 200 => [ '{DAV:}displayname' => 'foo' ], |
|
269 | - * ] |
|
270 | - * |
|
271 | - * @return array |
|
272 | - */ |
|
273 | - public function getResultForMultiStatus() { |
|
274 | - |
|
275 | - $r = [ |
|
276 | - 200 => [], |
|
277 | - 404 => [], |
|
278 | - ]; |
|
279 | - foreach ($this->result as $propertyName => $info) { |
|
280 | - if (!isset($r[$info[0]])) { |
|
281 | - $r[$info[0]] = [$propertyName => $info[1]]; |
|
282 | - } else { |
|
283 | - $r[$info[0]][$propertyName] = $info[1]; |
|
284 | - } |
|
285 | - } |
|
286 | - // Removing the 404's for multi-status requests. |
|
287 | - if ($this->requestType === self::ALLPROPS) unset($r[404]); |
|
288 | - return $r; |
|
289 | - |
|
290 | - } |
|
291 | - |
|
292 | - /** |
|
293 | - * The path that we're fetching properties for. |
|
294 | - * |
|
295 | - * @var string |
|
296 | - */ |
|
297 | - protected $path; |
|
298 | - |
|
299 | - /** |
|
300 | - * The Depth of the request. |
|
301 | - * |
|
302 | - * 0 means only the current item. 1 means the current item + its children. |
|
303 | - * It can also be DEPTH_INFINITY if this is enabled in the server. |
|
304 | - * |
|
305 | - * @var int |
|
306 | - */ |
|
307 | - protected $depth = 0; |
|
308 | - |
|
309 | - /** |
|
310 | - * The type of request. See the TYPE constants |
|
311 | - */ |
|
312 | - protected $requestType; |
|
313 | - |
|
314 | - /** |
|
315 | - * A list of requested properties |
|
316 | - * |
|
317 | - * @var array |
|
318 | - */ |
|
319 | - protected $properties = []; |
|
320 | - |
|
321 | - /** |
|
322 | - * The result of the operation. |
|
323 | - * |
|
324 | - * The keys in this array are property names. |
|
325 | - * The values are an array with two elements: the http status code and then |
|
326 | - * optionally a value. |
|
327 | - * |
|
328 | - * Example: |
|
329 | - * |
|
330 | - * [ |
|
331 | - * "{DAV:}owner" : [404], |
|
332 | - * "{DAV:}displayname" : [200, "Admin"] |
|
333 | - * ] |
|
334 | - * |
|
335 | - * @var array |
|
336 | - */ |
|
337 | - protected $result = []; |
|
338 | - |
|
339 | - /** |
|
340 | - * This is used as an internal counter for the number of properties that do |
|
341 | - * not yet have a value. |
|
342 | - * |
|
343 | - * @var int |
|
344 | - */ |
|
345 | - protected $itemsLeft; |
|
13 | + /** |
|
14 | + * A normal propfind |
|
15 | + */ |
|
16 | + const NORMAL = 0; |
|
17 | + |
|
18 | + /** |
|
19 | + * An allprops request. |
|
20 | + * |
|
21 | + * While this was originally intended for instructing the server to really |
|
22 | + * fetch every property, because it was used so often and it's so heavy |
|
23 | + * this turned into a small list of default properties after a while. |
|
24 | + * |
|
25 | + * So 'all properties' now means a hardcoded list. |
|
26 | + */ |
|
27 | + const ALLPROPS = 1; |
|
28 | + |
|
29 | + /** |
|
30 | + * A propname request. This just returns a list of properties that are |
|
31 | + * defined on a node, without their values. |
|
32 | + */ |
|
33 | + const PROPNAME = 2; |
|
34 | + |
|
35 | + /** |
|
36 | + * Creates the PROPFIND object |
|
37 | + * |
|
38 | + * @param string $path |
|
39 | + * @param array $properties |
|
40 | + * @param int $depth |
|
41 | + * @param int $requestType |
|
42 | + */ |
|
43 | + public function __construct($path, array $properties, $depth = 0, $requestType = self::NORMAL) { |
|
44 | + |
|
45 | + $this->path = $path; |
|
46 | + $this->properties = $properties; |
|
47 | + $this->depth = $depth; |
|
48 | + $this->requestType = $requestType; |
|
49 | + |
|
50 | + if ($requestType === self::ALLPROPS) { |
|
51 | + $this->properties = [ |
|
52 | + '{DAV:}getlastmodified', |
|
53 | + '{DAV:}getcontentlength', |
|
54 | + '{DAV:}resourcetype', |
|
55 | + '{DAV:}quota-used-bytes', |
|
56 | + '{DAV:}quota-available-bytes', |
|
57 | + '{DAV:}getetag', |
|
58 | + '{DAV:}getcontenttype', |
|
59 | + ]; |
|
60 | + } |
|
61 | + |
|
62 | + foreach ($this->properties as $propertyName) { |
|
63 | + |
|
64 | + // Seeding properties with 404's. |
|
65 | + $this->result[$propertyName] = [404, null]; |
|
66 | + |
|
67 | + } |
|
68 | + $this->itemsLeft = count($this->result); |
|
69 | + |
|
70 | + } |
|
71 | + |
|
72 | + /** |
|
73 | + * Handles a specific property. |
|
74 | + * |
|
75 | + * This method checks wether the specified property was requested in this |
|
76 | + * PROPFIND request, and if so, it will call the callback and use the |
|
77 | + * return value for it's value. |
|
78 | + * |
|
79 | + * Example: |
|
80 | + * |
|
81 | + * $propFind->handle('{DAV:}displayname', function() { |
|
82 | + * return 'hello'; |
|
83 | + * }); |
|
84 | + * |
|
85 | + * Note that handle will only work the first time. If null is returned, the |
|
86 | + * value is ignored. |
|
87 | + * |
|
88 | + * It's also possible to not pass a callback, but immediately pass a value |
|
89 | + * |
|
90 | + * @param string $propertyName |
|
91 | + * @param mixed $valueOrCallBack |
|
92 | + * @return void |
|
93 | + */ |
|
94 | + public function handle($propertyName, $valueOrCallBack) { |
|
95 | + |
|
96 | + if ($this->itemsLeft && isset($this->result[$propertyName]) && $this->result[$propertyName][0] === 404) { |
|
97 | + if (is_callable($valueOrCallBack)) { |
|
98 | + $value = $valueOrCallBack(); |
|
99 | + } else { |
|
100 | + $value = $valueOrCallBack; |
|
101 | + } |
|
102 | + if (!is_null($value)) { |
|
103 | + $this->itemsLeft--; |
|
104 | + $this->result[$propertyName] = [200, $value]; |
|
105 | + } |
|
106 | + } |
|
107 | + |
|
108 | + } |
|
109 | + |
|
110 | + /** |
|
111 | + * Sets the value of the property |
|
112 | + * |
|
113 | + * If status is not supplied, the status will default to 200 for non-null |
|
114 | + * properties, and 404 for null properties. |
|
115 | + * |
|
116 | + * @param string $propertyName |
|
117 | + * @param mixed $value |
|
118 | + * @param int $status |
|
119 | + * @return void |
|
120 | + */ |
|
121 | + public function set($propertyName, $value, $status = null) { |
|
122 | + |
|
123 | + if (is_null($status)) { |
|
124 | + $status = is_null($value) ? 404 : 200; |
|
125 | + } |
|
126 | + // If this is an ALLPROPS request and the property is |
|
127 | + // unknown, add it to the result; else ignore it: |
|
128 | + if (!isset($this->result[$propertyName])) { |
|
129 | + if ($this->requestType === self::ALLPROPS) { |
|
130 | + $this->result[$propertyName] = [$status, $value]; |
|
131 | + } |
|
132 | + return; |
|
133 | + } |
|
134 | + if ($status !== 404 && $this->result[$propertyName][0] === 404) { |
|
135 | + $this->itemsLeft--; |
|
136 | + } elseif ($status === 404 && $this->result[$propertyName][0] !== 404) { |
|
137 | + $this->itemsLeft++; |
|
138 | + } |
|
139 | + $this->result[$propertyName] = [$status, $value]; |
|
140 | + |
|
141 | + } |
|
142 | + |
|
143 | + /** |
|
144 | + * Returns the current value for a property. |
|
145 | + * |
|
146 | + * @param string $propertyName |
|
147 | + * @return mixed |
|
148 | + */ |
|
149 | + public function get($propertyName) { |
|
150 | + |
|
151 | + return isset($this->result[$propertyName]) ? $this->result[$propertyName][1] : null; |
|
152 | + |
|
153 | + } |
|
154 | + |
|
155 | + /** |
|
156 | + * Returns the current status code for a property name. |
|
157 | + * |
|
158 | + * If the property does not appear in the list of requested properties, |
|
159 | + * null will be returned. |
|
160 | + * |
|
161 | + * @param string $propertyName |
|
162 | + * @return int|null |
|
163 | + */ |
|
164 | + public function getStatus($propertyName) { |
|
165 | + |
|
166 | + return isset($this->result[$propertyName]) ? $this->result[$propertyName][0] : null; |
|
167 | + |
|
168 | + } |
|
169 | + |
|
170 | + /** |
|
171 | + * Updates the path for this PROPFIND. |
|
172 | + * |
|
173 | + * @param string $path |
|
174 | + * @return void |
|
175 | + */ |
|
176 | + public function setPath($path) { |
|
177 | + |
|
178 | + $this->path = $path; |
|
179 | + |
|
180 | + } |
|
181 | + |
|
182 | + /** |
|
183 | + * Returns the path this PROPFIND request is for. |
|
184 | + * |
|
185 | + * @return string |
|
186 | + */ |
|
187 | + public function getPath() { |
|
188 | + |
|
189 | + return $this->path; |
|
190 | + |
|
191 | + } |
|
192 | + |
|
193 | + /** |
|
194 | + * Returns the depth of this propfind request. |
|
195 | + * |
|
196 | + * @return int |
|
197 | + */ |
|
198 | + public function getDepth() { |
|
199 | + |
|
200 | + return $this->depth; |
|
201 | + |
|
202 | + } |
|
203 | + |
|
204 | + /** |
|
205 | + * Updates the depth of this propfind request. |
|
206 | + * |
|
207 | + * @param int $depth |
|
208 | + * @return void |
|
209 | + */ |
|
210 | + public function setDepth($depth) { |
|
211 | + |
|
212 | + $this->depth = $depth; |
|
213 | + |
|
214 | + } |
|
215 | + |
|
216 | + /** |
|
217 | + * Returns all propertynames that have a 404 status, and thus don't have a |
|
218 | + * value yet. |
|
219 | + * |
|
220 | + * @return array |
|
221 | + */ |
|
222 | + public function get404Properties() { |
|
223 | + |
|
224 | + if ($this->itemsLeft === 0) { |
|
225 | + return []; |
|
226 | + } |
|
227 | + $result = []; |
|
228 | + foreach ($this->result as $propertyName => $stuff) { |
|
229 | + if ($stuff[0] === 404) { |
|
230 | + $result[] = $propertyName; |
|
231 | + } |
|
232 | + } |
|
233 | + return $result; |
|
234 | + |
|
235 | + } |
|
236 | + |
|
237 | + /** |
|
238 | + * Returns the full list of requested properties. |
|
239 | + * |
|
240 | + * This returns just their names, not a status or value. |
|
241 | + * |
|
242 | + * @return array |
|
243 | + */ |
|
244 | + public function getRequestedProperties() { |
|
245 | + |
|
246 | + return $this->properties; |
|
247 | + |
|
248 | + } |
|
249 | + |
|
250 | + /** |
|
251 | + * Returns true if this was an '{DAV:}allprops' request. |
|
252 | + * |
|
253 | + * @return bool |
|
254 | + */ |
|
255 | + public function isAllProps() { |
|
256 | + |
|
257 | + return $this->requestType === self::ALLPROPS; |
|
258 | + |
|
259 | + } |
|
260 | + |
|
261 | + /** |
|
262 | + * Returns a result array that's often used in multistatus responses. |
|
263 | + * |
|
264 | + * The array uses status codes as keys, and property names and value pairs |
|
265 | + * as the value of the top array.. such as : |
|
266 | + * |
|
267 | + * [ |
|
268 | + * 200 => [ '{DAV:}displayname' => 'foo' ], |
|
269 | + * ] |
|
270 | + * |
|
271 | + * @return array |
|
272 | + */ |
|
273 | + public function getResultForMultiStatus() { |
|
274 | + |
|
275 | + $r = [ |
|
276 | + 200 => [], |
|
277 | + 404 => [], |
|
278 | + ]; |
|
279 | + foreach ($this->result as $propertyName => $info) { |
|
280 | + if (!isset($r[$info[0]])) { |
|
281 | + $r[$info[0]] = [$propertyName => $info[1]]; |
|
282 | + } else { |
|
283 | + $r[$info[0]][$propertyName] = $info[1]; |
|
284 | + } |
|
285 | + } |
|
286 | + // Removing the 404's for multi-status requests. |
|
287 | + if ($this->requestType === self::ALLPROPS) unset($r[404]); |
|
288 | + return $r; |
|
289 | + |
|
290 | + } |
|
291 | + |
|
292 | + /** |
|
293 | + * The path that we're fetching properties for. |
|
294 | + * |
|
295 | + * @var string |
|
296 | + */ |
|
297 | + protected $path; |
|
298 | + |
|
299 | + /** |
|
300 | + * The Depth of the request. |
|
301 | + * |
|
302 | + * 0 means only the current item. 1 means the current item + its children. |
|
303 | + * It can also be DEPTH_INFINITY if this is enabled in the server. |
|
304 | + * |
|
305 | + * @var int |
|
306 | + */ |
|
307 | + protected $depth = 0; |
|
308 | + |
|
309 | + /** |
|
310 | + * The type of request. See the TYPE constants |
|
311 | + */ |
|
312 | + protected $requestType; |
|
313 | + |
|
314 | + /** |
|
315 | + * A list of requested properties |
|
316 | + * |
|
317 | + * @var array |
|
318 | + */ |
|
319 | + protected $properties = []; |
|
320 | + |
|
321 | + /** |
|
322 | + * The result of the operation. |
|
323 | + * |
|
324 | + * The keys in this array are property names. |
|
325 | + * The values are an array with two elements: the http status code and then |
|
326 | + * optionally a value. |
|
327 | + * |
|
328 | + * Example: |
|
329 | + * |
|
330 | + * [ |
|
331 | + * "{DAV:}owner" : [404], |
|
332 | + * "{DAV:}displayname" : [200, "Admin"] |
|
333 | + * ] |
|
334 | + * |
|
335 | + * @var array |
|
336 | + */ |
|
337 | + protected $result = []; |
|
338 | + |
|
339 | + /** |
|
340 | + * This is used as an internal counter for the number of properties that do |
|
341 | + * not yet have a value. |
|
342 | + * |
|
343 | + * @var int |
|
344 | + */ |
|
345 | + protected $itemsLeft; |
|
346 | 346 | |
347 | 347 | } |
@@ -15,77 +15,77 @@ |
||
15 | 15 | */ |
16 | 16 | class StringUtil { |
17 | 17 | |
18 | - /** |
|
19 | - * Checks if a needle occurs in a haystack ;) |
|
20 | - * |
|
21 | - * @param string $haystack |
|
22 | - * @param string $needle |
|
23 | - * @param string $collation |
|
24 | - * @param string $matchType |
|
25 | - * @return bool |
|
26 | - */ |
|
27 | - static function textMatch($haystack, $needle, $collation, $matchType = 'contains') { |
|
28 | - |
|
29 | - switch ($collation) { |
|
30 | - |
|
31 | - case 'i;ascii-casemap' : |
|
32 | - // default strtolower takes locale into consideration |
|
33 | - // we don't want this. |
|
34 | - $haystack = str_replace(range('a', 'z'), range('A', 'Z'), $haystack); |
|
35 | - $needle = str_replace(range('a', 'z'), range('A', 'Z'), $needle); |
|
36 | - break; |
|
37 | - |
|
38 | - case 'i;octet' : |
|
39 | - // Do nothing |
|
40 | - break; |
|
41 | - |
|
42 | - case 'i;unicode-casemap' : |
|
43 | - $haystack = mb_strtoupper($haystack, 'UTF-8'); |
|
44 | - $needle = mb_strtoupper($needle, 'UTF-8'); |
|
45 | - break; |
|
46 | - |
|
47 | - default : |
|
48 | - throw new Exception\BadRequest('Collation type: ' . $collation . ' is not supported'); |
|
49 | - |
|
50 | - } |
|
51 | - |
|
52 | - switch ($matchType) { |
|
53 | - |
|
54 | - case 'contains' : |
|
55 | - return strpos($haystack, $needle) !== false; |
|
56 | - case 'equals' : |
|
57 | - return $haystack === $needle; |
|
58 | - case 'starts-with' : |
|
59 | - return strpos($haystack, $needle) === 0; |
|
60 | - case 'ends-with' : |
|
61 | - return strrpos($haystack, $needle) === strlen($haystack) - strlen($needle); |
|
62 | - default : |
|
63 | - throw new Exception\BadRequest('Match-type: ' . $matchType . ' is not supported'); |
|
64 | - |
|
65 | - } |
|
66 | - |
|
67 | - } |
|
68 | - |
|
69 | - /** |
|
70 | - * This method takes an input string, checks if it's not valid UTF-8 and |
|
71 | - * attempts to convert it to UTF-8 if it's not. |
|
72 | - * |
|
73 | - * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1), |
|
74 | - * anything else will likely fail. |
|
75 | - * |
|
76 | - * @param string $input |
|
77 | - * @return string |
|
78 | - */ |
|
79 | - static function ensureUTF8($input) { |
|
80 | - |
|
81 | - $encoding = mb_detect_encoding($input, ['UTF-8', 'ISO-8859-1'], true); |
|
82 | - |
|
83 | - if ($encoding === 'ISO-8859-1') { |
|
84 | - return utf8_encode($input); |
|
85 | - } else { |
|
86 | - return $input; |
|
87 | - } |
|
88 | - |
|
89 | - } |
|
18 | + /** |
|
19 | + * Checks if a needle occurs in a haystack ;) |
|
20 | + * |
|
21 | + * @param string $haystack |
|
22 | + * @param string $needle |
|
23 | + * @param string $collation |
|
24 | + * @param string $matchType |
|
25 | + * @return bool |
|
26 | + */ |
|
27 | + static function textMatch($haystack, $needle, $collation, $matchType = 'contains') { |
|
28 | + |
|
29 | + switch ($collation) { |
|
30 | + |
|
31 | + case 'i;ascii-casemap' : |
|
32 | + // default strtolower takes locale into consideration |
|
33 | + // we don't want this. |
|
34 | + $haystack = str_replace(range('a', 'z'), range('A', 'Z'), $haystack); |
|
35 | + $needle = str_replace(range('a', 'z'), range('A', 'Z'), $needle); |
|
36 | + break; |
|
37 | + |
|
38 | + case 'i;octet' : |
|
39 | + // Do nothing |
|
40 | + break; |
|
41 | + |
|
42 | + case 'i;unicode-casemap' : |
|
43 | + $haystack = mb_strtoupper($haystack, 'UTF-8'); |
|
44 | + $needle = mb_strtoupper($needle, 'UTF-8'); |
|
45 | + break; |
|
46 | + |
|
47 | + default : |
|
48 | + throw new Exception\BadRequest('Collation type: ' . $collation . ' is not supported'); |
|
49 | + |
|
50 | + } |
|
51 | + |
|
52 | + switch ($matchType) { |
|
53 | + |
|
54 | + case 'contains' : |
|
55 | + return strpos($haystack, $needle) !== false; |
|
56 | + case 'equals' : |
|
57 | + return $haystack === $needle; |
|
58 | + case 'starts-with' : |
|
59 | + return strpos($haystack, $needle) === 0; |
|
60 | + case 'ends-with' : |
|
61 | + return strrpos($haystack, $needle) === strlen($haystack) - strlen($needle); |
|
62 | + default : |
|
63 | + throw new Exception\BadRequest('Match-type: ' . $matchType . ' is not supported'); |
|
64 | + |
|
65 | + } |
|
66 | + |
|
67 | + } |
|
68 | + |
|
69 | + /** |
|
70 | + * This method takes an input string, checks if it's not valid UTF-8 and |
|
71 | + * attempts to convert it to UTF-8 if it's not. |
|
72 | + * |
|
73 | + * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1), |
|
74 | + * anything else will likely fail. |
|
75 | + * |
|
76 | + * @param string $input |
|
77 | + * @return string |
|
78 | + */ |
|
79 | + static function ensureUTF8($input) { |
|
80 | + |
|
81 | + $encoding = mb_detect_encoding($input, ['UTF-8', 'ISO-8859-1'], true); |
|
82 | + |
|
83 | + if ($encoding === 'ISO-8859-1') { |
|
84 | + return utf8_encode($input); |
|
85 | + } else { |
|
86 | + return $input; |
|
87 | + } |
|
88 | + |
|
89 | + } |
|
90 | 90 | |
91 | 91 | } |
@@ -60,7 +60,7 @@ |
||
60 | 60 | // pure sql. MySQL's non-standard string concatenation prevents us |
61 | 61 | // from doing this though. |
62 | 62 | $query = sprintf('SELECT owner, token, timeout, created, scope, depth, uri FROM %s WHERE (created > (? - timeout)) && ((uri = ?)', $this->tableName); |
63 | - $params = [time(),$uri]; |
|
63 | + $params = [time(), $uri]; |
|
64 | 64 | |
65 | 65 | // We need to check locks for every part in the uri. |
66 | 66 | $uriParts = explode('/', $uri); |
@@ -16,165 +16,165 @@ |
||
16 | 16 | */ |
17 | 17 | class PDO extends AbstractBackend { |
18 | 18 | |
19 | - /** |
|
20 | - * The PDO tablename this backend uses. |
|
21 | - * |
|
22 | - * @var string |
|
23 | - */ |
|
24 | - public $tableName = 'locks'; |
|
25 | - |
|
26 | - /** |
|
27 | - * The PDO connection object |
|
28 | - * |
|
29 | - * @var pdo |
|
30 | - */ |
|
31 | - protected $pdo; |
|
32 | - |
|
33 | - /** |
|
34 | - * Constructor |
|
35 | - * |
|
36 | - * @param PDO $pdo |
|
37 | - */ |
|
38 | - public function __construct(\PDO $pdo) { |
|
39 | - |
|
40 | - $this->pdo = $pdo; |
|
41 | - |
|
42 | - } |
|
43 | - |
|
44 | - /** |
|
45 | - * Returns a list of Sabre\DAV\Locks\LockInfo objects |
|
46 | - * |
|
47 | - * This method should return all the locks for a particular uri, including |
|
48 | - * locks that might be set on a parent uri. |
|
49 | - * |
|
50 | - * If returnChildLocks is set to true, this method should also look for |
|
51 | - * any locks in the subtree of the uri for locks. |
|
52 | - * |
|
53 | - * @param string $uri |
|
54 | - * @param bool $returnChildLocks |
|
55 | - * @return array |
|
56 | - */ |
|
57 | - public function getLocks($uri, $returnChildLocks) { |
|
58 | - |
|
59 | - // NOTE: the following 10 lines or so could be easily replaced by |
|
60 | - // pure sql. MySQL's non-standard string concatenation prevents us |
|
61 | - // from doing this though. |
|
62 | - $query = sprintf('SELECT owner, token, timeout, created, scope, depth, uri FROM %s WHERE (created > (? - timeout)) && ((uri = ?)', $this->tableName); |
|
63 | - $params = [time(),$uri]; |
|
64 | - |
|
65 | - // We need to check locks for every part in the uri. |
|
66 | - $uriParts = explode('/', $uri); |
|
67 | - |
|
68 | - // We already covered the last part of the uri |
|
69 | - array_pop($uriParts); |
|
70 | - |
|
71 | - $currentPath = ''; |
|
72 | - |
|
73 | - foreach ($uriParts as $part) { |
|
74 | - |
|
75 | - if ($currentPath) $currentPath .= '/'; |
|
76 | - $currentPath .= $part; |
|
77 | - |
|
78 | - $query .= ' OR (depth!=0 && uri = ?)'; |
|
79 | - $params[] = $currentPath; |
|
80 | - |
|
81 | - } |
|
82 | - |
|
83 | - if ($returnChildLocks) { |
|
84 | - |
|
85 | - $query .= ' OR (uri LIKE ?)'; |
|
86 | - $params[] = $uri . '/%'; |
|
87 | - |
|
88 | - } |
|
89 | - $query .= ')'; |
|
90 | - |
|
91 | - $stmt = $this->pdo->prepare($query); |
|
92 | - $stmt->execute($params); |
|
93 | - $result = $stmt->fetchAll(); |
|
94 | - |
|
95 | - $lockList = []; |
|
96 | - foreach ($result as $row) { |
|
97 | - |
|
98 | - $lockInfo = new LockInfo(); |
|
99 | - $lockInfo->owner = $row['owner']; |
|
100 | - $lockInfo->token = $row['token']; |
|
101 | - $lockInfo->timeout = $row['timeout']; |
|
102 | - $lockInfo->created = $row['created']; |
|
103 | - $lockInfo->scope = $row['scope']; |
|
104 | - $lockInfo->depth = $row['depth']; |
|
105 | - $lockInfo->uri = $row['uri']; |
|
106 | - $lockList[] = $lockInfo; |
|
107 | - |
|
108 | - } |
|
109 | - |
|
110 | - return $lockList; |
|
111 | - |
|
112 | - } |
|
113 | - |
|
114 | - /** |
|
115 | - * Locks a uri |
|
116 | - * |
|
117 | - * @param string $uri |
|
118 | - * @param LockInfo $lockInfo |
|
119 | - * @return bool |
|
120 | - */ |
|
121 | - public function lock($uri, LockInfo $lockInfo) { |
|
122 | - |
|
123 | - // We're making the lock timeout 30 minutes |
|
124 | - $lockInfo->timeout = 30 * 60; |
|
125 | - $lockInfo->created = time(); |
|
126 | - $lockInfo->uri = $uri; |
|
127 | - |
|
128 | - $locks = $this->getLocks($uri, false); |
|
129 | - $exists = false; |
|
130 | - foreach ($locks as $lock) { |
|
131 | - if ($lock->token == $lockInfo->token) $exists = true; |
|
132 | - } |
|
133 | - |
|
134 | - if ($exists) { |
|
135 | - $stmt = $this->pdo->prepare(sprintf('UPDATE %s SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?', $this->tableName)); |
|
136 | - $stmt->execute([ |
|
137 | - $lockInfo->owner, |
|
138 | - $lockInfo->timeout, |
|
139 | - $lockInfo->scope, |
|
140 | - $lockInfo->depth, |
|
141 | - $uri, |
|
142 | - $lockInfo->created, |
|
143 | - $lockInfo->token |
|
144 | - ]); |
|
145 | - } else { |
|
146 | - $stmt = $this->pdo->prepare('INSERT INTO ' . $this->tableName . ' (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)'); |
|
147 | - $stmt->execute([ |
|
148 | - $lockInfo->owner, |
|
149 | - $lockInfo->timeout, |
|
150 | - $lockInfo->scope, |
|
151 | - $lockInfo->depth, |
|
152 | - $uri, |
|
153 | - $lockInfo->created, |
|
154 | - $lockInfo->token |
|
155 | - ]); |
|
156 | - } |
|
157 | - |
|
158 | - return true; |
|
159 | - |
|
160 | - } |
|
161 | - |
|
162 | - |
|
163 | - |
|
164 | - /** |
|
165 | - * Removes a lock from a uri |
|
166 | - * |
|
167 | - * @param string $uri |
|
168 | - * @param LockInfo $lockInfo |
|
169 | - * @return bool |
|
170 | - */ |
|
171 | - public function unlock($uri, LockInfo $lockInfo) { |
|
172 | - |
|
173 | - $stmt = $this->pdo->prepare(sprintf('DELETE FROM %s WHERE uri = ? && token = ?', $this->tableName)); |
|
174 | - $stmt->execute([$uri, $lockInfo->token]); |
|
175 | - |
|
176 | - return $stmt->rowCount() === 1; |
|
177 | - |
|
178 | - } |
|
19 | + /** |
|
20 | + * The PDO tablename this backend uses. |
|
21 | + * |
|
22 | + * @var string |
|
23 | + */ |
|
24 | + public $tableName = 'locks'; |
|
25 | + |
|
26 | + /** |
|
27 | + * The PDO connection object |
|
28 | + * |
|
29 | + * @var pdo |
|
30 | + */ |
|
31 | + protected $pdo; |
|
32 | + |
|
33 | + /** |
|
34 | + * Constructor |
|
35 | + * |
|
36 | + * @param PDO $pdo |
|
37 | + */ |
|
38 | + public function __construct(\PDO $pdo) { |
|
39 | + |
|
40 | + $this->pdo = $pdo; |
|
41 | + |
|
42 | + } |
|
43 | + |
|
44 | + /** |
|
45 | + * Returns a list of Sabre\DAV\Locks\LockInfo objects |
|
46 | + * |
|
47 | + * This method should return all the locks for a particular uri, including |
|
48 | + * locks that might be set on a parent uri. |
|
49 | + * |
|
50 | + * If returnChildLocks is set to true, this method should also look for |
|
51 | + * any locks in the subtree of the uri for locks. |
|
52 | + * |
|
53 | + * @param string $uri |
|
54 | + * @param bool $returnChildLocks |
|
55 | + * @return array |
|
56 | + */ |
|
57 | + public function getLocks($uri, $returnChildLocks) { |
|
58 | + |
|
59 | + // NOTE: the following 10 lines or so could be easily replaced by |
|
60 | + // pure sql. MySQL's non-standard string concatenation prevents us |
|
61 | + // from doing this though. |
|
62 | + $query = sprintf('SELECT owner, token, timeout, created, scope, depth, uri FROM %s WHERE (created > (? - timeout)) && ((uri = ?)', $this->tableName); |
|
63 | + $params = [time(),$uri]; |
|
64 | + |
|
65 | + // We need to check locks for every part in the uri. |
|
66 | + $uriParts = explode('/', $uri); |
|
67 | + |
|
68 | + // We already covered the last part of the uri |
|
69 | + array_pop($uriParts); |
|
70 | + |
|
71 | + $currentPath = ''; |
|
72 | + |
|
73 | + foreach ($uriParts as $part) { |
|
74 | + |
|
75 | + if ($currentPath) $currentPath .= '/'; |
|
76 | + $currentPath .= $part; |
|
77 | + |
|
78 | + $query .= ' OR (depth!=0 && uri = ?)'; |
|
79 | + $params[] = $currentPath; |
|
80 | + |
|
81 | + } |
|
82 | + |
|
83 | + if ($returnChildLocks) { |
|
84 | + |
|
85 | + $query .= ' OR (uri LIKE ?)'; |
|
86 | + $params[] = $uri . '/%'; |
|
87 | + |
|
88 | + } |
|
89 | + $query .= ')'; |
|
90 | + |
|
91 | + $stmt = $this->pdo->prepare($query); |
|
92 | + $stmt->execute($params); |
|
93 | + $result = $stmt->fetchAll(); |
|
94 | + |
|
95 | + $lockList = []; |
|
96 | + foreach ($result as $row) { |
|
97 | + |
|
98 | + $lockInfo = new LockInfo(); |
|
99 | + $lockInfo->owner = $row['owner']; |
|
100 | + $lockInfo->token = $row['token']; |
|
101 | + $lockInfo->timeout = $row['timeout']; |
|
102 | + $lockInfo->created = $row['created']; |
|
103 | + $lockInfo->scope = $row['scope']; |
|
104 | + $lockInfo->depth = $row['depth']; |
|
105 | + $lockInfo->uri = $row['uri']; |
|
106 | + $lockList[] = $lockInfo; |
|
107 | + |
|
108 | + } |
|
109 | + |
|
110 | + return $lockList; |
|
111 | + |
|
112 | + } |
|
113 | + |
|
114 | + /** |
|
115 | + * Locks a uri |
|
116 | + * |
|
117 | + * @param string $uri |
|
118 | + * @param LockInfo $lockInfo |
|
119 | + * @return bool |
|
120 | + */ |
|
121 | + public function lock($uri, LockInfo $lockInfo) { |
|
122 | + |
|
123 | + // We're making the lock timeout 30 minutes |
|
124 | + $lockInfo->timeout = 30 * 60; |
|
125 | + $lockInfo->created = time(); |
|
126 | + $lockInfo->uri = $uri; |
|
127 | + |
|
128 | + $locks = $this->getLocks($uri, false); |
|
129 | + $exists = false; |
|
130 | + foreach ($locks as $lock) { |
|
131 | + if ($lock->token == $lockInfo->token) $exists = true; |
|
132 | + } |
|
133 | + |
|
134 | + if ($exists) { |
|
135 | + $stmt = $this->pdo->prepare(sprintf('UPDATE %s SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?', $this->tableName)); |
|
136 | + $stmt->execute([ |
|
137 | + $lockInfo->owner, |
|
138 | + $lockInfo->timeout, |
|
139 | + $lockInfo->scope, |
|
140 | + $lockInfo->depth, |
|
141 | + $uri, |
|
142 | + $lockInfo->created, |
|
143 | + $lockInfo->token |
|
144 | + ]); |
|
145 | + } else { |
|
146 | + $stmt = $this->pdo->prepare('INSERT INTO ' . $this->tableName . ' (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)'); |
|
147 | + $stmt->execute([ |
|
148 | + $lockInfo->owner, |
|
149 | + $lockInfo->timeout, |
|
150 | + $lockInfo->scope, |
|
151 | + $lockInfo->depth, |
|
152 | + $uri, |
|
153 | + $lockInfo->created, |
|
154 | + $lockInfo->token |
|
155 | + ]); |
|
156 | + } |
|
157 | + |
|
158 | + return true; |
|
159 | + |
|
160 | + } |
|
161 | + |
|
162 | + |
|
163 | + |
|
164 | + /** |
|
165 | + * Removes a lock from a uri |
|
166 | + * |
|
167 | + * @param string $uri |
|
168 | + * @param LockInfo $lockInfo |
|
169 | + * @return bool |
|
170 | + */ |
|
171 | + public function unlock($uri, LockInfo $lockInfo) { |
|
172 | + |
|
173 | + $stmt = $this->pdo->prepare(sprintf('DELETE FROM %s WHERE uri = ? && token = ?', $this->tableName)); |
|
174 | + $stmt->execute([$uri, $lockInfo->token]); |
|
175 | + |
|
176 | + return $stmt->rowCount() === 1; |
|
177 | + |
|
178 | + } |
|
179 | 179 | |
180 | 180 | } |
@@ -33,7 +33,7 @@ |
||
33 | 33 | /** |
34 | 34 | * Constructor |
35 | 35 | * |
36 | - * @param PDO $pdo |
|
36 | + * @param \PDO $pdo |
|
37 | 37 | */ |
38 | 38 | public function __construct(\PDO $pdo) { |
39 | 39 |
@@ -72,7 +72,9 @@ discard block |
||
72 | 72 | |
73 | 73 | foreach ($uriParts as $part) { |
74 | 74 | |
75 | - if ($currentPath) $currentPath .= '/'; |
|
75 | + if ($currentPath) { |
|
76 | + $currentPath .= '/'; |
|
77 | + } |
|
76 | 78 | $currentPath .= $part; |
77 | 79 | |
78 | 80 | $query .= ' OR (depth!=0 && uri = ?)'; |
@@ -128,7 +130,9 @@ discard block |
||
128 | 130 | $locks = $this->getLocks($uri, false); |
129 | 131 | $exists = false; |
130 | 132 | foreach ($locks as $lock) { |
131 | - if ($lock->token == $lockInfo->token) $exists = true; |
|
133 | + if ($lock->token == $lockInfo->token) { |
|
134 | + $exists = true; |
|
135 | + } |
|
132 | 136 | } |
133 | 137 | |
134 | 138 | if ($exists) { |
@@ -73,7 +73,9 @@ discard block |
||
73 | 73 | |
74 | 74 | // Checking if we can remove any of these locks |
75 | 75 | foreach ($newLocks as $k => $lock) { |
76 | - if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]); |
|
76 | + if (time() > $lock->timeout + $lock->created) { |
|
77 | + unset($newLocks[$k]); |
|
78 | + } |
|
77 | 79 | } |
78 | 80 | return $newLocks; |
79 | 81 | |
@@ -140,7 +142,9 @@ discard block |
||
140 | 142 | */ |
141 | 143 | protected function getData() { |
142 | 144 | |
143 | - if (!file_exists($this->locksFile)) return []; |
|
145 | + if (!file_exists($this->locksFile)) { |
|
146 | + return []; |
|
147 | + } |
|
144 | 148 | |
145 | 149 | // opening up the file, and creating a shared lock |
146 | 150 | $handle = fopen($this->locksFile, 'r'); |
@@ -155,7 +159,9 @@ discard block |
||
155 | 159 | |
156 | 160 | // Unserializing and checking if the resource file contains data for this file |
157 | 161 | $data = unserialize($data); |
158 | - if (!$data) return []; |
|
162 | + if (!$data) { |
|
163 | + return []; |
|
164 | + } |
|
159 | 165 | return $data; |
160 | 166 | |
161 | 167 | } |
@@ -19,167 +19,167 @@ |
||
19 | 19 | */ |
20 | 20 | class File extends AbstractBackend { |
21 | 21 | |
22 | - /** |
|
23 | - * The storage file |
|
24 | - * |
|
25 | - * @var string |
|
26 | - */ |
|
27 | - private $locksFile; |
|
28 | - |
|
29 | - /** |
|
30 | - * Constructor |
|
31 | - * |
|
32 | - * @param string $locksFile path to file |
|
33 | - */ |
|
34 | - public function __construct($locksFile) { |
|
35 | - |
|
36 | - $this->locksFile = $locksFile; |
|
37 | - |
|
38 | - } |
|
39 | - |
|
40 | - /** |
|
41 | - * Returns a list of Sabre\DAV\Locks\LockInfo objects |
|
42 | - * |
|
43 | - * This method should return all the locks for a particular uri, including |
|
44 | - * locks that might be set on a parent uri. |
|
45 | - * |
|
46 | - * If returnChildLocks is set to true, this method should also look for |
|
47 | - * any locks in the subtree of the uri for locks. |
|
48 | - * |
|
49 | - * @param string $uri |
|
50 | - * @param bool $returnChildLocks |
|
51 | - * @return array |
|
52 | - */ |
|
53 | - public function getLocks($uri, $returnChildLocks) { |
|
54 | - |
|
55 | - $newLocks = []; |
|
56 | - |
|
57 | - $locks = $this->getData(); |
|
58 | - |
|
59 | - foreach ($locks as $lock) { |
|
60 | - |
|
61 | - if ($lock->uri === $uri || |
|
62 | - //deep locks on parents |
|
63 | - ($lock->depth != 0 && strpos($uri, $lock->uri . '/') === 0) || |
|
64 | - |
|
65 | - // locks on children |
|
66 | - ($returnChildLocks && (strpos($lock->uri, $uri . '/') === 0))) { |
|
67 | - |
|
68 | - $newLocks[] = $lock; |
|
69 | - |
|
70 | - } |
|
71 | - |
|
72 | - } |
|
73 | - |
|
74 | - // Checking if we can remove any of these locks |
|
75 | - foreach ($newLocks as $k => $lock) { |
|
76 | - if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]); |
|
77 | - } |
|
78 | - return $newLocks; |
|
79 | - |
|
80 | - } |
|
81 | - |
|
82 | - /** |
|
83 | - * Locks a uri |
|
84 | - * |
|
85 | - * @param string $uri |
|
86 | - * @param LockInfo $lockInfo |
|
87 | - * @return bool |
|
88 | - */ |
|
89 | - public function lock($uri, LockInfo $lockInfo) { |
|
90 | - |
|
91 | - // We're making the lock timeout 30 minutes |
|
92 | - $lockInfo->timeout = 1800; |
|
93 | - $lockInfo->created = time(); |
|
94 | - $lockInfo->uri = $uri; |
|
95 | - |
|
96 | - $locks = $this->getData(); |
|
97 | - |
|
98 | - foreach ($locks as $k => $lock) { |
|
99 | - if ( |
|
100 | - ($lock->token == $lockInfo->token) || |
|
101 | - (time() > $lock->timeout + $lock->created) |
|
102 | - ) { |
|
103 | - unset($locks[$k]); |
|
104 | - } |
|
105 | - } |
|
106 | - $locks[] = $lockInfo; |
|
107 | - $this->putData($locks); |
|
108 | - return true; |
|
109 | - |
|
110 | - } |
|
111 | - |
|
112 | - /** |
|
113 | - * Removes a lock from a uri |
|
114 | - * |
|
115 | - * @param string $uri |
|
116 | - * @param LockInfo $lockInfo |
|
117 | - * @return bool |
|
118 | - */ |
|
119 | - public function unlock($uri, LockInfo $lockInfo) { |
|
120 | - |
|
121 | - $locks = $this->getData(); |
|
122 | - foreach ($locks as $k => $lock) { |
|
123 | - |
|
124 | - if ($lock->token == $lockInfo->token) { |
|
125 | - |
|
126 | - unset($locks[$k]); |
|
127 | - $this->putData($locks); |
|
128 | - return true; |
|
129 | - |
|
130 | - } |
|
131 | - } |
|
132 | - return false; |
|
133 | - |
|
134 | - } |
|
135 | - |
|
136 | - /** |
|
137 | - * Loads the lockdata from the filesystem. |
|
138 | - * |
|
139 | - * @return array |
|
140 | - */ |
|
141 | - protected function getData() { |
|
142 | - |
|
143 | - if (!file_exists($this->locksFile)) return []; |
|
144 | - |
|
145 | - // opening up the file, and creating a shared lock |
|
146 | - $handle = fopen($this->locksFile, 'r'); |
|
147 | - flock($handle, LOCK_SH); |
|
148 | - |
|
149 | - // Reading data until the eof |
|
150 | - $data = stream_get_contents($handle); |
|
22 | + /** |
|
23 | + * The storage file |
|
24 | + * |
|
25 | + * @var string |
|
26 | + */ |
|
27 | + private $locksFile; |
|
28 | + |
|
29 | + /** |
|
30 | + * Constructor |
|
31 | + * |
|
32 | + * @param string $locksFile path to file |
|
33 | + */ |
|
34 | + public function __construct($locksFile) { |
|
35 | + |
|
36 | + $this->locksFile = $locksFile; |
|
37 | + |
|
38 | + } |
|
39 | + |
|
40 | + /** |
|
41 | + * Returns a list of Sabre\DAV\Locks\LockInfo objects |
|
42 | + * |
|
43 | + * This method should return all the locks for a particular uri, including |
|
44 | + * locks that might be set on a parent uri. |
|
45 | + * |
|
46 | + * If returnChildLocks is set to true, this method should also look for |
|
47 | + * any locks in the subtree of the uri for locks. |
|
48 | + * |
|
49 | + * @param string $uri |
|
50 | + * @param bool $returnChildLocks |
|
51 | + * @return array |
|
52 | + */ |
|
53 | + public function getLocks($uri, $returnChildLocks) { |
|
54 | + |
|
55 | + $newLocks = []; |
|
56 | + |
|
57 | + $locks = $this->getData(); |
|
58 | + |
|
59 | + foreach ($locks as $lock) { |
|
60 | + |
|
61 | + if ($lock->uri === $uri || |
|
62 | + //deep locks on parents |
|
63 | + ($lock->depth != 0 && strpos($uri, $lock->uri . '/') === 0) || |
|
64 | + |
|
65 | + // locks on children |
|
66 | + ($returnChildLocks && (strpos($lock->uri, $uri . '/') === 0))) { |
|
67 | + |
|
68 | + $newLocks[] = $lock; |
|
69 | + |
|
70 | + } |
|
71 | + |
|
72 | + } |
|
73 | + |
|
74 | + // Checking if we can remove any of these locks |
|
75 | + foreach ($newLocks as $k => $lock) { |
|
76 | + if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]); |
|
77 | + } |
|
78 | + return $newLocks; |
|
79 | + |
|
80 | + } |
|
81 | + |
|
82 | + /** |
|
83 | + * Locks a uri |
|
84 | + * |
|
85 | + * @param string $uri |
|
86 | + * @param LockInfo $lockInfo |
|
87 | + * @return bool |
|
88 | + */ |
|
89 | + public function lock($uri, LockInfo $lockInfo) { |
|
90 | + |
|
91 | + // We're making the lock timeout 30 minutes |
|
92 | + $lockInfo->timeout = 1800; |
|
93 | + $lockInfo->created = time(); |
|
94 | + $lockInfo->uri = $uri; |
|
95 | + |
|
96 | + $locks = $this->getData(); |
|
97 | + |
|
98 | + foreach ($locks as $k => $lock) { |
|
99 | + if ( |
|
100 | + ($lock->token == $lockInfo->token) || |
|
101 | + (time() > $lock->timeout + $lock->created) |
|
102 | + ) { |
|
103 | + unset($locks[$k]); |
|
104 | + } |
|
105 | + } |
|
106 | + $locks[] = $lockInfo; |
|
107 | + $this->putData($locks); |
|
108 | + return true; |
|
109 | + |
|
110 | + } |
|
111 | + |
|
112 | + /** |
|
113 | + * Removes a lock from a uri |
|
114 | + * |
|
115 | + * @param string $uri |
|
116 | + * @param LockInfo $lockInfo |
|
117 | + * @return bool |
|
118 | + */ |
|
119 | + public function unlock($uri, LockInfo $lockInfo) { |
|
120 | + |
|
121 | + $locks = $this->getData(); |
|
122 | + foreach ($locks as $k => $lock) { |
|
123 | + |
|
124 | + if ($lock->token == $lockInfo->token) { |
|
125 | + |
|
126 | + unset($locks[$k]); |
|
127 | + $this->putData($locks); |
|
128 | + return true; |
|
129 | + |
|
130 | + } |
|
131 | + } |
|
132 | + return false; |
|
133 | + |
|
134 | + } |
|
135 | + |
|
136 | + /** |
|
137 | + * Loads the lockdata from the filesystem. |
|
138 | + * |
|
139 | + * @return array |
|
140 | + */ |
|
141 | + protected function getData() { |
|
142 | + |
|
143 | + if (!file_exists($this->locksFile)) return []; |
|
144 | + |
|
145 | + // opening up the file, and creating a shared lock |
|
146 | + $handle = fopen($this->locksFile, 'r'); |
|
147 | + flock($handle, LOCK_SH); |
|
148 | + |
|
149 | + // Reading data until the eof |
|
150 | + $data = stream_get_contents($handle); |
|
151 | 151 | |
152 | - // We're all good |
|
153 | - flock($handle, LOCK_UN); |
|
154 | - fclose($handle); |
|
152 | + // We're all good |
|
153 | + flock($handle, LOCK_UN); |
|
154 | + fclose($handle); |
|
155 | 155 | |
156 | - // Unserializing and checking if the resource file contains data for this file |
|
157 | - $data = unserialize($data); |
|
158 | - if (!$data) return []; |
|
159 | - return $data; |
|
160 | - |
|
161 | - } |
|
162 | - |
|
163 | - /** |
|
164 | - * Saves the lockdata |
|
165 | - * |
|
166 | - * @param array $newData |
|
167 | - * @return void |
|
168 | - */ |
|
169 | - protected function putData(array $newData) { |
|
170 | - |
|
171 | - // opening up the file, and creating an exclusive lock |
|
172 | - $handle = fopen($this->locksFile, 'a+'); |
|
173 | - flock($handle, LOCK_EX); |
|
174 | - |
|
175 | - // We can only truncate and rewind once the lock is acquired. |
|
176 | - ftruncate($handle, 0); |
|
177 | - rewind($handle); |
|
178 | - |
|
179 | - fwrite($handle, serialize($newData)); |
|
180 | - flock($handle, LOCK_UN); |
|
181 | - fclose($handle); |
|
182 | - |
|
183 | - } |
|
156 | + // Unserializing and checking if the resource file contains data for this file |
|
157 | + $data = unserialize($data); |
|
158 | + if (!$data) return []; |
|
159 | + return $data; |
|
160 | + |
|
161 | + } |
|
162 | + |
|
163 | + /** |
|
164 | + * Saves the lockdata |
|
165 | + * |
|
166 | + * @param array $newData |
|
167 | + * @return void |
|
168 | + */ |
|
169 | + protected function putData(array $newData) { |
|
170 | + |
|
171 | + // opening up the file, and creating an exclusive lock |
|
172 | + $handle = fopen($this->locksFile, 'a+'); |
|
173 | + flock($handle, LOCK_EX); |
|
174 | + |
|
175 | + // We can only truncate and rewind once the lock is acquired. |
|
176 | + ftruncate($handle, 0); |
|
177 | + rewind($handle); |
|
178 | + |
|
179 | + fwrite($handle, serialize($newData)); |
|
180 | + flock($handle, LOCK_UN); |
|
181 | + fclose($handle); |
|
182 | + |
|
183 | + } |
|
184 | 184 | |
185 | 185 | } |