Skip to content

Commit

Permalink
Merge pull request #467 from JohnXLivingston/feature_styling_plugins
Browse files Browse the repository at this point in the history
New Styling plugin
  • Loading branch information
effgarces authored Dec 24, 2024
2 parents 4921b01 + 8bc7c8f commit 584376b
Show file tree
Hide file tree
Showing 20 changed files with 225 additions and 3 deletions.
22 changes: 22 additions & 0 deletions Domain/ReservationItemView.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ public function GetTextColor();
*/
public function GetBorderColor();

/**
* @return string[]
*/
public function GetAdditonalCSSClasses();

/**
* @return string
*/
Expand Down Expand Up @@ -403,6 +408,11 @@ class ReservationItemView implements IReservedItemView

private $ownerGroupIds = [];

/**
* @var StylingFactory
*/
private $StylingFactory;

/**
* @param $referenceNumber string
* @param $startDate Date
Expand Down Expand Up @@ -522,6 +532,8 @@ public function __construct(

$this->Attributes = CustomAttributes::Parse($attribute_list);
$this->UserPreferences = UserPreferences::Parse($preferences);

$this->StylingFactory= PluginManager::Instance()->LoadStyling();
}

/**
Expand Down Expand Up @@ -990,6 +1002,11 @@ public function GetBorderColor()
return '';
}

public function GetAdditonalCSSClasses()
{
return $this->StylingFactory->GetReservationAdditonalCSSClasses($this) ?? [];
}

public function GetTitle()
{
return $this->Title;
Expand Down Expand Up @@ -1285,6 +1302,11 @@ public function GetBorderColor()
return '';
}

public function GetAdditonalCSSClasses()
{
return [];
}

public function GetTitle()
{
return $this->Title;
Expand Down
9 changes: 9 additions & 0 deletions Pages/Admin/ManageConfigurationPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ public function SetPreReservationPluginValues($values);
*/
public function SetPostReservationPluginValues($values);

/**
* @param string[] $values
*/
public function SetStylingPluginValues($values);

/**
* @return int
*/
Expand Down Expand Up @@ -253,6 +258,10 @@ public function SetPostReservationPluginValues($values)
{
$this->Set('PostReservationPluginValues', $values);
}
public function SetStylingPluginValues($values)
{
$this->Set('StylingPluginValues', $values);
}

public function GetHomePageId()
{
Expand Down
5 changes: 5 additions & 0 deletions Pages/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ protected function __construct($titleKey = '', $pageDepth = 0)
$this->smarty->assign('CssUrl', 'custom-style.css');
}

$stylingFactory = PluginManager::Instance()->LoadStyling();
if (!empty($stylingFactory->AdditionalCSS($userSession))) {
$this->smarty->assign('CssStylingFile', 'styling-plugin.php');
}

$this->smarty->assign('FaviconUrl', 'favicon.ico');
if (file_exists($this->path . 'custom-favicon.png')) {
$this->smarty->assign('FaviconUrl', 'custom-favicon.png');
Expand Down
36 changes: 36 additions & 0 deletions Pages/StylingPluginPage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

// debugging tools / libs
if (file_exists(ROOT_DIR . 'vendor/autoload.php')) {
require ROOT_DIR . 'vendor/autoload.php';
}

require_once(ROOT_DIR . 'lib/Common/namespace.php');

interface IStylingPluginPage
{
public function PageLoad();
}

class StylingPluginPage implements IStylingPluginPage
{
public function PageLoad()
{
$userSession = ServiceLocator::GetServer()->GetUserSession();

header('Content-type: text/css');
$factory = PluginManager::Instance()->LoadStyling();
$path = $factory->AdditionalCSS($userSession);
if (empty($path)) {
http_response_code(200);
die();
}
if (!file_exists($path)) {
http_response_code(404);
die();
}
http_response_code(200);
readfile($path);
die();
}
}
1 change: 1 addition & 0 deletions Presenters/Admin/ManageConfigurationPresenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ private function PopulatePlugins()
$this->page->SetPostRegistrationPluginValues($plugins['PostRegistration']);
$this->page->SetPreReservationPluginValues($plugins['PreReservation']);
$this->page->SetPostReservationPluginValues($plugins['PostReservation']);
$this->page->SetStylingPluginValues($plugins['Styling']);
}

public function Update()
Expand Down
8 changes: 8 additions & 0 deletions Web/css/styling-plugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

define('ROOT_DIR', '../../');

require_once(ROOT_DIR . 'Pages/StylingPluginPage.php');

$page = new StylingPluginPage();
$page->PageLoad();
8 changes: 5 additions & 3 deletions Web/scripts/schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ function Schedule(opts, resourceGroups) {
const past = reservation.IsPast ? "past" : "";
const participant = reservation.IsParticipant ? "participating" : "";
const isPending = reservation.IsPending ? "pending" : "";
const additonalCSSClasses = reservation.AdditonalCSSClasses ? reservation.AdditonalCSSClasses.join(" ") : "";
const isNew = reservation.IsNew ? `<span class="reservation-new">${opts.newLabel}</span>` : "";
const isUpdated = reservation.IsUpdated ? `<span class="reservation-updated">${opts.updatedLabel}</span>` : "";
const isDraggable = reservation.IsReservation && ((reservation.IsOwner && !reservation.IsPast) || reservation.IsAdmin);
Expand All @@ -284,7 +285,7 @@ function Schedule(opts, resourceGroups) {
let color = reservation.BackgroundColor !== "" ? `background-color:${reservation.BackgroundColor};color:${reservation.TextColor};` : "";
const style = `left:${left}px; top:${top}px; width:${width}px; height:${divHeight}px;`;
const div = $(`<div
class="${className} ${mine} ${past} ${participant} ${isPending} event"
class="${className} ${mine} ${past} ${participant} ${isPending} ${additonalCSSClasses} event"
style="${style} ${color}"
data-resid="${reservation.ReferenceNumber}"
data-resourceid="${reservation.ResourceId}"
Expand Down Expand Up @@ -465,6 +466,7 @@ function Schedule(opts, resourceGroups) {
const isNew = res.IsNew ? `<span class="reservation-new">${opts.newLabel}</span>` : "";
const isUpdated = res.IsUpdated ? `<span class="reservation-updated">${opts.updatedLabel}</span>` : "";
const isPending = res.IsPending ? "pending" : "";
const additonalCSSClasses = res.AdditonalCSSClasses ? res.AdditonalCSSClasses.join(" ") : "";
const isDraggable = res.IsReservation && ((res.IsOwner && !res.IsPast) || res.IsAdmin);
const draggableAttribute = isDraggable ? 'draggable="true"' : "";
let color = res.BackgroundColor !== "" ? `background-color:${res.BackgroundColor};color:${res.TextColor};` : "";
Expand All @@ -483,7 +485,7 @@ function Schedule(opts, resourceGroups) {
let startTime = startsBefore ? opts.midnightLabel : res.StartTime;
let endTime = endsAfter ? opts.midnightLabel : res.EndTime;
const div = $(`<div
class="${className} ${mine} ${past} ${participant} ${isPending} condensed-event"
class="${className} ${mine} ${past} ${participant} ${isPending} ${additonalCSSClasses} condensed-event"
style="${color}"
data-resid="${res.ReferenceNumber}">
<span>${startTime}-${endTime}</span>
Expand Down Expand Up @@ -634,7 +636,7 @@ function Schedule(opts, resourceGroups) {
}
const style = `left:${left}px; top:${top}px; width:${width}px; height:${divHeight}px;`;
const div = $(`<div
class="${className} ${mine} ${past} ${participant} ${isPending} event"
class="${className} ${mine} ${past} ${participant} ${isPending} ${additonalCSSClasses} event"
style="${style} ${color}"
data-resid="${res.ReferenceNumber}"
data-resourceid="${res.ResourceId}"
Expand Down
1 change: 1 addition & 0 deletions config/config.devel.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
$conf['settings']['plugins']['PostRegistration'] = '';
$conf['settings']['plugins']['PreReservation'] = '';
$conf['settings']['plugins']['PostReservation'] = '';
$conf['settings']['plugins']['Styling'] = '';
/**
* Installation settings
*/
Expand Down
1 change: 1 addition & 0 deletions config/config.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
$conf['settings']['plugins']['PostRegistration'] = '';
$conf['settings']['plugins']['PreReservation'] = '';
$conf['settings']['plugins']['PostReservation'] = '';
$conf['settings']['plugins']['Styling'] = '';
/**
* Installation settings
*/
Expand Down
10 changes: 10 additions & 0 deletions lib/Application/Schedule/ReservationListItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ public function GetBorderColor()
return $this->item->GetBorderColor();
}

public function GetAdditonalCSSClasses()
{
return $this->item->GetAdditonalCSSClasses() ?? [];
}

/**
* @return string
*/
Expand Down Expand Up @@ -209,6 +214,7 @@ public function AsDto($currentUser)
$dto->BorderColor = $this->GetBorderColor();
$dto->BackgroundColor = $this->GetColor();
$dto->TextColor = $this->GetTextColor();
$dto->AdditonalCSSClasses = $this->GetAdditonalCSSClasses();
$dto->IsReservation = $this->IsReservation();
$dto->IsBuffered = false;
$dto->IsBuffer = false;
Expand Down Expand Up @@ -516,4 +522,8 @@ class ReservationListItemDto
* @var string|null
*/
public $BufferedEndTime;
/**
* @var string[]
*/
public $AdditonalCSSClasses;
}
5 changes: 5 additions & 0 deletions lib/Application/Schedule/ReservationSlot.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ public function BorderColor()
return $this->_reservation->GetBorderColor();
}

public function GetAdditonalCSSClasses()
{
return $this->_reservation->GetAdditonalCSSClasses() ?? [];
}

/**
* @return ReservationItemView
*/
Expand Down
45 changes: 45 additions & 0 deletions lib/Application/Styling/StylingFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

interface IStylingFactory
{
/**
* Returns a file path (on the server) to an additional CSS file to use.
* @param UserSession $userSession
* @return null|string
*/
public function AdditionalCSS(UserSession $userSession);

/**
* You can add some CSS classes to reservations items.
* Those classes can for example depends on some attributes.
* @param IReservedItemView $item
* @return string[]
*/
public function GetReservationAdditonalCSSClasses(IReservedItemView $item);
}

class StylingFactory implements IStylingFactory
{
public function __construct() {}

/**
* Returns a file path (on the server) to an additional CSS file to use.
* @param UserSession $userSession
* @return null|string
*/
public function AdditionalCSS(UserSession $userSession)
{
return null;
}

/**
* You can add some CSS classes to reservations items.
* Those classes can for example depends on some attributes.
* @param IReservedItemView $item
* @return string[]
*/
public function GetReservationAdditonalCSSClasses(IReservedItemView $item)
{
return [];
}
}
3 changes: 3 additions & 0 deletions lib/Application/Styling/namespace.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

require_once(ROOT_DIR . 'lib/Application/Styling/StylingFactory.php');
21 changes: 21 additions & 0 deletions lib/Common/PluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,27 @@ public function LoadPostRegistration()
return $postRegistration;
}

/**
* Loads the configured Styling plugin, if one exists
* If no plugin exists, the default PreReservationFactory class is returned
*
* @return IPreReservationFactory
*/
public function LoadStyling()
{
require_once(ROOT_DIR . 'lib/Application/Styling/namespace.php');

$factory = new StylingFactory();

$plugin = $this->LoadPlugin(ConfigKeys::PLUGIN_STYLING, 'Styling', $factory);

if (!is_null($plugin)) {
return $plugin;
}

return $factory;
}

/**
* @param string $configKey key to use
* @param string $pluginSubDirectory subdirectory name under 'plugins'
Expand Down
1 change: 1 addition & 0 deletions lib/Config/ConfigKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class ConfigKeys
public const PLUGIN_POSTREGISTRATION = 'PostRegistration';
public const PLUGIN_PRERESERVATION = 'PreReservation';
public const PLUGIN_POSTRESERVATION = 'PostReservation';
public const PLUGIN_STYLING = 'Styling';

public const RESERVATION_START_TIME_CONSTRAINT = 'start.time.constraint';
public const RESERVATION_UPDATES_REQUIRE_APPROVAL = 'updates.require.approval';
Expand Down
7 changes: 7 additions & 0 deletions plugins/Styling/StylingExample/StylingExample.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
table.reservations .reserved.mine {
background-color: red;
}

.custom-example-class {
border: 2px dotted orange;
}
30 changes: 30 additions & 0 deletions plugins/Styling/StylingExample/StylingExample.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

class StylingExample implements IStylingFactory
{
/**
* @var StylingFactory
*/
private $factoryToDecorate;

public function __construct(StylingFactory $factoryToDecorate)
{
$this->factoryToDecorate = $factoryToDecorate;
}

public function AdditionalCSS(UserSession $userSession)
{
return realpath(__DIR__ . DIRECTORY_SEPARATOR . 'StylingExample.css');
}

public function GetReservationAdditonalCSSClasses(IReservedItemView $item)
{
$additionalCSSClasses = $this->factoryToDecorate->GetReservationAdditonalCSSClasses($item) ?? [];

if (str_starts_with($item->GetTitle(), 'Example')) {
$additionalCSSClasses[] = 'custom-example-class';
}

return $additionalCSSClasses;
}
}
8 changes: 8 additions & 0 deletions tests/Presenters/Admin/ManageConfigurationPresenterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ public function SetPostReservationPluginValues($values)
// TODO: Implement SetPostReservationPluginValues() method.
}

/**
* @param string[] $values
*/
public function SetStylingPluginValues($values)
{
// TODO: Implement SetStylingPluginValues() method.
}

/**
* @return int
*/
Expand Down
4 changes: 4 additions & 0 deletions tpl/Admin/Configuration/manage_configuration.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
<select id="{$name}" name="{$name}" class="form-select">
{html_options values=$PostReservationPluginValues output=$PostReservationPluginValues selected=$setting->Value}
</select>
{elseif $setting->Key == ConfigKeys::PLUGIN_STYLING}
<select id="{$name}" name="{$name}" class="form-select">
{html_options values=$StylingPluginValues output=$StylingPluginValues selected=$setting->Value}
</select>
{elseif $setting->Type == ConfigSettingType::String}
<input id="{$name}" type="text" size="50" name="{$name}" value="{$setting->Value|escape}"
class="form-control" />
Expand Down
Loading

0 comments on commit 584376b

Please sign in to comment.