Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<?php
namespace Pycraft\PycraftModule\Ui\ControlPanel\Command;
use Anomaly\Streams\Platform\Support\Authorizer;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\Command\BuildNavigation;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\Contract\NavigationLinkInterface;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Section\SectionFactory;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Section\SectionInput;
use Anomaly\Streams\Platform\Ui\ControlPanel\ControlPanel;
use Anomaly\Streams\Platform\Ui\ControlPanel\ControlPanelBuilder;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Contracts\Container\Container;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Support\Collection;
use Pycraft\PycraftModule\Ui\ControlPanel\NavigationCollection;
use Pycraft\PycraftModule\Ui\ControlPanel\NavigationItem;
class BuildFullControlPanelNavigation
{
use DispatchesJobs;
/** @var \Illuminate\Support\Collection */
protected $menu;
/** @var \Illuminate\Contracts\Container\Container */
protected $container;
/** @var Authorizer */
protected $authorizer;
/** @var ControlPanel */
protected $cp;
/** @var \Anomaly\Streams\Platform\Addon\Module\ModuleCollection */
protected $modules;
/** @var SectionInput */
protected $input;
/** @var SectionFactory */
protected $factory;
/** @var Collection */
protected $items;
/** @var Repository */
protected $cache;
public function __construct(NavigationCollection $menu)
{
$this->menu = $menu;
if ( ! Collection::hasMacro('reset')) {
Collection::macro('reset', function () {
$this->items = [];
return $this;
});
}
}
public function handle(Container $container, Repository $cache, Authorizer $authorizer, ControlPanelBuilder $builder, SectionInput $input, SectionFactory $factory)
{
$this->container = $container;
$this->cache = $cache;
$this->authorizer = $authorizer;
$this->input = $input;
$this->factory = $factory;
$this->modules = $container->make('module.collection');
$this->cp = $builder->getControlPanel();
$this->dispatch(new BuildNavigation($builder));
/* @var NavigationLinkInterface $link */
foreach ($builder->getControlPanelNavigation() as $link) {
if ( ! $authorizer->authorize($link->getPermission())) {
continue;
}
$this->handleLink($link);
}
}
protected function handleLink(NavigationLinkInterface $link)
{
if($this->menu->get($link->getSlug(), null) !== null){
return;
}
$builder = $this->container->make(ControlPanelBuilder::class);
$this->dispatch(new BuildNavigation($builder));
$link->setActive(true);
$module = $this->modules->get($link->getSlug());
$module->setActive(true);
try {
$this->input->read($builder);
}
catch (\ErrorException $e) {
}
$sections = $builder->getSections();
foreach ($sections as $section) {
if ( ! $this->authorizer->authorize(array_get($section, 'permission'))) {
continue;
}
$this->cp->addSection($this->factory->make($section));
}
$module->setActive(false);
$link->setActive(false);
$this->menu->push(new NavigationItem($link, $module, $this->cp->getSections()->all()));
$this->cp->getSections()->reset();
$builder->setSections([]);
}
}
<?php
namespace Pycraft\PycraftModule\Ui\ControlPanel;
use Anomaly\Streams\Platform\Addon\Module\Module;
use Anomaly\Streams\Platform\View\Event\TemplateDataIsLoading;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Support\ServiceProvider;
use Pycraft\PycraftModule\Ui\ControlPanel\Command\BuildFullControlPanelNavigation;
class ControlPanelServiceProvider extends ServiceProvider
{
use DispatchesJobs;
/**
* boot method
*
* @return void
* @throws \Exception
*/
public function boot()
{
if ( $this->isAdminUrl()) {
if (config('pycraft.module.pycraft::cp.replace_sidebar', false)) {
$this->replaceControlPanelSidebar();
}
}
}
protected function isAdminUrl()
{
return starts_with(url()->current(), url()->to('admin'));
}
/**
* replaceAdminMenu method
*
* @return void
* @throws \Exception
*/
protected function replaceControlPanelSidebar()
{
$this->app->make('events')->listen(TemplateDataIsLoading::class, function (TemplateDataIsLoading $event) {
debugbar()->startMeasure('BuildFullControlPanelNavigation');
$cache = $this->app->make('cache.store');
$modifiedCheckStr = md5($this->app->make('module.collection')->enabled()->transform(function (Module $module) {
return $module->getSlug();
})->implode('_'));
$modifiedCheckStrCached = $cache->get('pycraft.module.pycraft::BuildFullControlPanelNavigation.modifiedCheck');
// refresh cached menu
if ($modifiedCheckStr !== $modifiedCheckStrCached || ! $cache->has('pycraft.module.pycraft::BuildFullControlPanelNavigation')) {
$cache->forever('pycraft.module.pycraft::BuildFullControlPanelNavigation.modifiedCheck', $modifiedCheckStr);
$menu = $cache->rememberForever('pycraft.module.pycraft::BuildFullControlPanelNavigation', function () {
$menu = new NavigationCollection;
$this->dispatch(new BuildFullControlPanelNavigation($menu));
return $menu;
});
} else {
$menu = $cache->get('pycraft.module.pycraft::BuildFullControlPanelNavigation');
}
$template = $event->getTemplate();
// workaround bug fix
$menu = $menu->filter(function (NavigationItem $item) {
$isArray = false;
$item->getSections()->each(function (NavigationItemChild $section) use ($item, &$isArray) {
$title = $section->getTitle();
if (is_array($title)) {
$isArray = true;
}
});
return $isArray === false;
});
$template->set('admin_menu', $menu);
debugbar()->stopMeasure('BuildFullControlPanelNavigation');
});
}
}
<?php
namespace Pycraft\PycraftModule\Ui\ControlPanel;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\Contract\NavigationLinkInterface;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\NavigationLink;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Section\Section;
use Illuminate\Support\Collection;
class NavigationCollection extends Collection implements \Serializable
{
/**
* Get a navigation link.
*
* @param mixed $key
* @param null $default
*
* @return \Pycraft\PycraftModule\Ui\ControlPanel\NavigationItem
*/
public function get($key, $default = null)
{
/* @var \Pycraft\PycraftModule\Ui\ControlPanel\NavigationItem $item */
foreach ($this->items as $item) {
if ($item->getSlug() == $key) {
return $item;
}
}
return $default ? $this->get($default) : null;
}
/**
* String representation of object
*
* @link http://php.net/manual/en/serializable.serialize.php
* @return string the string representation of the object or null
* @since 5.1.0
*/
public function serialize()
{
return $this->toJson();
}
/**
* Constructs the object
*
* @link http://php.net/manual/en/serializable.unserialize.php
*
* @param string $serialized <p>
* The string representation of the object.
* </p>
*
* @return void
* @since 5.1.0
*/
public function unserialize($serialized)
{
$modules = app()->make('module.collection');
$items = json_decode($serialized, true);
foreach($items as $item) {
$navLink = app()->make(NavigationLink::class);
foreach($item as $key => $value){
$method = 'set'.ucfirst($key);
if(method_exists($navLink, $method)){
$navLink->$method($value);
}
}
$sections = collect($item['sections'])->transform(function($data){
$section = new Section();
foreach($data as $key => $value){
$method = 'set'.ucfirst($key);
if(method_exists($section, $method)){
$section->$method($value);
}
}
return $section;
})->all();
$this->push(new NavigationItem($navLink, $modules->get($item['module']['id']), $sections));
}
$a = 'a';
}
}
<?php
namespace Pycraft\PycraftModule\Ui\ControlPanel;
use Anomaly\Streams\Platform\Addon\Module\Module;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\Contract\NavigationLinkInterface;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\NavigationLink;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Section\Section;
use Illuminate\Contracts\Support\Arrayable;
class NavigationItem extends NavigationLink implements Arrayable
{
/** @var \Illuminate\Support\Collection|\Pycraft\PycraftModule\Ui\ControlPanel\NavigationItemChild[] */
protected $sections;
/** @var \Anomaly\Streams\Platform\Addon\Module\Module */
protected $module;
/**
* NavigationMenuItem constructor.
*
* @param \Anomaly\Streams\Platform\Ui\ControlPanel\Component\Navigation\Contract\NavigationLinkInterface $link
* @param \Anomaly\Streams\Platform\Addon\Module\Module $module
* @param \Illuminate\Support\Collection|\Pycraft\PycraftModule\Ui\ControlPanel\NavigationItemChild[] $sections
*/
public function __construct(NavigationLinkInterface $link, Module $module, array $sections)
{
parent::__construct($link->image, $link->asset);
$this->module = $module;
$this->sections = collect($sections)->transform(function (Section $section) {
return new NavigationItemChild($section);
});
foreach (get_class_vars(NavigationLink::class) as $key => $value) {
if ($key === 'image' || $key === 'asset') {
continue;
}
$this->{$key} = $link->{$key};
}
}
/**
* getSections method
*
* @return \Illuminate\Support\Collection|\Pycraft\PycraftModule\Ui\ControlPanel\NavigationItemChild[]
*/
public function getSections()
{
return $this->sections;
}
/**
* setSections method
*
* @param $sections
*
* @return $this
*/
public function setSections($sections)
{
$this->sections = $sections;
return $this;
}
/**
* @return \Anomaly\Streams\Platform\Addon\Module\Module
*/
public function getModule()
{
return $this->module;
}
/**
* Set the module value
*
* @param \Anomaly\Streams\Platform\Addon\Module\Module $module
*
* @return NavigationItem
*/
public function setModule($module)
{
$this->module = $module;
return $this;
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
$data = [];
foreach (get_class_vars(static::class) as $key => $val) {
if ($key === 'image' || $key === 'asset') {
continue;
}
$value = $this->{$key};
if ($value instanceof Arrayable) {
$value = $value->toArray();
} elseif($key === 'title'){
// $value = trans($value);
}
$data[ $key ] = $value;
}
return $data;
}
}
<?php
namespace Pycraft\PycraftModule\Ui\ControlPanel;
use Anomaly\Streams\Platform\Ui\ControlPanel\Component\Section\Section;
use Illuminate\Contracts\Support\Arrayable;
class NavigationItemChild extends Section implements Arrayable
{
public function __construct(Section $section)
{
foreach ($this->getClassKeys() as $key) {
$this->{$key} = $section->{$key};
}
}
private function getClassKeys()
{
return array_except(array_keys(get_class_vars(Section::class)), [ 'buttons', 'parent' ]);
}
public function toArray()
{
$data = [];
foreach ($this->getClassKeys() as $key) {
$value = $this->{$key};
if($key === 'title'){
// $value = trans($value);
}
$data[ $key ] = $value;
}
return $data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment