Newer
Older

narendraR
committed
<?php
namespace Drupal\project_browser\ProjectBrowser;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Unicode;

Tim Plunkett
committed
use Drupal\Component\Utility\Xss;
use Drupal\Core\Url;

Adam G-H
committed
use Drupal\project_browser\ActivationStatus;

Adam G-H
committed
use Drupal\project_browser\ProjectType;

narendraR
committed
/**
* Defines a single Project.
*/

Fran Garcia-Linares
committed
class Project implements \JsonSerializable {

narendraR
committed
/**
* A persistent ID for this project in non-volatile storage.
*
* This property is internal and should be ignored by source plugins.
*
* @var string
*
* @see \Drupal\project_browser\EnabledSourceHandler::getProjects()
*/
/**
* The ID of the source plugin which exposed this project.
*
* This property is internal and should be ignored by source plugins.
*
* @var string
*
* @see \Drupal\project_browser\EnabledSourceHandler::getProjects()
*/
public string $source;

Adam G-H
committed
/**
* The status of this project in the current site.
*
* This property is internal and should be ignored by source plugins.
*

Adam G-H
committed
* @var \Drupal\project_browser\ActivationStatus
*/
public ActivationStatus $status;
/**
* The instructions, if any, to activate this project.
*
* This property is internal and should be ignored by source plugins.
*
* @var string|\Drupal\Core\Url|null
*
* @see \Drupal\project_browser\ActivatorInterface::getInstructions()
*/
public string|Url|null $commands;

Adam G-H
committed
/**
* The project type (e.g., module, theme, recipe, or something else).
*
* @var \Drupal\project_browser\ProjectType|string
*/
public readonly ProjectType|string $type;

Fran Garcia-Linares
committed
/**

Srishti Bankar
committed
* Constructs a Project object.

Fran Garcia-Linares
committed
*

Srishti Bankar
committed
* @param array $logo
* Logo of the project.
* @param bool $isCompatible
* Whether the project is compatible with the current version of Drupal.
* @param bool $isCovered
* Whether the project is considered to be covered or not.
* @param int $projectUsageTotal
* Total usage of the project.
* @param string $machineName
* Value of project_machine_name of the project.
* @param array $body
* Body field of the project in array format.
* @param string $title
* Title of the project.
* @param array $author
* Author of the project in array format.
* @param string $packageName
* The Composer package name of this project, e.g. `drupal/project_browser`.
* @param bool $isMaintained
* Whether the project is considered to be maintained or not.
* @param \Drupal\Core\Url|null $url
* URL of the project, if any. Defaults to NULL.

Srishti Bankar
committed
* @param array $categories
* Value of module_categories of the project.
* @param array $images
* Images of the project.
* @param array $warnings
* Warnings for the project.

Adam G-H
committed
* @param string|ProjectType $type
* The project type. Defaults to a module, but may be any string that is not
* one of the cases of \Drupal\project_browser\ProjectType.
* @param string|null $id
* (optional) A local, source plugin-specific identifier for this project.
* Cannot contain slashes. Will be automatically generated if not passed.
*
* @throws \InvalidArgumentException
* Thrown if $id contains slashes.

Srishti Bankar
committed
*/
public function __construct(
public array $logo,
public bool $isCompatible,
public bool $isCovered,
public int $projectUsageTotal,
public string $machineName,
private array $body,
public string $title,
public array $author,
public string $packageName,
public bool $isMaintained = FALSE,
public ?Url $url = NULL,

Srishti Bankar
committed
public array $categories = [],
public array $images = [],
public array $warnings = [],

Adam G-H
committed
string|ProjectType $type = ProjectType::Module,
?string $id = NULL,

Srishti Bankar
committed
) {
$this->setSummary($body);

Adam G-H
committed
if (is_string($type)) {
// If the $type can't be mapped to a ProjectType case, use it as-is.
$type = ProjectType::tryFrom($type) ?? $type;
}
$this->type = $type;
// If no local ID was passed, generate it from the package name and machine
// name, which are unlikely to change.
if (empty($id)) {
$id = str_replace('/', '-', [$packageName, $machineName]);
$id = implode('-', $id);
$id = trim($id, '-');
}
if (str_contains($id, '/')) {
throw new \InvalidArgumentException("The project ID cannot contain slashes.");
}
$this->id = $id;

narendraR
committed
}
/**

Fran Garcia-Linares
committed
* Set the project short description.
*
* @param array $body
* Body in array format.

Tim Plunkett
committed
*
* @return $this

narendraR
committed
*/

Fran Garcia-Linares
committed
public function setSummary(array $body) {

Fran Garcia-Linares
committed
$this->body = $body;

Fran Garcia-Linares
committed
if (empty($this->body['summary'])) {
$this->body['summary'] = $this->body['value'] ?? '';

narendraR
committed
}

Fran Garcia-Linares
committed
$this->body['summary'] = Html::escape(strip_tags($this->body['summary']));
$this->body['summary'] = Unicode::truncate($this->body['summary'], 200, TRUE, TRUE);

Tim Plunkett
committed
return $this;

narendraR
committed
}

Narendra Singh Rathore
committed
/**
* Returns the selector id of the project.
*
* @return string
* Selector id of the project.
*/
public function getSelectorId(): string {
return str_replace('_', '-', $this->machineName);
}

Fran Garcia-Linares
committed
/**
* {@inheritdoc}
*/
public function jsonSerialize(): array {
$commands = $this->commands;
if ($commands instanceof Url) {
$commands = $commands->setAbsolute()->toString();
}
elseif (is_string($commands)) {
$commands = Xss::filter($commands, [...Xss::getAdminTagList(), 'textarea', 'button']);
}
return [

Fran Garcia-Linares
committed
'is_compatible' => $this->isCompatible,

Srishti Bankar
committed
'is_covered' => $this->isCovered,

Tim Plunkett
committed
'project_usage_total' => $this->projectUsageTotal,

Srishti Bankar
committed
'module_categories' => $this->categories,
'project_machine_name' => $this->machineName,

Tim Plunkett
committed
'project_images' => $this->images,
'logo' => $this->logo,
'body' => $this->body,

Srishti Bankar
committed
'title' => $this->title,

Tim Plunkett
committed
'author' => $this->author,
'warnings' => $this->warnings,
'package_name' => $this->packageName,
'is_maintained' => $this->isMaintained,
'url' => $this->url?->setAbsolute()->toString(),

Adam G-H
committed
'status' => match ($this->status) {
ActivationStatus::Absent => 'absent',
ActivationStatus::Present => 'present',
ActivationStatus::Active => 'active',
},

Narendra Singh Rathore
committed
'selector_id' => $this->getSelectorId(),
'commands' => $commands,
'source' => $this->source,

Fran Garcia-Linares
committed
];
}