Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions controllers/AjaxController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php
/**
* The Simple Pages Ajax controller class.
*
* @package SimplePages
*/
class SimplePages_AjaxController extends Omeka_Controller_AbstractActionController
{
/**
* Controller-wide initialization. Sets the underlying model to use.
*/
public function init()
{
// Don't render the view script.
$this->_helper->viewRenderer->setNoRender(true);

$this->_helper->db->setDefaultModelName('SimplePagesPage');
}

/**
* Handle AJAX requests to update a simple page.
*/
public function updateAction()
{
if (!$this->_checkAjax('update')) {
return;
}

// Handle action.
try {
$status = $this->_getParam('status');
if (!in_array($status, array('public', 'private'))) {
$this->getResponse()->setHttpResponseCode(400);
return;
}

$id = (integer) $this->_getParam('id');
$simplePage = $this->_helper->db->find($id);
if (!$simplePage) {
$this->getResponse()->setHttpResponseCode(400);
return;
}
$simplePage->is_published = ($status == 'public');
$simplePage->save();
} catch (Exception $e) {
$this->getResponse()->setHttpResponseCode(500);
}
}

/**
* Handle AJAX requests to delete a simple page.
*/
public function deleteAction()
{
if (!$this->_checkAjax('delete')) {
return;
}

// Handle action.
try {
$id = (integer) $this->_getParam('id');
$simplePage = $this->_helper->db->find($id);
if (!$simplePage) {
$this->getResponse()->setHttpResponseCode(400);
return;
}
$simplePage->delete();
} catch (Exception $e) {
$this->getResponse()->setHttpResponseCode(500);
}
}

/**
* Handle AJAX requests to change a list of simple pages.
*/
public function changeAction()
{
if (!$this->_checkAjax('change')) {
return;
}

// Handle action.
try {
$remove = $this->_getParam('remove');
$remove = $remove ?: array();
if (!is_array($remove)) {
$this->getResponse()->setHttpResponseCode(400);
return;
}

$order = $this->_getParam('order');
if (!is_array($order) || empty($order)) {
$this->getResponse()->setHttpResponseCode(400);
return;
}

// Secure and normalize order.
$newOrder = array();
// Remove root.
unset($order[0]);
foreach ($order as $input) {
$newOrder[(integer) $input['id']] = (integer) $input['parent_id'];
}

// Delete pages to remove and update order array.
foreach ($remove as $id) {
$id = (integer) $id;
$simplePage = $this->_helper->db->find($id);
if (!$simplePage) {
$this->getResponse()->setHttpResponseCode(400);
return;
}
// Remove deleted pages from new order and attach children to
// new parent.
$newParentId = $newOrder[$id];
unset($newOrder[$id]);
foreach ($newOrder as &$parentId) {
if ($parentId == $id) {
$parentId = $newParentId;
}
}
$simplePage->delete();
}

// Reorder pages if needed.
simple_pages_update_order($newOrder);
} catch (Exception $e) {
$this->getResponse()->setHttpResponseCode(500);
}
}

/**
* Check AJAX requests.
*
* 400 Bad Request
* 403 Forbidden
* 500 Internal Server Error
*
* @param string $action
*/
protected function _checkAjax($action)
{
// Only allow AJAX requests.
$request = $this->getRequest();
if (!$request->isXmlHttpRequest()) {
$this->getResponse()->setHttpResponseCode(403);
return false;
}

// Allow only valid calls.
if ($request->getControllerName() != 'ajax'
|| $request->getActionName() != $action
) {
$this->getResponse()->setHttpResponseCode(400);
return false;
}

// Allow only allowed users.
if (!is_allowed('SimplePages_Page', $action)) {
$this->getResponse()->setHttpResponseCode(403);
return false;
}

return true;
}
}
94 changes: 84 additions & 10 deletions helpers/SimplePageFunctions.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,42 @@ function simple_pages_display_breadcrumbs($pageId = null, $seperator=' > ', $inc
return $html;
}

function simple_pages_display_hierarchy($parentPageId = 0, $partialFilePath = 'index/browse-hierarchy-page.php')
/**
* Recursively list the pages under a page for editing.
*
* @param SimplePage $page A page to list.
* @return string
*/
function simple_pages_edit_page_list($page)
{
$html = '';
$childrenPages = get_db()->getTable('SimplePagesPage')->findChildrenPages($parentPageId);
if (count($childrenPages)) {
$html = '<li class="page" id="page_' . $page->id . '">';
$html .= '<div class="sortable-item">';
$html .= sprintf('<a href="%s">%s</a>', html_escape(record_url($page)), html_escape($page->title));
$html .= ' (' . html_escape($page->slug) . ')';
$html .= '<ul class="action-links group">';
$html .= '<li>' . sprintf('<a href="%s" id="simplepage-%s" class="simplepage toggle-status status %s">%s</a>',
ADMIN_BASE_URL,
$page->id,
($page->is_published ? 'public' : 'private'),
($page->is_published ? __('Published') : __('Private'))) . '</li>';
$html .= '<li>' . link_to($page, 'edit', __('Edit'), array('class' => 'edit')) . '</li>';
$html .= '</ul>';
$html .= '<br />';
$html .= __('<strong>%1$s</strong> on %2$s',
html_escape(metadata($page, 'modified_username')),
html_escape(format_date(metadata($page, 'updated'), Zend_Date::DATETIME_SHORT)));
$html .= '<a class="delete-toggle delete-element" href="#">' . __('Delete') . '</a>';
$html .= '</div>';

$childrenPages = $page->getChildren();
if (count($childrenPages)) {
$html .= '<ul>';
foreach($childrenPages as $childPage) {
$html .= '<li>';
$html .= get_view()->partial($partialFilePath, array('simple_pages_page' => $childPage));
$html .= simple_pages_display_hierarchy($childPage->id, $partialFilePath);
$html .= '</li>';
foreach ($childrenPages as $childPage) {
$html .= simple_pages_edit_page_list($childPage);
}
$html .= '</ul>';
}
$html .= '</li>';
return $html;
}

Expand Down Expand Up @@ -171,4 +193,56 @@ function simple_pages_get_parent_options($page)
}
}
return $valuePairs;
}
}

/**
* Update orders of all simple pages that have been modified.
*/
function simple_pages_update_order($newOrder)
{
$db = get_db();
$table = $db->SimplePagesPage;

// Pages are ordered by order, then by title, so two passes are needed.

// First step: update parent if needed.
$sql = "SELECT `id`, `parent_id` FROM `$table` ORDER BY `order` ASC, `title` ASC";
$currentOrder = $db->fetchPairs($sql);

foreach ($newOrder as $id => $parentId) {
if ($currentOrder[$id] != $parentId) {
$db->update($table,
array('parent_id' => $parentId),
'id = ' . $id);
// Update old hierarchy for next step.
$currentOrder[$id] = $parentId;
}
}

// Second step: update order if needed for each sibling.
// For each parent, check if current children are ordered as new ones.
while (!empty($newOrder)) {
$parentId = reset($newOrder);

// Get all current and new pages with this parent.
$currentChildren = array_intersect($currentOrder, array($parentId));
$newChildren = array_intersect($newOrder, array($parentId));

// Compare them and update all values if they are different.
// Orders are compared as csv because no function allows to check order.
if (implode(',', array_keys($currentChildren)) != implode(',', array_keys($newChildren))) {
// Order by 10 for easier insert and update of edited pages.
$order = 10;
foreach ($newChildren as $id => $parentId) {
$db->update($table,
array('order' => $order),
'id = ' . $id);
$order += 10;
}
}

// Remove filtered keys before loop.
$currentOrder = array_diff_key($currentOrder, $currentChildren);
$newOrder = array_diff_key($newOrder, $newChildren);
}
}
51 changes: 51 additions & 0 deletions views/admin/css/simple-pages.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.simplepages-list {
padding: 0;
margin: 0;
}
.simplepages-list li {
list-style: none outside none;
padding-left: 10px;
display: inline-block;
font-family: "Arvo",serif;
margin: 0;
padding: 4px 4px 4px 4px;
}
a.simplepage.status {
position:relative;
padding-left: 20px;
cursor: pointer;
}
a.simplepage.toggle-status.public {
background: url('../../../../../application/views/scripts/images/silk-icons/tick.png') no-repeat scroll 0 0 transparent;
}
a.simplepage.toggle-status.private {
background: url('../../../../../application/views/scripts/images/silk-icons/error.png') no-repeat scroll 0 0 transparent;
}
a.simplepage.transmit {
background: url('../../shared/images/waiting-mini.gif') no-repeat scroll 0 0 transparent !important;
}
.action {
color: #338899;
cursor: pointer;
}
.instructions {
font-size:11px;
color: #888;
clear: both;
}
/* override for core's .undo-delete hiding */
#page-list .undo-delete {
display: inline;
}
#page-list .page ul {
margin-top: 15px;
}
#page-list ul.action-links {
margin-top: 0;
}
#page-list ul.action-links li {
margin-bottom: 0;
}
#page-list ul.action-links li a.edit {
padding-left: 3px;
}
21 changes: 0 additions & 21 deletions views/admin/index/browse-hierarchy-page.php

This file was deleted.

19 changes: 17 additions & 2 deletions views/admin/index/browse-hierarchy.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
<?php
$topPages = get_db()->getTable('SimplePagesPage')->findChildrenPages(0, false);
?>
<p class="instructions"><?php
echo ' ' . __('To delete, reorder or nest pages, click and drag a page to the preferred location, then click the update button.');
echo ' ' . __('To publish or unpublish a page, click on the icon (change is immediate).');
?></p>
<div id="page-hierarchy">
<?php echo simple_pages_display_hierarchy(0); ?>
</div>
<div id="pages-list-container">
<ul id="page-list" class="sortable" href="<?php echo ADMIN_BASE_URL; ?>">
<?php
foreach($topPages as $page):
echo simple_pages_edit_page_list($page);
endforeach;
?>
</ul>
</div>
</div>
Loading