Skip to content

Commit

Permalink
Merge Api classes
Browse files Browse the repository at this point in the history
  • Loading branch information
distantnative committed Nov 21, 2024
1 parent 14e4685 commit 0b338a2
Show file tree
Hide file tree
Showing 37 changed files with 1,027 additions and 1,083 deletions.
2 changes: 1 addition & 1 deletion config/fields/mixins/upload.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

use Kirby\Cms\Api;
use Kirby\Api\Api;
use Kirby\Cms\File;
use Kirby\Exception\Exception;
use Kirby\Exception\InvalidArgumentException;
Expand Down
230 changes: 225 additions & 5 deletions src/Api/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@

use Closure;
use Exception;
use Kirby\Cms\App;
use Kirby\Cms\File;
use Kirby\Cms\Files;
use Kirby\Cms\Find;
use Kirby\Cms\ModelWithContent;
use Kirby\Cms\Page;
use Kirby\Cms\Pages;
use Kirby\Cms\Site;
use Kirby\Cms\User;
use Kirby\Cms\Users;
use Kirby\Exception\Exception as ExceptionException;
use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\F;
use Kirby\Form\Form;
use Kirby\Http\Response;
use Kirby\Http\Route;
use Kirby\Http\Router;
use Kirby\Session\Session;
use Kirby\Toolkit\Collection as BaseCollection;
use Kirby\Toolkit\Pagination;
use Throwable;
Expand Down Expand Up @@ -49,6 +60,8 @@ class Api
*/
protected array $data = [];

protected App $kirby;

/**
* Model definitions
*/
Expand Down Expand Up @@ -88,8 +101,9 @@ public function __construct(array $props)
{
$this->authentication = $props['authentication'] ?? null;
$this->data = $props['data'] ?? [];
$this->debug = $props['debug'] ?? false;
$this->kirby = $props['kirby'] ?? App::instance();
$this->routes = $props['routes'] ?? [];
$this->debug = $props['debug'] ?? false;

if ($collections = $props['collections'] ?? null) {
$this->collections = array_change_key_case($collections);
Expand Down Expand Up @@ -147,6 +161,14 @@ public function call(
$this->setRequestMethod($method);
$this->setRequestData($requestData);

$this->kirby->setCurrentLanguage($this->language());

$impersonate = $this->kirby()->option('api.allowImpersonation', false);

$translation = $this->kirby->user(null, $impersonate)?->language();
$translation ??= $this->kirby->panelLanguage();
$this->kirby->setCurrentTranslation($translation);

$this->router = new Router($this->routes());
$this->route = $this->router->find($path, $method);
$auth = $this->route?->attributes()['auth'] ?? true;
Expand Down Expand Up @@ -212,13 +234,14 @@ public function clone(array $props = []): static
{
return new static([
'autentication' => $this->authentication,
'data' => $this->data,
'routes' => $this->routes,
'debug' => $this->debug,
'collections' => $this->collections,
'models' => $this->models,
'data' => $this->data,
'debug' => $this->debug,
'kirby' => $this->kirby,
'models' => $this->models,
'requestData' => $this->requestData,
'requestMethod' => $this->requestMethod,
'routes' => $this->routes,
...$props
]);
}
Expand Down Expand Up @@ -284,6 +307,53 @@ public function debug(): bool
return $this->debug;
}

/**
* @throws \Kirby\Exception\NotFoundException if the field type cannot be found or the field cannot be loaded
*/
public function fieldApi(
ModelWithContent $model,
string $name,
string|null $path = null
): mixed {
$field = Form::for($model)->field($name);

$fieldApi = $this->clone([
'data' => [...$this->data(), 'field' => $field],
'routes' => $field->api(),
]);

return $fieldApi->call(
$path,
$this->requestMethod(),
$this->requestData()
);
}

/**
* Returns the file object for the given
* parent path and filename
*
* @param string $path Path to file's parent model
* @throws \Kirby\Exception\NotFoundException if the file cannot be found
*/
public function file(
string $path,
string $filename
): File|null {
return Find::file($path, $filename);
}

/**
* Returns the all readable files for the parent
*
* @param string $path Path to file's parent model
* @throws \Kirby\Exception\NotFoundException if the file cannot be found
*/
public function files(string $path): Files
{
return $this->parent($path)->files()->filter('isAccessible', true);
}

/**
* Checks if injected data exists for the given key
*/
Expand All @@ -292,6 +362,24 @@ public function hasData(string $key): bool
return isset($this->data[$key]) === true;
}

/**
* Returns the Kirby instance
*/
public function kirby(): App
{
return $this->kirby;
}

/**
* Returns the language request header
*/
public function language(): string|null
{
return
$this->requestQuery('language') ??
$this->requestHeaders('x-language');
}

/**
* Matches an object with an array item
* based on the `type` field
Expand Down Expand Up @@ -341,6 +429,51 @@ public function models(): array
return $this->models;
}

/**
* Returns the page object for the given id
*
* @param string $id Page's id
* @throws \Kirby\Exception\NotFoundException if the page cannot be found
*/
public function page(string $id): Page|null
{
return Find::page($id);
}

/**
* Returns the subpages for the given
* parent. The subpages can be filtered
* by status (draft, listed, unlisted, published, all)
*/
public function pages(
string|null $parentId = null,
string|null $status = null
): Pages {
$parent = $parentId === null ? $this->site() : $this->page($parentId);
$pages = match ($status) {
'all' => $parent->childrenAndDrafts(),
'draft', 'drafts' => $parent->drafts(),
'listed' => $parent->children()->listed(),
'unlisted' => $parent->children()->unlisted(),
'published' => $parent->children(),
default => $parent->children()
};

return $pages->filter('isAccessible', true);
}

/**
* Returns the model's object for the given path
*
* @param string $path Path to parent model
* @throws \Kirby\Exception\InvalidArgumentException if the model type is invalid
* @throws \Kirby\Exception\NotFoundException if the model cannot be found
*/
public function parent(string $path): ModelWithContent|null
{
return Find::parent($path);
}

/**
* Getter for request data
* Can either get all the data
Expand Down Expand Up @@ -577,6 +710,57 @@ public function responseForException(Throwable $e): array
return $result;
}

/**
* Search for direct subpages of the
* given parent
*/
public function searchPages(string|null $parent = null): Pages
{
$pages = $this->pages($parent, $this->requestQuery('status'));

if ($this->requestMethod() === 'GET') {
return $pages->search($this->requestQuery('q'));
}

return $pages->query($this->requestBody());
}

/**
* @throws \Kirby\Exception\NotFoundException if the section type cannot be found or the section cannot be loaded
*/
public function sectionApi(
ModelWithContent $model,
string $name,
string|null $path = null
): mixed {
if (!$section = $model->blueprint()?->section($name)) {
throw new NotFoundException(
message: 'The section "' . $name . '" could not be found'
);
}

$sectionApi = $this->clone([
'data' => [...$this->data(), 'section' => $section],
'routes' => $section->api(),
]);

return $sectionApi->call(
$path,
$this->requestMethod(),
$this->requestData()
);
}

/**
* Returns the current Session instance
*
* @param array $options Additional options, see the session component
*/
public function session(array $options = []): Session
{
return $this->kirby->session(['detect' => true, ...$options]);
}

/**
* Setter for the request data
* @return $this
Expand Down Expand Up @@ -604,6 +788,14 @@ protected function setRequestMethod(
return $this;
}

/**
* Returns the site object
*/
public function site(): Site
{
return $this->kirby->site();
}

/**
* Upload helper method
*
Expand All @@ -619,4 +811,32 @@ public function upload(
): array {
return (new Upload($this, $single, $debug))->process($callback);
}

/**
* Returns the user object for the given id or
* returns the current authenticated user if no
* id is passed
*
* @throws \Kirby\Exception\NotFoundException if the user for the given id cannot be found
*/
public function user(string|null $id = null): User|null
{
try {
return Find::user($id);
} catch (NotFoundException $e) {
if ($id === null) {
return null;
}

throw $e;
}
}

/**
* Returns the users collection
*/
public function users(): Users
{
return $this->kirby->users();
}
}
8 changes: 6 additions & 2 deletions src/Api/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ public function __construct(
null => 'null',
default => $this->data::class,
};
throw new Exception(sprintf('Invalid model type "%s" expected: "%s"', $class, $schema['type']));
throw new Exception(
message: sprintf('Invalid model type "%s" expected: "%s"', $class, $schema['type'])
);
}
}

Expand Down Expand Up @@ -218,7 +220,9 @@ public function view(string $name): static

// try to fall back to the default view at least
if (isset($this->views[$name]) === false) {
throw new Exception(sprintf('The view "%s" does not exist', $name));
throw new Exception(
message: sprintf('The view "%s" does not exist', $name)
);
}
}

Expand Down
Loading

0 comments on commit 0b338a2

Please sign in to comment.