Skip to content

Commit

Permalink
Make releasetime-templates editable, add selector
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Schendel committed Feb 13, 2019
1 parent 06ef11d commit 8053b80
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 25 deletions.
195 changes: 170 additions & 25 deletions PageAccessReleasetime.module.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<?php
namespace ProcessWire;

class PageAccessReleasetime extends WireData implements Module {
class PageAccessReleasetime extends WireData implements Module, ConfigurableModule {

const module_tags = 'Releasetime';
const fieldnames = array('releasetime_start_activate', 'releasetime_start', 'releasetime_end_activate', 'releasetime_end');
const permissionname = 'page-view-not-released';

// Add this selector to your query, to filter unreleased pages:
const selector = "or1=(releasetime_start_activate=0), or1=(releasetime_start=''), or1=(releasetime_start<=now), or2=(releasetime_end_activate=0), or2=(releasetime_end=''), or2=(releasetime_end>=now)";

public static function getModuleInfo() {
return array(
'title' => __('Page Access Releasetime'),
'version' => '1.0.1',
'version' => '1.0.2',
'summary' => __('Enables you to set a start- and end-time for the release of pages. Prevents unreleased pages from being displayed.'),
'singular' => true,
'autoload' => true,
Expand All @@ -20,7 +23,7 @@ public static function getModuleInfo() {
}

public function ___install(){
$flags = Field::flagGlobal + Field::flagSystem + Field::flagAccessAPI + Field::flagAutojoin;
$flags = Field::flagSystem + Field::flagAccessAPI + Field::flagAutojoin;

$field = new Field();
$field->type = $this->modules->get("FieldtypeCheckbox");
Expand Down Expand Up @@ -71,25 +74,90 @@ public function ___install(){
}

public function ___uninstall(){
// Remove releasetime-fields:
foreach(self::fieldnames as $fieldname){
$feld = $this->wire('fields')->get($fieldname);
if(!($feld instanceof Field) || $feld->name != $fieldname) continue;
$field = $this->wire('fields')->get($fieldname);
if(!($field instanceof Field) || $field->name != $fieldname) continue;

$feld->flags = Field::flagSystemOverride;
$feld->flags = 0;
$feld->save();
$field->flags = Field::flagSystemOverride;
$field->flags = 0;
$field->save();

foreach($this->wire('templates') as $template){
if(!$template->hasField($fieldname)) continue;
$template->fieldgroup->remove($feld);
$template->fieldgroup->remove($field);
$template->fieldgroup->save();
}

$this->wire('fields')->delete($feld);
$this->wire('fields')->delete($field);
}

// remove permission:
$permission = wire('permissions')->get(self::permissionname);
if($permission instanceof Permission && $permission->id){
$this->wire('permissions')->delete($permission);
}

}

protected static $defaults = array(
'autoAdd' => 0,
'templates' => []
);

public static function getModuleConfigInputfields(array $data) {
$form = new InputfieldWrapper();
$moduleconfig = wire('modules')->getModuleConfigData('PageAccessReleasetime');
$data = array_merge(self::$defaults, $data);

$f = new InputfieldCheckbox();
$f->attr('id+name', 'autoAdd');
$f->label = __('Mode');
$f->label2 = __('Add to all templates automatically');
$f->description = __('Enabling this feature will add the fields to every page automatically.');
$f->value = $data['autoAdd'];
$checked = isset($data['autoAdd']) && $data['autoAdd'] == '' ? '' : 'checked';
$f->attr('checked', $checked);
$form->add($f);

$f = new InputfieldAsmSelect();
$f->attr('id+name', 'templates');
$f->label = __('Templates');
$f->description = __("Select all templates that should get the releasetime fields.");
$f->showIf = 'autoAdd=0';

// Dynamically check which templates have all releasetime-fields and check them afterwards:
$templatesWithFields = array();

foreach(wire('templates') as $template) {
// Exclude system templates:
if($template->flags & Template::flagSystem) continue;
$f->addOption($template->id, $template->getLabel());

// Check, if the template already has all releasetime-fields:
$allFieldsExistFlag = true;
foreach(self::fieldnames as $fieldname){
if(!$template->hasField($fieldname)){
$allFieldsExistFlag = false;
}
}

if($allFieldsExistFlag){
$templatesWithFields[] = $template->id;
}
}

$data['templates'] = $templatesWithFields;
$f->attr('value', $data['templates']);

$form->add($f);

return $form;
}

public function init() {
$this->addHookAfter("Modules::saveConfig", $this, "hookModulesSaveConfig");

// Move releasetime-fields to settings-tab
$this->addHookAfter("ProcessPageEdit::buildForm", $this, "moveFieldToSettings");

Expand All @@ -115,7 +183,7 @@ public function init() {
* @param HookEvent $event
*
*/
public function hookPageViewable($event) {
public function hookPageViewable(HookEvent $event) {
$page = $event->object;
$viewable = $event->return;

Expand All @@ -132,10 +200,10 @@ public function hookPageViewable($event) {
*
* @see https://processwire.com/talk/topic/15622-pagefilesecure-and-pageispublic-hook-not-working/
*/
public function hookPageIsPublic($e) {
$page = $e->object;
if($e->return && $this->isReleaseTimeSet($page)) {
$e->return = false;
public function hookPageIsPublic(HookEvent $event) {
$page = $event->object;
if($event->return && $this->isReleaseTimeSet($page)) {
$event->return = false;
}
}

Expand All @@ -146,8 +214,8 @@ public function hookPageIsPublic($e) {
*
* @see https://processwire.com/talk/topic/15622-pagefilesecure-and-pageispublic-hook-not-working/
*/
public function hookProcessPageViewSendFile($e) {
$page = $e->arguments[0];
public function hookProcessPageViewSendFile(HookEvent $event) {
$page = $event->arguments[0];
if(!$this->canUserSee($page)) {
throw new Wire404Exception($this->_('File not found'));
}
Expand Down Expand Up @@ -216,24 +284,101 @@ public function isReleaseTimeSet(Page $page){
return false;
}

/**
* Adds releasetime-fields to the wanted templates after module's save
* @param HookEvent $event
*/
public function hookModulesSaveConfig(HookEvent $event){
// Get the object the event occurred on, if needed
$modules = $event->object;

$data = $event->arguments(1);

// If auto-add is activated: Make fields global
if(isset($data['autoAdd']) && $data['autoAdd']){
foreach(self::fieldnames as $fieldname){
$field = $this->wire('fields')->get($fieldname);
if(!($field instanceof Field) || $field->name != $fieldname){
continue;
}

if($field->hasFlag(Field::flagGlobal)){
// Field is already global
continue;
}

$field->addFlag(Field::flagGlobal);
$field->save();
}
return;
}

// auto-add is not activated. The fields should not be global an will be added manually.
foreach(self::fieldnames as $fieldname){
$field = $this->wire('fields')->get($fieldname);
if(!($field instanceof Field) || $field->name != $fieldname){
continue;
}

if(!$field->hasFlag(Field::flagGlobal)){
// Field is not global
continue;
}

$field->removeFlag(Field::flagGlobal);
$field->save();
}

$savedTemplates = array();
if(isset($data['templates']) && is_array($data['templates'])){
$savedTemplates = $data['templates'];
}

foreach(wire('templates') as $template){
if(array_search($template->id, $savedTemplates) !== false){

// Fields should be added
foreach(self::fieldnames as $fieldname){
if($template->hasField($fieldname)){
// Field is already there
continue;
}

$template->fieldgroup->add($fieldname);
$template->fieldgroup->save();
}
continue;
}

// Fields should be removed
foreach(self::fieldnames as $fieldname){
if(!$template->hasField($fieldname)){
// Field was not added
continue;
}

$template->fieldgroup->remove($fieldname);
$template->fieldgroup->save();
}
}
}

/**
* Moves the releasetime-fields to the settings-tab
* @param HookEvent $event
*/
public function moveFieldToSettings(HookEvent $event) {
$form = $event->return;

$settings = $form->find("id=ProcessPageEditSettings")->first();
if(!$settings) return;

foreach(self::fieldnames as $fieldname){
$field = $form->find("name=".$fieldname)->first();
if(!$field) continue;

if($field) {
$settings = $form->find("id=ProcessPageEditSettings")->first();

if($settings) {
$form->remove($field);
$settings->append($field);
}
}
$form->remove($field);
$settings->append($field);
}
}

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ Additionally we hook into `ProcessPageEdit::buildForm` to add the PageAccessRele
## Limitations
In the current version, releasetime-protected pages will appear in `wire('pages')->find()` queries. If you want to display a list of pages, where pages could be releasetime-protected, you should double-check with `$page->viewable()` wether the page can be accessed. `$page->viewable()` returns false, if the page is not released yet.

To filter unreleased pages, add the `PageAccessReleasetime::selector` to your selector:

```php
$onlyReleasedPages = wire('pages')->find('template.name=news, ' . PageAccessReleasetime::selector);
```

If you have an idea how unreleased pages can be filtered out of ProcessWire selector queries, feel free to write an issue, comment or make a pull request!

## Versioning
Expand Down

0 comments on commit 8053b80

Please sign in to comment.