13000);
}
public static function get_instance_javascript(BlockInstance $bi) {
$blockid = $bi->get('id');
return array(
array(
'file' => 'js/taggedposts.js',
'initjs' => "addNewTaggedPostShortcut($blockid);",
)
);
}
/**
* Given a list of tags, finds blocks by the current user that contain those tags
* (Used to determine which ones to check for the view_artefact table)
* @param array $tags
* @return array
*/
public static function find_matching_blocks(array $tags) {
global $USER;
$taggedblockids = (array)get_column_sql(
'SELECT bi.id as block
FROM
{blocktype_taggedposts_tags} btt
INNER JOIN {block_instance} bi
ON btt.block_instance = bi.id
INNER JOIN {view} v
ON bi.view = v.id
WHERE
v.owner = ?
AND btt.tagtype = ?
AND btt.tag IN (' . implode(',', db_array_to_ph($tags)) . ')
',
array_merge(
array(
$USER->id,
PluginBlocktypeTaggedposts::TAGTYPE_INCLUDE
),
$tags
)
);
if ($taggedblockids) {
return $taggedblockids;
}
else {
return array();
}
}
/**
* Returns the blog posts that will be displayed by this block.
*
* @param BlockInstance $instance
* @param array $tagsin Optional reference variable for finding out the "include" tags used by this block
* @param array $tagsout Optional reference variable for finding out the "extclude" tags used by this block
* @return array of blogpost records
*/
public static function get_blog_posts_in_block(BlockInstance $instance, &$tagsinreturn = null, &$tagsoutreturn = null) {
$configdata = $instance->get('configdata');
$results = array();
$tagsin = $tagsout = array();
$tagrecords = get_records_array('blocktype_taggedposts_tags', 'block_instance', $instance->get('id'), 'tagtype desc, tag', 'tag, tagtype');
if ($tagrecords) {
$view = $instance->get('view');
$limit = isset($configdata['count']) ? (int) $configdata['count'] : 10;
foreach ($tagrecords as $tag) {
if ($tag->tagtype == PluginBlocktypeTaggedposts::TAGTYPE_INCLUDE) {
$tagsin[] = $tag->tag;
}
else {
$tagsout[] = $tag->tag;
}
}
$tagsout = array_filter($tagsout);
$sqlvalues = array($view);
$sql =
'SELECT a.title, p.title AS parenttitle, a.id, a.parent, a.owner, a.description, a.allowcomments, at.tag, a.ctime
FROM {artefact} a
JOIN {artefact} p ON a.parent = p.id
JOIN {artefact_blog_blogpost} ab ON (ab.blogpost = a.id AND ab.published = 1)
JOIN {artefact_tag} at ON (at.artefact = a.id)
WHERE a.artefacttype = \'blogpost\'
AND a.owner = (SELECT "owner" from {view} WHERE id = ?)';
if (!empty($tagsin)) {
foreach ($tagsin as $tagin) {
$sql .= ' AND EXISTS (
SELECT * FROM {artefact_tag} AS at
WHERE a.id = at.artefact
AND at.tag = ?
)';
}
$sqlvalues = array_merge($sqlvalues, $tagsin);
}
if (!empty($tagsout)) {
foreach ($tagsout as $tagout) {
$sql .= ' AND NOT EXISTS (
SELECT * FROM {artefact_tag} AS at
WHERE a.id = at.artefact
AND at.tag = ?
)';
}
$sqlvalues = array_merge($sqlvalues, $tagsout);
}
$sql .= ' ORDER BY a.ctime DESC, a.id DESC';
$results = get_records_sql_array($sql, $sqlvalues);
// We need to filter this down to unique results
if (!empty($results)) {
$used = array();
foreach ($results as $key => $result) {
if (array_search($result->id, $used) === false) {
$used[] = $result->id;
}
else {
unset($results[$key]);
}
}
if (!empty($limit)) {
$results = array_slice($results, 0, $limit);
}
}
else {
$results = array();
}
}
if ($tagsinreturn !== null) {
$tagsinreturn = $tagsin;
}
if ($tagsoutreturn !== null) {
$tagsoutreturn = $tagsout;
}
return $results;
}
public static function render_instance(BlockInstance $instance, $editing=false) {
global $USER;
$configdata = $instance->get('configdata');
$view = $instance->get('view');
$full = isset($configdata['full']) ? $configdata['full'] : false;
$results = array();
$smarty = smarty_core();
$smarty->assign('view', $view);
$viewownerdisplay = null;
// Display all posts, from all blogs, owned by this user
$tagsin = $tagsout = array();
$results = self::get_blog_posts_in_block($instance, $tagsin, $tagsout);
if ($tagsin || $tagsout) {
$smarty->assign('blockid', $instance->get('id'));
$smarty->assign('editing', $editing);
if ($editing) {
// Get list of blogs owned by this user to create the "Add new post" shortcut while editing
$viewowner = $instance->get_view()->get('owner');
if (!$viewowner || !$blogs = get_records_select_array('artefact', 'artefacttype = \'blog\' AND owner = ?', array($viewowner), 'title ASC', 'id, title')) {
$blogs = array();
}
$smarty->assign('tagselect', implode(', ', $tagsin));
$smarty->assign('blogs', $blogs);
}
// if posts are not found with the selected tag, notify the user
if (!$results) {
$smarty->assign('badtag', implode(', ', $tagsin));
$smarty->assign('badnotag', implode(', ', $tagsout));
return $smarty->fetch('blocktype:taggedposts:taggedposts.tpl');
}
// update the view_artefact table so journal entries are accessible when this is the only block on the page
// referencing this journal
$dataobject = array(
'view' => $view,
'block' => $instance->get('id'),
);
require_once(get_config('docroot') . 'lib/view.php');
$viewobj = new View($view);
require_once(get_config('docroot') . 'artefact/lib.php');
safe_require('artefact', 'blog');
safe_require('artefact', 'comment');
foreach ($results as $result) {
$dataobject["artefact"] = $result->parent;
$result->postedbyon = get_string('postedbyon', 'artefact.blog', display_default_name($result->owner), format_date(strtotime($result->ctime)));
$result->displaydate= format_date(strtotime($result->ctime));
$artefact = new ArtefactTypeBlogpost($result->id);
// get comments for this post
$result->commentcount = count_records_select('artefact_comment_comment', "onartefact = {$result->id} AND private = 0 AND deletedby IS NULL");
$allowcomments = $artefact->get('allowcomments');
if (empty($result->commentcount) && empty($allowcomments)) {
$result->commentcount = null;
}
list($commentcount, $comments) = ArtefactTypeComment::get_artefact_comments_for_view($artefact, $viewobj, null, false);
$result->comments = $comments;
// get all tags for this post
$taglist = get_records_array('artefact_tag', 'artefact', $result->id, "tag DESC");
foreach ($taglist as $t) {
$result->taglist[] = $t->tag;
}
if ($full) {
$rendered = $artefact->render_self(array('viewid' => $view, 'details' => true, 'blockid' => $instance->get('id')));
$result->html = $rendered['html'];
if (!empty($rendered['javascript'])) {
$result->html .= '';
}
}
}
// check if the user viewing the page is the owner of the selected tag
$owner = $results[0]->owner;
if ($USER->id != $owner) {
$viewownerdisplay = get_user_for_display($owner);
}
$smarty->assign('tagsin', $tagsin);
$smarty->assign('tagsout', $tagsout);
}
else if (!self::get_chooseable_tags()) {
// error if block configuration fails
$smarty->assign('configerror', get_string('notagsavailableerror', 'blocktype.blog/taggedposts'));
return $smarty->fetch('blocktype:taggedposts:taggedposts.tpl');
}
else {
// error if block configuration fails
$smarty->assign('configerror', get_string('configerror', 'blocktype.blog/taggedposts'));
return $smarty->fetch('blocktype:taggedposts:taggedposts.tpl');
}
// add any needed links to the tags
$tagstr = $tagomitstr = '';
foreach ($tagsin as $key => $tag) {
if ($key > 0) {
$tagstr .= ', ';
}
$tagstr .= ($viewownerdisplay) ? '"' . $tag . '"' : '"' . $tag . '"';
}
if (!empty($tagsout)) {
foreach ($tagsout as $key => $tag) {
if ($key > 0) {
$tagomitstr .= ', ';
}
$tagomitstr .= ($viewownerdisplay) ? '"' . $tag . '"' : '"' . $tag . '"';
}
}
$blockheading = get_string('blockheadingtags', 'blocktype.blog/taggedposts', count($tagsin), $tagstr);
$blockheading .= (!empty($tagomitstr)) ? get_string('blockheadingtagsomit', 'blocktype.blog/taggedposts', count($tagsout), $tagomitstr) : '';
$blockheading .= ($viewownerdisplay) ? ' ' . get_string('by', 'artefact.blog') . ' ' . display_name($viewownerdisplay) . '' : '';
$smarty->assign('full', $full);
$smarty->assign('results', $results);
$smarty->assign('blockheading', $blockheading);
return $smarty->fetch('blocktype:taggedposts:taggedposts.tpl');
}
private static function get_selected_tags() {
}
/**
* Get the tags the user can choose from
* (i.e. tags they use on their blogpost artefacts)
* @return array
*/
private static function get_chooseable_tags() {
global $USER;
return get_records_sql_array("
SELECT at.tag
FROM
{artefact_tag} at
JOIN {artefact} a
ON a.id = at.artefact
WHERE
a.owner = ?
AND a.artefacttype = 'blogpost'
GROUP BY at.tag
ORDER BY at.tag ASC
", array($USER->id));
}
public static function has_instance_config() {
return true;
}
public static function instance_config_form(BlockInstance $instance) {
global $USER;
$configdata = $instance->get('configdata');
$tags = self::get_chooseable_tags();
$elements = array();
if (!empty($tags)) {
$tagselect = array();
$tagrecords = get_records_array('blocktype_taggedposts_tags', 'block_instance', $instance->get('id'), 'tagtype desc, tag', 'tag, tagtype');
if ($tagrecords) {
foreach ($tagrecords as $tag) {
if ($tag->tagtype == PluginBlocktypeTaggedposts::TAGTYPE_INCLUDE) {
$tagselect[] = $tag->tag;
}
else {
$tagselect[] = '-' . $tag->tag;
}
}
}
// The javascript to alter the display for the excluded tags
$excludetag = get_string('excludetag', 'blocktype.blog/taggedposts');
$formatSelection = << 'autocomplete',
'title' => get_string('taglist','blocktype.blog/taggedposts'),
'description' => get_string('taglistdesc', 'blocktype.blog/taggedposts'),
'defaultvalue' => $tagselect,
'ajaxurl' => get_config('wwwroot') . 'artefact/blog/blocktype/taggedposts/taggedposts.json.php',
'initfunction' => 'translate_ids_to_tags',
'multiple' => true,
'ajaxextraparams' => array(),
'rules' => array('required' => 'true'),
'required' => true,
'blockconfig' => true,
'help' => true,
'mininputlength' => 0,
'extraparams' => array('formatSelection' => "$formatSelection"),
);
$elements['count'] = array(
'type' => 'text',
'title' => get_string('itemstoshow', 'blocktype.blog/taggedposts'),
'description' => get_string('betweenxandy', 'mahara', 1, 100),
'defaultvalue' => isset($configdata['count']) ? $configdata['count'] : 10,
'size' => 3,
'rules' => array('integer' => true, 'minvalue' => 1, 'maxvalue' => 999),
);
$elements['full'] = array(
'type' => 'checkbox',
'title' => get_string('showjournalitemsinfull', 'blocktype.blog/taggedposts'),
'description' => get_string('showjournalitemsinfulldesc', 'blocktype.blog/taggedposts'),
'defaultvalue' => isset($configdata['full']) ? $configdata['full'] : false,
);
return $elements;
}
else {
return array(
'notags' => array(
'type' => 'html',
'title' => get_string('taglist', 'blocktype.blog/taggedposts'),
'value' => get_string('notagsavailable', 'blocktype.blog/taggedposts'),
),
);
}
}
public static function instance_config_validate($form, $values) {
if (empty($values['tagselect'])) {
// We don't have a tagselect field due to no journal entries having a tag
$form->set_error(null, get_string('notagsavailableerror', 'blocktype.blog/taggedposts'));
}
else {
// Need to fully check that the returned array is empty
$values['tagselect'] = array_filter($values['tagselect']);
if (empty($values['tagselect'])) {
$result['message'] = get_string('required', 'mahara');
$form->set_error('tagselect', $form->i18n('rule', 'required', 'required'), false);
$form->reply(PIEFORM_ERR, $result);
}
}
}
public static function instance_config_save($values, BlockInstance $instance) {
$tagselect = $values['tagselect'];
unset($values['tagselect']);
if (!empty($tagselect)) {
delete_records('blocktype_taggedposts_tags', 'block_instance', $instance->get('id'));
foreach ($tagselect as $tag) {
$value = PluginBlocktypeTaggedposts::TAGTYPE_INCLUDE;
if (substr($tag, 0, 1) == '-') {
$value = PluginBlocktypeTaggedposts::TAGTYPE_EXCLUDE;
$tag = substr($tag, 1);
}
$todb = new stdClass();
$todb->block_instance = $instance->get('id');
$todb->tag = $tag;
$todb->tagtype = $value;
insert_record('blocktype_taggedposts_tags', $todb);
}
}
return $values;
}
/**
* Returns a list of artefact IDs that are "in" this blockinstance.
*
* {@internal{Because links to artefacts within blogposts don't count
* as making those artefacts 'children' of the blog post, we have to add
* them directly to the blog.}}
*
* @return array List of artefact IDs that are 'in' this blog - all
* blogposts in it plus all links to other artefacts that are
* part of the blogpost text. Note that proper artefact
* children, such as blog post attachments, aren't included -
* the artefact parent cache is used for them
* @see PluginBlocktypeBlogPost::get_artefacts()
*/
public static function get_artefacts(BlockInstance $instance) {
$artefacts = array();
$blogposts = self::get_blog_posts_in_block($instance);
foreach ($blogposts as $blogpost) {
$artefacts[] = $blogpost->id;
$artefacts[] = $blogpost->parent;
$blogpostobj = $instance->get_artefact_instance($blogpost->id);
$artefacts = array_merge($artefacts, $blogpostobj->get_referenced_artefacts_from_postbody());
}
$artefacts = array_unique($artefacts);
return $artefacts;
}
public static function default_copy_type() {
return 'nocopy';
}
/**
* Taggedposts blocktype is only allowed in personal views, because currently
* there's no such thing as group/site blogs
*/
public static function allowed_in_view(View $view) {
return $view->get('owner') != null;
}
}
function translate_ids_to_tags(array $ids) {
$ids = array_diff($ids, array(''));
$results = array();
if (!empty($ids)) {
foreach ($ids as $id) {
$text = (substr($id, 0, 1) == '-') ? substr($id, 1) : $id;
$results[] = (object) array('id' => $id, 'text' => $text);
}
}
return $results;
}