1 | <?php |
||||||
2 | /** |
||||||
3 | * @package midcom.routing |
||||||
4 | * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||||||
5 | * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
||||||
6 | * @license http://www.gnu.org/licenses/gpl.html GNU General Public License |
||||||
7 | */ |
||||||
8 | |||||||
9 | namespace midcom\routing; |
||||||
10 | |||||||
11 | use midcom_connection; |
||||||
12 | use midcom_core_context; |
||||||
13 | use midcom_db_topic; |
||||||
14 | |||||||
15 | /** |
||||||
16 | * URL name parser that uses the topic structure |
||||||
17 | * |
||||||
18 | * @package midcom.routing |
||||||
19 | */ |
||||||
20 | class parser |
||||||
21 | { |
||||||
22 | public array $argv = []; |
||||||
23 | |||||||
24 | private ?midcom_db_topic $current = null; |
||||||
25 | |||||||
26 | private string $url = ''; |
||||||
27 | |||||||
28 | /** |
||||||
29 | * Objects by URL |
||||||
30 | * |
||||||
31 | * @var midcom_db_topic[] |
||||||
32 | */ |
||||||
33 | private array $objects = []; |
||||||
34 | |||||||
35 | private midcom_core_context $context; |
||||||
36 | |||||||
37 | 354 | public function __construct(midcom_core_context $context) |
|||||
38 | { |
||||||
39 | 354 | $this->context = $context; |
|||||
40 | 354 | $url = $this->context->get_key(MIDCOM_CONTEXT_URI); |
|||||
41 | |||||||
42 | 354 | $prefix_length = strlen(midcom_connection::get_url('prefix')); |
|||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
43 | 354 | if ( $prefix_length > 1 |
|||||
44 | 354 | && str_starts_with($url, midcom_connection::get_url('prefix'))) { |
|||||
0 ignored issues
–
show
It seems like
midcom_connection::get_url('prefix') can also be of type null ; however, parameter $needle of str_starts_with() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() It seems like
$url can also be of type false ; however, parameter $haystack of str_starts_with() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
45 | $url = substr($url, $prefix_length); |
||||||
0 ignored issues
–
show
It seems like
$url can also be of type false ; however, parameter $string of substr() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
46 | } |
||||||
47 | 354 | $url = trim($url, '/'); |
|||||
48 | 354 | if ($url != '') { |
|||||
49 | 338 | $argv = explode('/', $url); |
|||||
50 | 338 | foreach ($argv as $val) { |
|||||
51 | 338 | if ($val !== '') { |
|||||
52 | 338 | $this->argv[] = $val; |
|||||
53 | } |
||||||
54 | } |
||||||
55 | } |
||||||
56 | } |
||||||
57 | |||||||
58 | /** |
||||||
59 | * Try to fetch a URL variable. |
||||||
60 | * |
||||||
61 | * Try to decode an midcom-<key>-<value> pair at the current URL |
||||||
62 | * position. |
||||||
63 | * |
||||||
64 | * On success it returns the command it found. |
||||||
65 | */ |
||||||
66 | 353 | public function find_urlmethod() : ?string |
|||||
67 | { |
||||||
68 | 353 | if ( empty($this->argv) |
|||||
69 | 353 | || !str_starts_with($this->argv[0], 'midcom-')) { |
|||||
70 | 352 | return null; |
|||||
71 | } |
||||||
72 | 1 | return $this->context->get_key(MIDCOM_CONTEXT_URI); |
|||||
73 | } |
||||||
74 | |||||||
75 | /** |
||||||
76 | * @throws \midcom_error |
||||||
77 | */ |
||||||
78 | 352 | public function find_topic() : midcom_db_topic |
|||||
79 | { |
||||||
80 | 352 | $this->current = $this->context->get_key(MIDCOM_CONTEXT_ROOTTOPIC); |
|||||
81 | 352 | if (!$this->current) { |
|||||
82 | throw new \midcom_error('Root node missing.'); |
||||||
83 | } |
||||||
84 | 352 | $this->walk_topics(); |
|||||
85 | |||||||
86 | // Initialize context |
||||||
87 | 352 | $this->context->set_key(MIDCOM_CONTEXT_ANCHORPREFIX, midcom_connection::get_url('self') . $this->url); |
|||||
88 | 352 | $this->context->set_key(MIDCOM_CONTEXT_COMPONENT, $this->current->component); |
|||||
89 | 352 | $this->context->set_key(MIDCOM_CONTEXT_CONTENTTOPIC, $this->current); |
|||||
90 | 352 | $this->context->set_key(MIDCOM_CONTEXT_URLTOPICS, $this->objects); |
|||||
91 | |||||||
92 | 352 | return $this->current; |
|||||
93 | } |
||||||
94 | |||||||
95 | /** |
||||||
96 | * Load topics recursively from argv |
||||||
97 | */ |
||||||
98 | 352 | private function walk_topics() |
|||||
99 | { |
||||||
100 | 352 | if (empty($this->argv)) { |
|||||
101 | // No arguments left |
||||||
102 | 20 | return; |
|||||
103 | } |
||||||
104 | |||||||
105 | 336 | $object_url = $this->argv[0] . '/'; |
|||||
106 | 336 | if (!empty($this->url)) { |
|||||
107 | 3 | $object_url = $this->url . $object_url; |
|||||
108 | } |
||||||
109 | 336 | if (!array_key_exists($object_url, $this->objects)) { |
|||||
110 | 336 | $qb = midcom_db_topic::new_query_builder(); |
|||||
111 | 336 | $qb->add_constraint('name', '=', $this->argv[0]); |
|||||
112 | 336 | $qb->add_constraint('up', '=', $this->current->id); |
|||||
113 | |||||||
114 | 336 | if ($qb->count() == 0) { |
|||||
115 | // last load returned ACCESS DENIED, no sense to dig deeper |
||||||
116 | 336 | if ($qb->denied > 0) { |
|||||
117 | throw new \midcom_error_forbidden; |
||||||
118 | } |
||||||
119 | // allow for handler switches to work |
||||||
120 | 336 | return; |
|||||
121 | } |
||||||
122 | // Set to current topic |
||||||
123 | 3 | $this->objects[$object_url] = $qb->get_result(0); |
|||||
124 | } |
||||||
125 | // Remove this component from path |
||||||
126 | 3 | array_shift($this->argv); |
|||||
127 | |||||||
128 | // Set as current object |
||||||
129 | 3 | $this->url = $object_url; |
|||||
130 | 3 | $this->current = $this->objects[$object_url]; |
|||||
131 | 3 | $this->walk_topics(); |
|||||
132 | } |
||||||
133 | } |
||||||
134 |