Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

Commit

Permalink
Added the getrandom User API method to fetch random pubs from a pubty…
Browse files Browse the repository at this point in the history
…pe. Closes #58, #113.

The RandomPub and RandomList blocks are examples of using the new method,
working with the same standards as list and display methods.
  • Loading branch information
matheo committed Oct 7, 2012
1 parent 0b54985 commit 219e338
Show file tree
Hide file tree
Showing 7 changed files with 644 additions and 3 deletions.
167 changes: 166 additions & 1 deletion src/modules/Clip/lib/Clip/Api/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ public function get($args)
$query->where('id = ?', $args['id']);
} else {
$query->where('core_pid = ?', $args['pid'])
->orderBy('core_language DESC, core_revision DESC');
->orderBy('core_revision DESC, core_language DESC');
}
// query for the current user language
$query->andWhere('(core_language = ? OR core_language = ?)', array(ZLanguage::getLanguageCode(), ''));
Expand Down Expand Up @@ -506,6 +506,171 @@ public function edit($args)
return $obj;
}

/**
* Returns a random number of Publications.
*
* @param integer $args['tid'] ID of the publication type.
* @param array $args['where'] Direct where conditions to the query.
* @param string $args['filter'] Filter string.
* @param integer $args['limit'] Number of items to retrieve.
* @param boolean $args['array'] Whether to fetch the resulting publications as array (default: false).
* @param boolean $args['handleplugins'] Whether to parse the plugin fields.
* @param boolean $args['loadworkflow'] Whether to add the workflow information.
* @param array $args['rel'] Relation configuration flags to use {load, onlyown, processrefs, checkperm, handleplugins, loadworkflow}.
*
* @return Doctrine_Collection Collection of random publications.
*/
public function getrandom($args)
{
//// Validation
if (!isset($args['tid'])) {
return LogUtil::registerError($this->__f('Error! Missing argument [%s].', 'tid'));
}

if (!Clip_Util::validateTid($args['tid'])) {
return LogUtil::registerError($this->__f('Error! Invalid publication type ID passed [%s].', DataUtil::formatForDisplay($args['tid'])));
}

$pubfields = Clip_Util::getPubFields($args['tid']);

if (!$pubfields) {
return LogUtil::registerError($this->__('Error! No publication fields found.'));
}

$pubtype = Clip_Util::getPubType($args['tid']);

//// Parameters
// define the arguments
$args = array(
'tid' => (int)$args['tid'],
'where' => isset($args['where']) ? $args['where'] : array(),
'filter' => isset($args['filter']) ? $args['filter'] : '()',
'limit' => (isset($args['limit']) && is_numeric($args['limit'])) ? (int)abs($args['limit']) : 1,
'array' => isset($args['array']) ? (bool)$args['array'] : false,
'handleplugins' => isset($args['handleplugins']) ? (bool)$args['handleplugins'] : true,
'loadworkflow' => isset($args['loadworkflow']) ? (bool)$args['loadworkflow'] : false,
'rel' => isset($args['rel']) ? $args['rel'] : null
);

if (!isset($args['rel'])) {
$args['rel'] = ($args['limit'] == 1) ? $pubtype['config']['display'] : $pubtype['config']['list'];
}

//// Misc values
// utility vars
$tableObj = Doctrine_Core::getTable('ClipModels_Pubdata'.$args['tid']);
$record = $tableObj->getRecordInstance();

//// Query setup
$args['queryalias'] = $queryalias = "random_{$args['tid']}";
$queryalias = "{$args['queryalias']} INDEXBY {$args['queryalias']}.id";

$query = $tableObj->createQuery($queryalias);

//// Filter
// resolve the FilterUtil arguments
$filter['args'] = array(
'alias' => $args['queryalias'],
'plugins' => array()
);

foreach ($pubfields as $field)
{
$plugin = Clip_Util_Plugins::get($field['fieldplugin']);

// enrich the filter parameters for restrictions and configurations
if (method_exists($plugin, 'enrichFilterArgs')) {
$plugin->enrichFilterArgs($filter['args'], $field, $args);
}

// enrich the query
if (method_exists($plugin, 'enrichQuery')) {
$plugin->enrichQuery($query, $field, $args);
}
}

// filter instance
$filter['obj'] = new Clip_Filter_Util('Clip', $tableObj, $filter['args']);
$filter['obj']->setFilter($args['filter']);

//// Relations
// filters will be limited to the loaded relations
$args['rel'] = isset($args['rel']) ? Clip_Util::getPubtypeConfig('list', $args['rel']) : array();

if ($args['rel'] && $args['rel']['load']) {
// adds the relations data
foreach ($record->getRelations($args['rel']['onlyown']) as $ralias => $rinfo) {
// load the relation if it means to load ONE related record only
if (($rinfo['own'] && $rinfo['type'] % 2 == 0) || (!$rinfo['own'] && $rinfo['type'] < 2)) {
$query->leftJoin("{$args['queryalias']}.{$ralias}");
}
}
}

// prioritizes the where clause coming from the filter
$filter['obj']->enrichQuery($query);

// add the conditions to the query
foreach ($args['where'] as $method => $condition) {
if (is_numeric($method)) {
$method = 'andWhere';
}
if (is_array($condition)) {
$query->$method($condition[0], $condition[1]);
} else {
$query->$method($condition);
}
}

// restrict to the current user language
$query->andWhere('(core_language = ? OR core_language = ?)', array(ZLanguage::getLanguageCode(), ''));

// restrictions for non-editors
$query->andWhere('(core_publishdate IS NULL OR core_publishdate <= ?)', date('Y-m-d H:i:s', time()) /*new Doctrine_Expression('NOW()')*/);
$query->andWhere('(core_expiredate IS NULL OR core_expiredate >= ?)', date('Y-m-d H:i:s', time()) /*new Doctrine_Expression('NOW()')*/);

// gets the random publist
$publist = new Doctrine_Collection($tableObj);

// count how many pubs are available
$pubcount = $query->count();

if ($pubcount) {
// can't retrieve more items than the existing ones
if ($args['limit'] > $pubcount) {
$args['limit'] = $pubcount;
}

// we will get one random pub at once
$query->limit(1);

// get the required publications
$offsets = array();
do {
// get a random offset
do {
$pos = rand(0, $pubcount - 1);

} while (in_array($pos, $offsets));

$offsets[] = $pos;
$query->offset($pos);

// get the publication and add it to the collection
$pub = $query->execute()->getFirst();

if (Clip_Access::toPub($pubtype, $pub, null, 'display')) {
$pub->clipProcess($args);
$publist->add($pub);
}

} while($publist->count() < $args['limit']);
}

//// Result
return $args['array'] ? $publist->toArray() : $publist;
}

/**
* Returns pid.
*
Expand Down
206 changes: 206 additions & 0 deletions src/modules/Clip/lib/Clip/Block/RandomList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
<?php
/**
* Clip
*
* @copyright (c) Clip Team
* @link http://github.com/zikula-modules/clip/
* @license GNU/GPL - http://www.gnu.org/copyleft/gpl.html
* @package Clip
* @subpackage Block
*/

/**
* RandomList Block.
*/
class Clip_Block_RandomList extends Zikula_Controller_AbstractBlock
{
/**
* Initialise block.
*/
public function init()
{
SecurityUtil::registerPermissionSchema('Clip:block:randomlist', 'Block Id:Pubtype Id:');
}

/**
* Get information on block.
*/
public function info()
{
return array(
'module' => 'Clip',
'text_type' => $this->__('Random List'),
'text_type_long' => $this->__('Random list of publications'),
'allow_multiple' => true,
'form_content' => false,
'form_refresh' => false,
'show_preview' => true
);
}

/**
* Display the block according its configuration.
*/
public function display($blockinfo)
{
$alert = $this->getVar('devmode', false) && Clip_Access::toClip(ACCESS_ADMIN);

// get variables from content block
$vars = BlockUtil::varsFromContent($blockinfo['content']);

// validation of required parameters
if (!isset($vars['tid']) || empty($vars['tid'])) {
return $alert ? $this->__f('Required parameter [%s] not set or empty.', 'tid') : null;
}
if (!Clip_Util::validateTid($vars['tid'])) {
return $alert ? LogUtil::registerError($this->__f('Error! Invalid publication type ID passed [%s].', DataUtil::formatForDisplay($vars['tid']))) : null;
}

// security check
// FIXME SECURITY centralize on Clip_Access
if (!SecurityUtil::checkPermission('Clip:block:randomlist', "$blockinfo[bid]:$vars[tid]:", ACCESS_OVERVIEW)) {
return;
}

// default values
$tpl = (isset($vars['template']) && !empty($vars['template'])) ? $vars['template'] : 'list';
$cachelt = isset($vars['cachelifetime']) ? (int)$vars['cachelifetime'] : null;

$pubtype = Clip_Util::getPubType($vars['tid']);
$template = "{$pubtype['folder']}/random_{$tpl}.tpl";

// check if the common does not exist
if (!$this->view->template_exists($template) && !$this->getVar('devmode', false)) {
return;
}

// check if cache is enabled and this block is cached
if (!empty($cachelt)) {
$this->view->setCacheLifetime($cachelt);

Clip_Util::register_nocache_plugins($this->view);

$cacheid = 'tid_'.$vars['tid'].'/randomlist'
.'/bid_'.$blockinfo['bid']
.'/'.UserUtil::getGidCacheString();
// FIXME PLUGINS Add plugin specific cache sections
// $cacheid .= '|field'.id.'|'.output

// set the output info
$this->view->setCaching(Zikula_View::CACHE_INDIVIDUAL)
->setCacheId($cacheid);

if ($this->view->is_cached($template)) {
$blockinfo['content'] = $this->view->fetch($template);

return BlockUtil::themeBlock($blockinfo);
}
} else {
$cacheid = null;
$this->view->setCaching(Zikula_View::CACHE_DISABLED);
}

//// Execution
$vars['limit'] = isset($vars['limit']) && (int)$vars['limit'] > 1 ? (int)$vars['limit'] : 3;

$vars['filter'] = isset($vars['filter']) && !empty($vars['filter']) ? $vars['filter'] : '()';

$vars['where'] = array();
$vars['where'][] = array('core_online = ?', 1);
$vars['where'][] = array('core_visible = ?', 1);
$vars['where'][] = array('core_intrash = ?', 0);

// get the random list
$publist = ModUtil::apiFunc('Clip', 'user', 'getrandom', $vars);

if (!$publist->count()) {
return;
}

// register clip_util
Clip_Util::register_utilities($this->view);

//// Output
// assign the pubdata and pubtype to the output
$this->view->assign('publist', $publist)
->assign('pubtype', $pubtype);

// check if template is not available
if (!$this->view->template_exists($template)) {
if ($alert) {
LogUtil::registerStatus($this->__f('Notice: Template [%s] not found.', $template));
}

$template = 'generic_blocklist.tpl';

// settings for the autogenerated display template
$this->view->setForceCompile(true)
->setCaching(Zikula_View::CACHE_DISABLED)
->assign('clip_generic_tpl', true);
}

$blockinfo['content'] = $this->view->fetch($template, $cacheid);

if (empty($blockinfo['content'])) {
return;
}

return BlockUtil::themeBlock($blockinfo);
}

/**
* Modify block settings.
*/
public function modify($blockinfo)
{
// get current content
$vars = BlockUtil::varsFromContent($blockinfo['content']);

// defaults
if (!isset($vars['tid'])) {
$vars['tid'] = '';
}
if (!isset($vars['filter'])) {
$vars['filter'] = '';
}
if (!isset($vars['limit']) || (int)$vars['limit'] < 1) {
$vars['limit'] = 3;
}
if (!isset($vars['template'])) {
$vars['template'] = '';
}
if (!isset($vars['cachelifetime'])) {
$vars['cachelifetime'] = 0;
}

// builds the pubtypes selector
$pubtypes = Clip_Util::getPubType(-1)->toKeyValueArray('tid', 'title');

// builds the output
$this->view->assign('vars', $vars)
->assign('pubtypes', $pubtypes);

// return output
return $this->view->fetch('clip_block_randomlist_modify.tpl');
}

/**
* Update block settings.
*/
public function update($blockinfo)
{
$vars = array (
'tid' => FormUtil::getPassedValue('tid'),
'filter' => FormUtil::getPassedValue('filter'),
'limit' => FormUtil::getPassedValue('limit'),
'template' => FormUtil::getPassedValue('template'),
'cachelifetime' => FormUtil::getPassedValue('cachelifetime')
);

$vars['limit'] = (int)$vars['limit'] > 1 ? (int)$vars['limit'] : 3;

$blockinfo['content'] = BlockUtil::varsToContent($vars);

return $blockinfo;
}
}
Loading

0 comments on commit 219e338

Please sign in to comment.