I've been asked to create a custom plugin displays course overview (course id, course name, enrolled and completed) through API. There is a report_completionoverview plugin that I can refer to and basically wanna retrieve exactly the same list via Moodle API in JSON format.
I'm trying to create a local plugin based on moodle documentation (https://docs.moodle.org/dev/Adding_a_web_service_to_a_plugin) and other default plugins, but having difficulty to debug.
* modified folder name to match plugin name *
I've Created
local/get_completion_overview/db/service.php
local/get_completion_overview/lang/en/local_get_completion_overview.php
local/get_completion_overview/externallib.php
local/get_completion_overview/version.php
Successfully installed the plugin without error in Moodle, but the plugin is not listed in the function.
I honestly think that my code is not right (and it is messy since I've copied from different sources), but don't know how to debug it.
Can anyone please let me know if you know how?
I also attach local/completionview/externallib.php (I'm sure this is causing the issue I believe).
Any help or idea or comment would be appreciated.
Thanks a lot!
<?php
require_once($CFG->libdir . "/externallib.php");
require_once("lib.php");
class local_get_completion_overview_external extends external_api {
public static function get_completion_overview_parameters() {
return new external_function_parameters(
array(
'field' => new external_value(PARAM_ALPHA, 'The field to search can be left empty for all courses or:
id: course id
ids: comma separated course ids
shortname: course short name
idnumber: course id number
category: category id the course belongs to
', VALUE_DEFAULT, ''),
'value' => new external_value(PARAM_RAW, 'The value to match', VALUE_DEFAULT, '')
)
);
}
public static function get_completion_overview($field = '', $value = ''){
global $CFG, $DB;
require_once($CFG->dirroot . '/course/lib.php');
require_once($CFG->libdir . '/filterlib.php');
$params = self::validate_parameters(self::get_completion_overview_parameters(),
array(
'field' => $field,
'value' => $value,
)
);
$sql = "SELECT DISTINCT cr.id AS courseid, cr.fullname AS coursename,
COUNT(DISTINCT ra.id ) AS enrols,
COUNT(DISTINCT cc.timecompleted) AS completed
FROM {course} cr
JOIN {context} ct ON ( ct.instanceid = cr.id )
LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5
LEFT JOIN {course_completions} cc ON cc.course = cr.id
GROUP BY cr.fullname, cr.id
ORDER BY coursename";
$warnings = array();
if (empty($params['field'])) {
$courses = $DB->get_records_sql($sql, array());
} else {
switch ($params['field']) {
case 'id':
case 'category':
$value = clean_param($params['value'], PARAM_INT);
break;
case 'ids':
$value = clean_param($params['value'], PARAM_SEQUENCE);
break;
case 'shortname':
$value = clean_param($params['value'], PARAM_TEXT);
break;
case 'idnumber':
$value = clean_param($params['value'], PARAM_RAW);
break;
default:
throw new invalid_parameter_exception('Invalid field name');
}
if ($params['field'] === 'ids') {
$courses = $DB->get_records_list('course', 'id', explode(',', $value), 'id ASC');
} else {
$courses = $DB->get_records('course', array($params['field'] => $value), 'id ASC');
}
}
if(!empty($courses)){
$coursesdata = array();
$currentcourseid = null;
$course = null;
foreach($courses as $completion) {
$context = context_course::instance($course->id);
$crs = array();
$crs['courseid'] = $completion->courseid;
$crs['coursename'] = (string)$completion->coursename;
$crs['enrols'] = $completion->enrols;
$crs['completed'] = $completion->completed;
try {
self::validate_context($context);
} catch (Exception $e) {
continue;
}
if(is_null($currentcourseid) || ($completion->courseid != $currentcourseid)) {
if(!is_null($course)) {
$coursesdata[] = $course;
}
$course = array();
$course['courseid'] = $completion->courseid;
}
$course['courseid'][] = $crs;
$currentcourseid = $completion->courseid;
}
if(!is_null($course)){
$coursesdata[] = $course;
}
$courses->close();
}
$result = array();
$result['course'] = $coursesdata;
return $result;
}
public static function get_completion_overview_returns() {
return new external_single_structure(
array(
'course' => new external_multiple_structure(self::get_completion_overview(), 'list of courses completion')
)
);
}
}
** service.php
<?php
$functions = array(
'local_get_completion_overview' =>
array('classname' => 'local_get_completion_overview_external',
'methodname' => 'get_completion_overview',
'classpath' => 'local/get_completion_overview/externallib.php',
'description' => 'Get course completion overview',
'type' => 'read',
'capabilities'=> array(), //optional, useful to let the administrator know what potential capabilities the user 'could' need
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
);
$services = array(
'get completion overview' => array( //the name of the web service
'functions' => array ('local_get_completion_overview'), //web service functions of this service
'requiredcapability' => '', //if set, the web service user need this capability to access
//any function of this service. For example: 'some/capability:specified'
'restrictedusers' =>0, //if enabled, the Moodle administrator must link some user to this service
//into the administration
'enabled'=>1, //if enabled, the service can be reachable on a default installation
)
);
service.php should be services.php.
After fixing the filename, it appears in Moodle as function, however having an issue to load the function.
Undefined property: stdClass::$id in
/Users/lucy/Sites/moodle/local/get_completion_overview/externallib.php
on line 84
which is
$context = context_course::instance($completion->id);
in foreach block.
also,
Debug info: SELECT id,category FROM {course} WHERE id IS NULL
[array (
)]
Error code: invalidrecord
Stack trace:
line 1562 of /lib/dml/moodle_database.php: dml_missing_record_exception thrown
line 1538 of /lib/dml/moodle_database.php: call to moodle_database->get_record_select()
line 6822 of /lib/accesslib.php: call to moodle_database->get_record()
line 84 of /local/get_completion_overview/externallib.php: call to context_course::instance()
line 138 of /local/get_completion_overview/externallib.php: call to local_get_completion_overview_external::get_completion_overview()
line 124 of /lib/externallib.php: call to local_get_completion_overview_external::get_completion_overview_returns()
line 219 of /webservice/renderer.php: call to external_api::external_function_info()
line 121 of /admin/webservice/service_functions.php: call to core_webservice_renderer->admin_service_function_list()
Increment version number within version.php file. It will trigger moodle for update. Then you should do few updates in moodle. After that you shoudl see the listing
This works as expected. I've changed the permission to has_capability('moodle/site:config', $context);
I'm posting my solution in case someone runs into the same issue.
<?php
require_once('../../config.php');
require_once($CFG->libdir . "/externallib.php");
// require_once('../lib/externallib.php');
// require_once("lib.php");
class local_get_completion_overview_external extends external_api {
public static function get_completion_overview_parameters() {
return new external_function_parameters(
array(
'field' => new external_value(PARAM_ALPHA, 'The field to search can be left empty for all courses or:
id: course id', VALUE_DEFAULT, ''),
'value' => new external_value(PARAM_RAW, 'The value to match', VALUE_DEFAULT, '')
)
);
}
public static function get_completion_overview($field='', $value=''){
global $CFG, $DB;
require_once($CFG->dirroot . '/course/lib.php');
$params = self::validate_parameters(self::get_completion_overview_parameters(),
array(
'field' => $field,
'value' => $value,
)
);
$sql = "SELECT DISTINCT cr.id AS courseid,
cr.fullname AS coursename,
COUNT(DISTINCT ra.id ) AS enrols,
COUNT(DISTINCT cc.timecompleted) AS completed
FROM {course} cr
JOIN {context} ct ON ( ct.instanceid = cr.id )
LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5
LEFT JOIN {course_completions} cc ON cc.course = cr.id
GROUP BY cr.fullname, cr.id
ORDER BY coursename";
$warnings = array();
$coursesdata = array();
$requestedcourseids = $params['value'];
if (empty($params['field'])) {
$courses = $DB->get_records_sql($sql, array());
} else {
$value = clean_param($params['id'], PARAM_INT);
if (count($value) > 0) {
$placeholders = array();
$sql_2 = "SELECT DISTINCT cr.id AS courseid,
cr.fullname AS coursename,
COUNT(DISTINCT ra.id) AS enrols,
COUNT(DISTINCT cc.timecompleted) AS completed
FROM {course} cr JOIN {context} ct ON ( ct.instanceid = cr.id )
LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5
LEFT JOIN {course_completions} cc ON (cc.course = cr.id)
WHERE cr.id = ".$requestedcourseids." GROUP BY cr.fullname, cr.id";
$courses = $DB->get_records_sql($sql_2, $placeholders);
}
}
if(!empty($courses)) {
$currentcourseid = null;
$course = null;
foreach($courses as $completion) {
$context = context_system::instance();
has_capability('moodle/site:config', $context);
if(is_null($currentcourseid) || ($completion->courseid != $currentcourseid)) {
if(!is_null($course)) {
$coursesdata[] = $course;
}
$course = array();
$course['courseid'] = $completion->courseid;
$course['coursename'] = $completion->coursename;
$course['enrols'] = $completion->enrols;
$course['completed'] = $completion->completed;
$course['totalcourses'] = count($course);
}
$currentcourseid = $completion->courseid;
}
if(!is_null($course)){
$coursesdata[] = $course;
}
} else {
$warning = array();
$warning['item'] = 'course';
$warning['itemid'] = $requestedcourseids;
$warning['warningcode'] = '1';
$warning['message'] = 'No course found';
$warnings[] = $warning;
}
$result['course'] = $coursesdata;
$result['warnings'] = $warnings;
return $result;
}
public static function get_completion_overview_returns() {
return new external_single_structure(
array(
'course' => new external_multiple_structure(
new external_single_structure(
array(
'courseid' => new external_value(PARAM_INT, 'description'),
'coursename' => new external_value(PARAM_TEXT, ''),
'enrols' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
'completed' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
'totalcourses' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
)
)
),
'warnings' => new external_warnings()
)
);
}
}
Related
I am trying to pull each course completion data through API.
Pulling all data and the course data by entering courseid working okay, but when I enter courseid doesn't exist in Moodle, it doesn't return the warning message.
courseid 5 doesn't exist and it should throw warning messages but it returns an error.
Looks like it recognises whether $courseid is empty or not and shows the right value based on entered request.
I've looked at other plugin files and saw how other people passed the warning message in their code, it looks the same and I can't figure out why this doesn't throw the error message.
Am I missing importing a class maybe?
Any help would be appreciated.
Here is my code.
class local_get_completion_overview_external extends external_api {
public static function get_completion_overview_parameters() {
return new external_function_parameters(
array(
'field' => new external_value(PARAM_ALPHA, 'The field to search can be left empty for all courses or:
id: course id', VALUE_DEFAULT, ''),
'value' => new external_value(PARAM_RAW, 'The value to match', VALUE_DEFAULT, '')
)
);
}
public static function get_completion_overview($field='', $value=''){
global $CFG, $DB;
require_once($CFG->dirroot . '/course/lib.php');
$params = self::validate_parameters(self::get_completion_overview_parameters(),
array(
'field' => $field,
'value' => $value,
)
);
$sql = "SELECT DISTINCT cr.id AS courseid,
cr.fullname AS coursename,
COUNT(DISTINCT ra.id ) AS enrols,
COUNT(DISTINCT cc.timecompleted) AS completed
FROM {course} cr
JOIN {context} ct ON ( ct.instanceid = cr.id )
LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5
LEFT JOIN {course_completions} cc ON cc.course = cr.id
GROUP BY cr.fullname, cr.id
ORDER BY coursename";
$warnings = array();
$requestedcourseids = $params['value'];
if (empty($params['field'])) {
$courses = $DB->get_records_sql($sql, array());
} else {
$value = clean_param($params['id'], PARAM_INT);
if (count($value) > 0) {
$placeholders = array();
$sql_2 = "SELECT DISTINCT cr.id AS courseid,
cr.fullname AS coursename,
COUNT(DISTINCT ra.id) AS enrols,
COUNT(DISTINCT cc.timecompleted) AS completed
FROM {course} cr JOIN {context} ct ON ( ct.instanceid = cr.id )
LEFT JOIN {role_assignments} ra ON ( ra.contextid = ct.id ) and ra.roleid = 5
LEFT JOIN {course_completions} cc ON (cc.course = cr.id)
WHERE cr.id = ".$requestedcourseids." GROUP BY cr.fullname, cr.id";
$courses = $DB->get_records_sql($sql_2, $placeholders);
}
}
if(!empty($courses)) {
$coursesdata = array();
$currentcourseid = null;
$course = null;
foreach($courses as $completion) {
$context = context_system::instance();
has_capability('moodle/site:config', $context);
if(is_null($currentcourseid) || ($completion->courseid != $currentcourseid)) {
if(!is_null($course)) {
$coursesdata[] = $course;
}
$course = array();
$course['courseid'] = $completion->courseid;
$course['coursename'] = $completion->coursename;
$course['enrols'] = $completion->enrols;
$course['completed'] = $completion->completed;
$course['totalcourses'] = count($course);
}
$currentcourseid = $completion->courseid;
}
if(!is_null($course)){
$coursesdata[] = $course;
}
} else {
$warning = array();
$warning['item'] = 'course';
$warning['itemid'] = $requestedcourseids;
$warning['warningcode'] = '1';
$warning['message'] = 'No course found';
$warnings[] = $warning;
}
$result['course'] = $coursesdata;
$result['warnings'] = $warnings;
return $result;
}
public static function get_completion_overview_returns() {
return new external_single_structure(
array(
'course' => new external_multiple_structure(
new external_single_structure(
array(
'courseid' => new external_value(PARAM_INT, 'description'),
'coursename' => new external_value(PARAM_TEXT, ''),
'enrols' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
'completed' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
'totalcourses' => new external_value(PARAM_INT, '', VALUE_OPTIONAL),
)
)
),
'warnings' => new external_warnings()
)
);
}
}
In your code, the variable $coursesdata is only initialised as an array if at least one requested course is found in the database.
So, the line:
$result['courses'] = $coursesdata;
Will produce a warning message (if debugging is on) and set $result['courses'] to null. The expected type here is an array, so the webservice code correctly complains that the 'courses' value is not the correct type.
To fix, make sure you add:
$coursesdata = [];
Somewhere near the top of your function.
I'm new on php, I'm triyng to backup a post before deleting on a mybb forum.
I edited inc/class_moderation.php adding the following function backup_post, but when the call to the function backup_post
throws
Call to undefined function backup_post() in
/membri/myforum/inc/class_moderation.php on line 485
function delete_post($pid)
{
global $mybb, $db, $cache, $plugins;
$pid = $plugins->run_hooks("class_moderation_delete_post_start", $pid);
// Get pid, uid, fid, tid, visibility, forum post count status of post
$pid = intval($pid);
$query = $db->query("
SELECT p.pid, p.uid, p.fid, p.tid, p.visible, f.usepostcounts, t.visible as threadvisible, message, p.username as p_username, p.subject, p.dateline
FROM ".TABLE_PREFIX."posts p
LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid)
WHERE p.pid='$pid'
");
$post = $db->fetch_array($query);
// If post counts enabled in this forum and it hasn't already been unapproved, remove 1
if($post['usepostcounts'] != 0 && $post['visible'] != 0 && $post['threadvisible'] != 0)
{
$db->update_query("users", array("postnum" => "postnum-1"), "uid='{$post['uid']}'", 1, true);
}
if(!function_exists("remove_attachments"))
{
require MYBB_ROOT."inc/functions_upload.php";
}
// Remove attachments
remove_attachments($pid);
//Backup the post
backup_post($pid);
// Delete the post
$db->delete_query("posts", "pid='$pid'");
// Remove any reports attached to this post
$db->delete_query("reportedposts", "pid='$pid'");
$num_unapproved_posts = $num_approved_posts = 0;
// Update unapproved post count
if($post['visible'] == 0 || $post['threadvisible'] == 0)
{
++$num_unapproved_posts;
}
else
{
++$num_approved_posts;
}
$plugins->run_hooks("class_moderation_delete_post", $post['pid']);
// Update stats
$update_array = array(
"replies" => "-{$num_approved_posts}",
"unapprovedposts" => "-{$num_unapproved_posts}"
);
update_thread_counters($post['tid'], $update_array);
// Update stats
$update_array = array(
"posts" => "-{$num_approved_posts}",
"unapprovedposts" => "-{$num_unapproved_posts}"
);
update_forum_counters($post['fid'], $update_array);
return true;
}
function backup_post($pid)
{
global $mybb, $db, $cache, $plugins;
// Get pid, uid, fid, tid, visibility, forum post count status of post
$pid = intval($pid);
$query = $db->query("
SELECT p.pid, p.uid, p.fid, p.tid, p.visible, f.usepostcounts, t.visible as threadvisible, message, p.username as p_username, p.subject, p.dateline
FROM ".TABLE_PREFIX."posts p
LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid)
WHERE p.pid='$pid'
");
$post = $db->fetch_array($query);
$deletedpost = array(
"username_delete" => $mybb->user['username'],
"username" => $post['p_username'],
"subject" => $post['subject'],
"message" => $post['message'],
"dateline" => TIME_NOW,
"post_dateline" => $post['dateline'],
);
$db->insert_query("posts_deleted", $deletedpost);
//14-06-20016
//ob_start();
//var_dump($mybb);
//$data = ob_get_clean();
//$fp = fopen(MYBB_ROOT."myText.txt","wb");
//fwrite($fp,$data);
//fwrite($fp, "cancellato da ".$mybb->user['username']);
//fwrite($fp, "autore ".$post['p_username']);
//fwrite($fp, "messaggio ".$post['message']);
/*
foreach ($post as $key => $value) {
fwrite($fp, $key );
}
*/
//fclose($fp);
return true;
}
You are adding functions to a class (then we tend to call them "methods" instead of "functions", but that doesn't really matter).
When you want to call a class method, you need to call it like $class_instance->method_name() instead of the usual method_name(), which works for "plain" functions.
When you are calling a method from another method in the same class, you use $this to get the same class instance.
So if you change this line:
backup_post($pid);
to:
$this->backup_post($pid);
it should work.
I am using a real estate component that has a front-end admin area to view property listings. An additional field was added to a section called custom fields that is named Ref (Reference). In the admin listings I am trying to add an additional search that searches for that reference. There are three tables involved here:
1j0_cddir_jomestate Which holds the property listings information such as title and description.
1j0_cddir_fields which is the custom fields created.
1j0_cddir_content_has_fields and this holds the values of the custom fields
I would need to join 1j0_cddir_content_has_fields "fields_id" with 1j0_cddir_fields "id" and 1j0_cddir_jomestate "id" must join 1j0_cddir_content_has_fields "content_id"
I am struggling to figure out how to add this function to the models/admin_listings.php so that I may add that search input to the admin_listings view.
<?php
protected $text_prefix = 'COM_JOMESTATE';
protected $user;
function __construct()
{
parent::__construct();
$this->user=JFactory::getUser();
$this->planID=$this->getPlanID();
}
protected function getListQuery()
{
// Initialise variables.
$db = $this->getDbo();
$query = $db->getQuery(true);
if ($this->planID->profile=='company'){
$query->select(
$this->getState(
'list.select',
'a.id AS id, a.title AS title, a.date_created, a.featured, a.users_id, a.published, '.
'c.title as category_title,a.date_publish,a.date_publish_down,ag.first_name,ag.last_name'
)
);
}else{
$query->select(
$this->getState(
'list.select',
'a.id AS id, a.title AS title, a.featured, a.date_created, a.users_id, a.published, '.
'c.title as category_title,a.date_publish,a.date_publish_down'
)
);
}
$query->from($db->quoteName('#__cddir_jomestate').' AS a');
$query->select('COUNT(l.id) AS viewHow, SUM(l.view_item) AS viewSum');
$query->join('LEFT', '#__cddir_statistic AS l ON (l.item_id = a.id AND l.extension=\'com_jomestate\')');
// Join over the categories.
$query->join('LEFT', '#__cddir_categories AS c ON c.id = a.categories_id');
$query->join('LEFT', '#__cddir_categories AS e ON e.id = a.categories_address_id');
if ($this->planID->profile=='company'){
$query->join('LEFT', '#__cddir_agent AS ag ON a.users_id = ag.users_id');
$query->join('LEFT', '#__cddir_company AS co ON co.id = ag.company_id');
}
$query->join('LEFT', '#__users AS u ON u.id = a.users_id');
// Filter by published published
$published = $this->getState('filter.published');
if (is_numeric($published)) {
$query->where('a.published = '.(int) $published);
}
// Filter by category.
$categoryId = $this->getState('filter.categories_id');
if (is_numeric($categoryId) && $categoryId!=0) {
$cat_tbl = JTable::getInstance('Category', 'JomcomdevTable');
$cat_tbl->load($categoryId);
$rgt = $cat_tbl->rgt;
$lft = $cat_tbl->lft;
$baselevel = (int) $cat_tbl->level;
$query->where('c.lft >= '.(int) $lft);
$query->where('c.rgt <= '.(int) $rgt);
}
$search = $this->getState('filter.search');
if (!empty($search)) {
if (stripos($search, 'id:') === 0) {
$query->where('a.id = '.(int) substr($search, 3));
} else {
$search = $db->Quote('%'.$db->escape($search, true).'%');
$query->where('(a.title LIKE '.$search.' OR a.alias LIKE '.$search.')');
}
}
if ($this->planID->profile=='company'){
$query->where('(a.users_id ='.(int) $this->user->id.' or co.users_id='.(int) $this->user->id.')');
}
else $query->where('a.users_id ='.(int) $this->user->id);
$sort = $this->getState('list.sort');
switch($sort) {
case 'most_viewed':
$query->order($db->escape('viewSum DESC, a.date_publish DESC'));
break;
case 'alfa':
$query->order($db->escape('a.title, a.date_publish DESC'));
break;
case 'featured':
$query->order($db->escape('a.featured DESC, a.date_publish DESC'));
break;
case 'latest':
default:
$query->order($db->escape('a.date_publish DESC'));
}
$query->group($db->escape('a.id'));
return $query;
}
function getCategories()
{
$cat_array = array(array('v'=>'','t'=>JText::_('COM_JOMESTATE_ADM_ALL')));
$query = "SELECT title, id, level FROM #__cddir_categories WHERE extension='com_jomestate.jomestate' ORDER BY lft";
$data = $this->_getList($query);
foreach ($data as $row):
for ($i=1;$i<$row->level;$i++) $row->title=" ".$row->title;
$temp_array=array('v'=>$row->id,'t'=>$row->title);
array_push($cat_array,$temp_array);
endforeach;
return $cat_array;
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* #since 1.6
*/
protected function populateState($ordering = null, $direction = null)
{
// Initialise variables.
$app = JFactory::getApplication('site');
// Load the parameters.
// $params = $app->getParams();
$params = JComponentHelper::getParams('com_jomestate');
$menu = $app->getMenu();
$this->active = $menu->getActive();
if ($this->active) {
$menuParams = $this->active->params;
$global = $menuParams->get('global_option');
if(!$global) {
$paramsa = $menuParams->toArray();
$paramsb = $params->toArray();
foreach($paramsa AS $key=>$p) $paramsb[$key] = $p;
$newObject = (object) $paramsb;
$newObject->activeItemid = $this->active->id;
$params->loadObject($newObject);
}
}
$this->setState('params', $params);
$limit = $this->getUserStateFromRequest($this->context.'.list.limit', 'jdItemsPerPage', $params->get('listing_per_page'), 'uint');
$this->setState('list.limit', $limit);
$value = $app->getUserStateFromRequest($this->context . '.list.limitstart', 'limitstart', 0);
$limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0);
$this->setState('list.start', $limitstart);
$search = $this->getUserStateFromRequest($this->context.'.filter.search', 'filter_search', '', 'string');
$this->setState('filter.search', $search);
$categoryId = $this->getUserStateFromRequest($this->context.'.filter.categories_id', 'filter_category', '', 'string');
$this->setState('filter.categories_id', $categoryId);
$sort = $this->getUserStateFromRequest($this->context.'.list.sort', 'jdItemsSort', 'latest', 'string');
$this->setState('list.sort', $sort);
}
public function getUserStateFromRequest($key, $request, $default = null, $type = 'none', $resetPage = true)
{
$app = JFactory::getApplication();
$old_state = $app->getUserState($key);
$cur_state = (!is_null($old_state)) ? $old_state : $default;
$new_state = JRequest::getVar($request, $old_state, 'default', $type);
if (($cur_state != $new_state) && ($resetPage))
{
JRequest::setVar('limitstart', 0);
}
// Save the new value only if it is set in this request.
if ($new_state !== null)
{
$app->setUserState($key, $new_state);
}
else
{
$new_state = $cur_state;
}
return $new_state;
}
public function getUser()
{
return $this->user;
}
public function getToolbar()
{
$document = JFactory::getDocument();
$document->addStyleSheet('administrator/templates/system/css/system.css');
$document->addStyleSheet('components/com_jomestate/assets/css/backadmin.css');
$controller='admin_listings';
jimport('joomla.html.toolbar');
$bar = new JToolBar( 'toolbar' );
if(Joomla_Version::if3()) {
$bar->appendButton( 'standard', 'new', JText::_('COM_JOMESTATE_ADM_ADD'), $controller.'.add', false );
$bar->appendButton( 'standard', 'publish', JText::_('COM_JOMESTATE_ADM_PUBLISH'), $controller.'.publish', false );
$bar->appendButton( 'standard', 'unpublish', JText::_('COM_JOMESTATE_ADM_UNPUBLISH'), $controller.'.unpublish', false );
$bar->appendButton( 'standard', 'delete', JText::_('COM_JOMESTATE_ADM_DELETE'), $controller.'.delete', false );
} else {
$bar->appendButton( 'Frontend', 'new', JText::_('COM_JOMESTATE_ADM_ADD'), $controller.'.add', false );
$bar->appendButton( 'Frontend', 'publish', JText::_('COM_JOMESTATE_ADM_PUBLISH'), $controller.'.publish', false );
$bar->appendButton( 'Frontend', 'unpublish', JText::_('COM_JOMESTATE_ADM_UNPUBLISH'), $controller.'.unpublish', false );
$bar->appendButton( 'Frontend', 'delete', JText::_('COM_JOMESTATE_ADM_DELETE'), $controller.'.delete', false );
}
return $bar->render();
}
I have a function getCart which has a complicated query that is merged together. I want to select only one array that is $cart['tee_times'] = array(); and place that array in another function. How can I accomplish this?
Here is a snippet of the query I am trying to pull from.
function getCart($id, DBConnection $connection) {
$query = 'SELECT * FROM cart WHERE IDCart=:cart_id LIMIT 1';
$prepared = array(
"cart_id" => $id
);
$results = $connection->fetch($query, $prepared);
$cart = !empty($results) ? $results[0] : null;
if (isset($cart)) {
$cart['IDCustomer'] = isset($cart['IDCustomer']) ? (int)$cart['IDCustomer'] : null;
$cart['IDDestination'] = isset($cart['IDDestination']) ? (int)$cart['IDDestination'] : null;
$cart['total'] = 0;
$cart['tee_times'] = array();
$cart['rooms'] = array();
$cart['cars'] = array();
$query = '
SELECT
a.*,
e. city_name,
f.IDDestination,
((CASE DATE_FORMAT(a.teetime_dt, "%w")
WHEN 0 THEN b.sun
WHEN 1 THEN b.mon
WHEN 2 THEN b.tue
WHEN 3 THEN b.wed
WHEN 4 THEN b.thu
WHEN 5 THEN b.fri
WHEN 6 THEN b.sat
ELSE 0
END) * a.no_rounds * a.no_golfers) price,
c.tax_rate
FROM cart_course_teetimes a
JOIN course_priceplan b
ON b.IDCoursePricePlan = a.IDCoursePricePlan
JOIN course_tax c
ON c.IDCourseTax = a.IDCourseTax
JOIN course d
ON d.IDCourse = b. IDCourse
JOIN vw_cities e
ON e.IDCity = d. IDCity
JOIN destinations_cities f
ON f.IDCity = e.IDCity
WHERE IDCart=:cart_id
';
$results = $connection->fetch($query, $prepared);
foreach ($results as $row) {
$formatted = array(
'IDCartTeetimes' => (int)$row['IDCartTeetimes'],
'IDCoursePricePlan' => (int)$row['IDCoursePricePlan'],
'IDCourseTax' => (int)$row['IDCourseTax'],
'teetime_date' => $row['teetime_dt'],
'num_golfers' => (int)$row['no_golfers'],
'num_rounds' => (int)$row['no_rounds'],
'price' => (float)$row['price'],
'tax_rate' => (float)$row['tax_rate'],
'city_name' => $row['city_name'],
'IDDestination' => (int)$row['IDDestination'],
);
$cart['tee_times'][] = $formatted;
$cart['total'] += $formatted['price'];
}
Here is my function and my attempt at retrieving the tee_times array
function filterCart($cart_id, DBConnection $connection) {
$cart = getCart($cart_id, $connection);
if (!isset($cart)) {
http_response_code(404);
return 'Cart does not exist.';
}
$results =$cart['tee_times'];
echo $results;
$id = null;
foreach ($results as $row){
var_dump($row['IDDestination']);
If you want to filter out courses that have more than one IDDestination, change the WHERE clause to:
WHERE IDCart = :cart_id
AND IDCart NOT IN (
SELECT IDCart
FROM course a
JOIN destinations_cities b ON b.IDCity = a.IDCity
GROUP BY IDCart
HAVING COUNT(*) > 1)
i have problems when i'm trying to display the result of the following query:
SELECT COUNT(`entity_id` ) icount, `field_tags_tid`, `taxonomy_term_data`.`name`
FROM `field_data_field_tags`
INNER JOIN `taxonomy_term_data`
ON `taxonomy_term_data`.`tid`=`field_data_field_tags`.`field_tags_tid`
GROUP BY `field_tags_tid`
ORDER BY icount DESC
LIMIT 0 , 30
in a custom block in Drupal.
Here is my my_tags.module file:
<?php
function my_tags_block_info() {
$blocks = array();
$blocks['my_first_block'] = array(
'info' => t('My custom block'),
// DRUPAL_CACHE_PER_ROLE will be assumed.
);
return $blocks;
}
function my_tags_block_view($delta = '') {
if (arg(0) == 'node' && is_numeric(arg(1))) {
$nid = arg(1);
};
$block = array();
switch ($delta) {
case 'my_first_block':
$result = db_query('SELECT COUNT(`entity_id` ) icount, `field_tags_tid`, `taxonomy_term_data`.`name`
FROM `field_data_field_tags`
INNER JOIN `taxonomy_term_data`
ON `taxonomy_term_data`.`tid`=`field_data_field_tags`.`field_tags_tid`
GROUP BY `field_tags_tid`
ORDER BY icount DESC
LIMIT 0 , 10');
$list = array(
'#theme' => 'links',
'#links' => array(),
);
foreach ($result as $record) {
$list['#links'][] = array('title' => $record->name , 'name' => $record->icount);
}
$block['subject'] = t('Popular tags');
$block['content'] = $list;
break;
}
return $block;
}
?>
And as a result it is shown only the 'name' field, but i need and the 'icount' field.
Thank you.
Just solved my problem this way:
function my_tags_block_view($delta = '') {
$block = array();
switch ($delta) {
case 'my_first_block':
$result = db_query('SELECT COUNT(`entity_id` ) icount, `field_tags_tid`, `taxonomy_term_data`.`name`, `revision_id`
FROM `field_data_field_tags`
INNER JOIN `taxonomy_term_data`
ON `taxonomy_term_data`.`tid`=`field_data_field_tags`.`field_tags_tid`
GROUP BY `field_tags_tid`
ORDER BY icount DESC
LIMIT 0 , 10');
foreach ($result as $record) {
$list[] = l($record->name, 'taxonomy/term/'.$record->field_tags_tid);
}
dpm($list);
$block['subject'] = t('Popular tags');
$block['content'] = theme('item_list', array('items' => $list));;
break;
}