1
0
mirror of https://github.com/flarum/core.git synced 2025-10-10 22:44:25 +02:00
Files
php-flarum/src/Extension/Extension.php
Toby Zerner b3f8379a15 Allow a single extender to be returned (#1469)
Casting an object to an array does not have the intended effect of
wrapping the object in an array. Instead we need to explicitly check
if the returned value is an array or not.
2018-06-22 18:10:54 +09:30

319 lines
6.8 KiB
PHP

<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Extension;
use Flarum\Extend\Compat;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
/**
* @property string $name
* @property string $description
* @property string $type
* @property array $keywords
* @property string $homepage
* @property string $time
* @property string $license
* @property array $authors
* @property array $support
* @property array $require
* @property array $requireDev
* @property array $autoload
* @property array $autoloadDev
* @property array $conflict
* @property array $replace
* @property array $provide
* @property array $suggest
* @property array $extra
*/
class Extension implements Arrayable
{
const LOGO_MIMETYPES = [
'svg' => 'image/svg+xml',
'png' => 'image/png',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
];
/**
* Unique Id of the extension.
*
* @info Identical to the directory in the extensions directory.
* @example flarum_suspend
*
* @var string
*/
protected $id;
/**
* The directory of this extension.
*
* @var string
*/
protected $path;
/**
* Composer json of the package.
*
* @var array
*/
protected $composerJson;
/**
* Whether the extension is installed.
*
* @var bool
*/
protected $installed = true;
/**
* The installed version of the extension.
*
* @var string
*/
protected $version;
/**
* Whether the extension is enabled.
*
* @var bool
*/
protected $enabled = false;
/**
* @param $path
* @param array $composerJson
*/
public function __construct($path, $composerJson)
{
$this->path = $path;
$this->composerJson = $composerJson;
$this->assignId();
}
/**
* Assigns the id for the extension used globally.
*/
protected function assignId()
{
list($vendor, $package) = explode('/', $this->name);
$package = str_replace(['flarum-ext-', 'flarum-'], '', $package);
$this->id = "$vendor-$package";
}
public function extend(Container $app)
{
$bootstrapper = $this->getBootstrapperPath();
if (! file_exists($bootstrapper)) {
return;
}
$extenders = require $bootstrapper;
if (! is_array($extenders)) {
$extenders = [$extenders];
}
$extenders = array_flatten($extenders);
foreach ($extenders as $extender) {
// If an extension has not yet switched to the new bootstrap.php
// format, it might return a function (or more of them). We wrap
// these in a Compat extender to enjoy an unique interface.
if ($extender instanceof \Closure || is_string($extender)) {
$extender = new Compat($extender);
}
$extender($app, $this);
}
}
/**
* {@inheritdoc}
*/
public function __get($name)
{
return $this->composerJsonAttribute(Str::snake($name, '-'));
}
/**
* {@inheritdoc}
*/
public function __isset($name)
{
return isset($this->{$name}) || $this->composerJsonAttribute(Str::snake($name, '-'));
}
/**
* Dot notation getter for composer.json attributes.
*
* @see https://laravel.com/docs/5.1/helpers#arrays
*
* @param $name
* @return mixed
*/
public function composerJsonAttribute($name)
{
return Arr::get($this->composerJson, $name);
}
/**
* @param bool $installed
* @return Extension
*/
public function setInstalled($installed)
{
$this->installed = $installed;
return $this;
}
/**
* @return bool
*/
public function isInstalled()
{
return $this->installed;
}
/**
* @param string $version
* @return Extension
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* @return string
*/
public function getVersion()
{
return $this->version;
}
/**
* Loads the icon information from the composer.json.
*
* @return array|null
*/
public function getIcon()
{
$icon = $this->composerJsonAttribute('extra.flarum-extension.icon');
$file = Arr::get($icon, 'image');
if (is_null($icon) || is_null($file)) {
return $icon;
}
$file = $this->path.'/'.$file;
if (file_exists($file)) {
$extension = pathinfo($file, PATHINFO_EXTENSION);
if (! array_key_exists($extension, self::LOGO_MIMETYPES)) {
throw new \RuntimeException('Invalid image type');
}
$mimetype = self::LOGO_MIMETYPES[$extension];
$data = base64_encode(file_get_contents($file));
$icon['backgroundImage'] = "url('data:$mimetype;base64,$data')";
}
return $icon;
}
/**
* @param bool $enabled
* @return Extension
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
return $this;
}
/**
* @return bool
*/
public function isEnabled()
{
return $this->enabled;
}
/**
* The raw path of the directory under extensions.
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getPath()
{
return $this->path;
}
public function getBootstrapperPath()
{
return "{$this->path}/bootstrap.php";
}
/**
* Tests whether the extension has assets.
*
* @return bool
*/
public function hasAssets()
{
return realpath($this->path.'/assets/') !== false;
}
/**
* Tests whether the extension has migrations.
*
* @return bool
*/
public function hasMigrations()
{
return realpath($this->path.'/migrations/') !== false;
}
/**
* Generates an array result for the object.
*
* @return array
*/
public function toArray()
{
return (array) array_merge([
'id' => $this->getId(),
'version' => $this->getVersion(),
'path' => $this->path,
'icon' => $this->getIcon(),
'hasAssets' => $this->hasAssets(),
'hasMigrations' => $this->hasMigrations(),
], $this->composerJson);
}
}