flack /
openpsa
| 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 | 355 | public function __construct(midcom_core_context $context) |
|||||
| 38 | { |
||||||
| 39 | 355 | $this->context = $context; |
|||||
| 40 | 355 | $url = $this->context->get_key(MIDCOM_CONTEXT_URI); |
|||||
| 41 | |||||||
| 42 | 355 | $prefix_length = strlen(midcom_connection::get_url('prefix')); |
|||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||||
| 43 | 355 | if ( $prefix_length > 1 |
|||||
| 44 | 355 | && 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
Loading history...
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
Loading history...
|
|||||||
| 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
Loading history...
|
|||||||
| 46 | } |
||||||
| 47 | 355 | $url = trim($url, '/'); |
|||||
| 48 | 355 | if ($url != '') { |
|||||
| 49 | 339 | $argv = explode('/', $url); |
|||||
| 50 | 339 | foreach ($argv as $val) { |
|||||
| 51 | 339 | if ($val !== '') { |
|||||
| 52 | 339 | $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 | 354 | public function find_urlmethod() : ?string |
|||||
| 67 | { |
||||||
| 68 | 354 | if ( empty($this->argv) |
|||||
| 69 | 354 | || !str_starts_with($this->argv[0], 'midcom-')) { |
|||||
| 70 | 353 | return null; |
|||||
| 71 | } |
||||||
| 72 | 1 | return $this->context->get_key(MIDCOM_CONTEXT_URI); |
|||||
| 73 | } |
||||||
| 74 | |||||||
| 75 | /** |
||||||
| 76 | * @throws \midcom_error |
||||||
| 77 | */ |
||||||
| 78 | 353 | public function find_topic() : midcom_db_topic |
|||||
| 79 | { |
||||||
| 80 | 353 | $this->current = $this->context->get_key(MIDCOM_CONTEXT_ROOTTOPIC); |
|||||
| 81 | 353 | if (!$this->current) { |
|||||
| 82 | throw new \midcom_error('Root node missing.'); |
||||||
| 83 | } |
||||||
| 84 | 353 | $this->walk_topics(); |
|||||
| 85 | |||||||
| 86 | // Initialize context |
||||||
| 87 | 353 | $this->context->set_key(MIDCOM_CONTEXT_ANCHORPREFIX, midcom_connection::get_url('self') . $this->url); |
|||||
| 88 | 353 | $this->context->set_key(MIDCOM_CONTEXT_COMPONENT, $this->current->component); |
|||||
| 89 | 353 | $this->context->set_key(MIDCOM_CONTEXT_CONTENTTOPIC, $this->current); |
|||||
| 90 | 353 | $this->context->set_key(MIDCOM_CONTEXT_URLTOPICS, $this->objects); |
|||||
| 91 | |||||||
| 92 | 353 | return $this->current; |
|||||
| 93 | } |
||||||
| 94 | |||||||
| 95 | /** |
||||||
| 96 | * Load topics recursively from argv |
||||||
| 97 | */ |
||||||
| 98 | 353 | private function walk_topics() |
|||||
| 99 | { |
||||||
| 100 | 353 | if (empty($this->argv)) { |
|||||
| 101 | // No arguments left |
||||||
| 102 | 20 | return; |
|||||
| 103 | } |
||||||
| 104 | |||||||
| 105 | 337 | $object_url = $this->argv[0] . '/'; |
|||||
| 106 | 337 | if (!empty($this->url)) { |
|||||
| 107 | 3 | $object_url = $this->url . $object_url; |
|||||
| 108 | } |
||||||
| 109 | 337 | if (!array_key_exists($object_url, $this->objects)) { |
|||||
| 110 | 337 | $qb = midcom_db_topic::new_query_builder(); |
|||||
| 111 | 337 | $qb->add_constraint('name', '=', $this->argv[0]); |
|||||
| 112 | 337 | $qb->add_constraint('up', '=', $this->current->id); |
|||||
| 113 | |||||||
| 114 | 337 | if ($qb->count() == 0) { |
|||||
| 115 | // last load returned ACCESS DENIED, no sense to dig deeper |
||||||
| 116 | 337 | if ($qb->denied > 0) { |
|||||
| 117 | throw new \midcom_error_forbidden; |
||||||
| 118 | } |
||||||
| 119 | // allow for handler switches to work |
||||||
| 120 | 337 | 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 |