Getting a menu delivered via REST - rest

I am trying to get a menu via REST and I've created a new module and rest resource plugin that allows for GET on /entity/restmenu/{menu_name}.
I can successfully return this example json using this function when I hit the URL.
public function get(EntityInterface $entity) {
$result = array();
for ($i = 0; $i < 10; $i++) {
$temp = array(
'title' => 'Test ' . $i,
'href' => '#/' . $i
);
array_push($result, $temp);
}
return new ResourceResponse(json_encode($result));
}
I cannot figure out how to load the menu based on $entity. If I hit my URL (http://dang.dev:8888/entity/restmenu/main?_format=hal_json) $entity's value is 'main' which is the machine name of the main menu.
I've tried using Drupal menu tree, but I am not having luck, and debugging this thing with only JSON responses is quite difficult.
How do I get menu item titles and paths based on the menu machine name?
EDIT
Ok, sort of figured it out.
public function get($entity) {
$menu_name = $entity;
$menu_parameters = \Drupal::menuTree()->getCurrentRouteMenuTreeParameters($menu_name);
$tree = \Drupal::menuTree()->load($menu_name, $menu_parameters);
$renderable = \Drupal::menuTree()->build($tree);
$result = array();
foreach (end($renderable) as $key => $val) {
$temp = array(
'menu_item' => $val,
'route' => $key
);
array_push($result, $temp);
}
return new ResourceResponse(json_encode($result));
}
Right now that will output:
[
{
"menu_item":{
"is_expanded":false,
"is_collapsed":false,
"in_active_trail":false,
"attributes":"",
"title":"Home",
"url":{
},
"below":[
],
"original_link":{
}
},
"route":"standard.front_page"
},
{
"menu_item":{
"is_expanded":false,
"is_collapsed":false,
"in_active_trail":false,
"attributes":"",
"title":"Communities",
"url":{
},
"below":[
],
"original_link":{
}
},
"route":"menu_link_content:139d0413-dc50-4772-8200-bc6c92571fa7"
}
]
any idea why url or original_link are empty?

This was the correct answer:
public function get($entity) {
$menu_name = $entity;
$menu_parameters = \Drupal::menuTree()->getCurrentRouteMenuTreeParameters($menu_name);
$tree = \Drupal::menuTree()->load($menu_name, $menu_parameters);
$result = array();
foreach ($tree as $element) {
$link = $element->link;
array_push($result, array(
'title' => $link->getTitle(),
'url' => $link->getUrlObject()->getInternalPath(),
'weight' => $link->getWeight()
)
);
}
return new ResourceResponse(json_encode($result));
}

Related

Moodle File Manager - Crucial part

I am trying to show the file uploaded from File Manager mform element. I could store the file to mdl_files. To get the file saved is a bit hard to program. I tried implementing few options from Moodle Forums, but was stuck here. I really hope that someone can provide a solution for Moodle File manager (a crucial part). Could anyone guide me where I went wrong and suggest me to get the fileurl.
<?php
require('config.php');
require_once($CFG->libdir.'/formslib.php');
class active_form extends moodleform {
function definition() {
$mform = $this->_form;
$fileoptions = $this->_customdata['fileoptions'];
$mform->addElement('filemanager', 'video', get_string('video', 'moodle'), null,
$fileoptions);
$this->add_action_buttons();
}
function validation($data, $files) {
$errors = parent::validation($data, $files);
return $errors;
}
}
// Function for local_statistics plugin.
function local_statistics_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload,
array $options=array()) {
global $DB;
if ($context->contextlevel != CONTEXT_SYSTEM) {
return false;
}
$itemid = (int)array_shift($args);
if ($itemid != 0) {
return false;
}
$fs = get_file_storage();
$filename = array_pop($args);
if (empty($args)) {
$filepath = '/';
} else {
$filepath = '/'.implode('/', $args).'/';
}
$file = $fs->get_file($context->id, 'local_statistics', $filearea, $itemid, $filepath,$filename);
if (!$file) {
return false;
}
// finally send the file
send_stored_file($file, 0, 0, true, $options); // download MUST be forced - security!
}
// Form Settings
$fileoptions = array('maxbytes' => 0, 'maxfiles' => 1, 'subdirs' => 0, 'context' =>
context_system::instance());
$data = new stdClass();
$data = file_prepare_standard_filemanager($data, 'video', $fileoptions, context_system::instance(),
'local_statistics', 'video', 0);
$mform = new active_form(null, array('fileoptions' => $fileoptions));
// Form Submission
if ($data = $mform->get_data()) {
$data = file_postupdate_standard_filemanager($data, 'video', $fileoptions,
context_system::instance(), 'local_statistics', 'video', 0);
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'local_statistics', 'video', '0', 'sortorder', false);
foreach ($files as $file) {
$fileurl = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
$file->get_filearea(), $file->get_itemid(), $file->get_filepath(),
$file->get_filename());
echo $fileurl;
}
}
?>
I've had a quick look through your code and it all looks reasonable, but you've not included the code of the local_statistics_pluginfile() function in local/statistics/lib.php - without that function, Moodle is unable to authenticate any requests from the browser to serve files, so all files will return a 'file not found' message.
Have a look at the documentation for details of what the x_pluginfile function should look like (or look for examples in any of the core plugins in Moodle): https://docs.moodle.org/dev/File_API#Serving_files_to_users

How to add variable to header.php controller and use it in header.tpl

I am creating a custom theme for OpenCart 2.3 and I need to show some additional information in page header (header.tpl). So I added some variable to catalog/controller/common/header.php:
$data['some_var'] = 'some_value';
And then I am trying to use this data in the header.tpl:
<?php echo $this->data['some_var']; ?>
But I am always getting this error:
Notice: Undefined index: some_var in /var/www/store_com/public_html/catalog/view/theme/mystore/template/common/header.tpl on line 133
If I try to use this code:
<?php echo $some_var; ?>
Then I am getting another error:
Notice: Undefined variable: some_var in /var/www/store_com/public_html/catalog/view/theme/mystore/template/common/header.tpl on line 133
And even when I do echo print_r($this->data) in header.tpl I don't even see this variable in $data array.
What am I doing wrong? Please help.
EDIT
Here is the full code of my header.php controller file. I added my custom variable at the very end of the file.
class ControllerCommonHeader extends Controller {
public function index() {
// Analytics
$this->load->model('extension/extension');
$data['analytics'] = array();
$analytics = $this->model_extension_extension->getExtensions('analytics');
foreach ($analytics as $analytic) {
if ($this->config->get($analytic['code'] . '_status')) {
$data['analytics'][] = $this->load->controller('extension/analytics/' . $analytic['code'], $this->config->get($analytic['code'] . '_status'));
}
}
if ($this->request->server['HTTPS']) {
$server = $this->config->get('config_ssl');
} else {
$server = $this->config->get('config_url');
}
if (is_file(DIR_IMAGE . $this->config->get('config_icon'))) {
$this->document->addLink($server . 'image/' . $this->config->get('config_icon'), 'icon');
}
$data['title'] = $this->document->getTitle();
$data['base'] = $server;
$data['description'] = $this->document->getDescription();
$data['keywords'] = $this->document->getKeywords();
$data['links'] = $this->document->getLinks();
$data['styles'] = $this->document->getStyles();
$data['scripts'] = $this->document->getScripts();
$data['lang'] = $this->language->get('code');
$data['direction'] = $this->language->get('direction');
$data['name'] = $this->config->get('config_name');
if (is_file(DIR_IMAGE . $this->config->get('config_logo'))) {
$data['logo'] = $server . 'image/' . $this->config->get('config_logo');
} else {
$data['logo'] = '';
}
$this->load->language('common/header');
$data['text_home'] = $this->language->get('text_home');
// Wishlist
if ($this->customer->isLogged()) {
$this->load->model('account/wishlist');
$data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), $this->model_account_wishlist->getTotalWishlist());
} else {
$data['text_wishlist'] = sprintf($this->language->get('text_wishlist'), (isset($this->session->data['wishlist']) ? count($this->session->data['wishlist']) : 0));
}
$data['text_shopping_cart'] = $this->language->get('text_shopping_cart');
$data['text_logged'] = sprintf($this->language->get('text_logged'), $this->url->link('account/account', '', true), $this->customer->getFirstName(), $this->url->link('account/logout', '', true));
$data['text_account'] = $this->language->get('text_account');
$data['text_register'] = $this->language->get('text_register');
$data['text_login'] = $this->language->get('text_login');
$data['text_order'] = $this->language->get('text_order');
$data['text_transaction'] = $this->language->get('text_transaction');
$data['text_download'] = $this->language->get('text_download');
$data['text_logout'] = $this->language->get('text_logout');
$data['text_checkout'] = $this->language->get('text_checkout');
$data['text_category'] = $this->language->get('text_category');
$data['text_all'] = $this->language->get('text_all');
$data['home'] = $this->url->link('common/home');
$data['wishlist'] = $this->url->link('account/wishlist', '', true);
$data['logged'] = $this->customer->isLogged();
$data['account'] = $this->url->link('account/account', '', true);
$data['register'] = $this->url->link('account/register', '', true);
$data['login'] = $this->url->link('account/login', '', true);
$data['order'] = $this->url->link('account/order', '', true);
$data['transaction'] = $this->url->link('account/transaction', '', true);
$data['download'] = $this->url->link('account/download', '', true);
$data['logout'] = $this->url->link('account/logout', '', true);
$data['shopping_cart'] = $this->url->link('checkout/cart');
$data['checkout'] = $this->url->link('checkout/checkout', '', true);
$data['contact'] = $this->url->link('information/contact');
$data['telephone'] = $this->config->get('config_telephone');
// Menu
$this->load->model('catalog/category');
$this->load->model('catalog/product');
$data['categories'] = array();
$categories = $this->model_catalog_category->getCategories(0);
foreach ($categories as $category) {
if ($category['top']) {
// Level 2
$children_data = array();
$children = $this->model_catalog_category->getCategories($category['category_id']);
foreach ($children as $child) {
$filter_data = array(
'filter_category_id' => $child['category_id'],
'filter_sub_category' => true
);
$children_data[] = array(
'name' => $child['name'] . ($this->config->get('config_product_count') ? ' (' . $this->model_catalog_product->getTotalProducts($filter_data) . ')' : ''),
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
);
}
// Level 1
$data['categories'][] = array(
'name' => $category['name'],
'children' => $children_data,
'column' => $category['column'] ? $category['column'] : 1,
'href' => $this->url->link('product/category', 'path=' . $category['category_id'])
);
}
}
$data['language'] = $this->load->controller('common/language');
$data['currency'] = $this->load->controller('common/currency');
$data['search'] = $this->load->controller('common/search');
$data['cart'] = $this->load->controller('common/cart');
// For page specific css
if (isset($this->request->get['route'])) {
if (isset($this->request->get['product_id'])) {
$class = '-' . $this->request->get['product_id'];
} elseif (isset($this->request->get['path'])) {
$class = '-' . $this->request->get['path'];
} elseif (isset($this->request->get['manufacturer_id'])) {
$class = '-' . $this->request->get['manufacturer_id'];
} elseif (isset($this->request->get['information_id'])) {
$class = '-' . $this->request->get['information_id'];
} else {
$class = '';
}
$data['class'] = str_replace('/', '-', $this->request->get['route']) . $class;
} else {
$data['class'] = 'common-home';
}
//CUSTOM THEME VARIABLES BEGIN
$data['some_var'] = 'some_value';
//CUSTOM THEME VARIABLES END
return $this->load->view('common/header', $data);
}
}
I need to see your controller to get the full picture and then i will give you the full answer, but take a look on your controller and make sure that you bind your data like the sample below:
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/common/header.tpl')) {
return $this->load->view($this->config->get('config_template') . '/template/common/header.tpl', $data);
} else {
return $this->load->view('default/template/common/header.tpl', $data);
}
Thanks
I finally found the solution of my problem, but I am not sure if it is the right way to do this. I found that I need to make changes in system/storage/modification/catalog/controller/common/header‌​.php. It seems like after installing some extension via Vqmod the controller file have been copied to this folder. If I add my variables there then I can access them without any issues.

How do I attach a pdf file to a Gravity Forms Notification?

Gravity forms offers a way to attach files from the file uploader (See code below), but how would I change this code to simply attach my own PDF file from either a hidden field value or simply paste the pdf file within this code? I tried a few things but it didn't work. Any help would be appreciated!
add_filter( 'gform_notification', 'change_user_notification_attachments', 10, 3 );
function change_user_notification_attachments( $notification, $form, $entry ) {
//There is no concept of user notifications anymore, so we will need to target notifications based on other criteria, such as name
if ( $notification['name'] == 'User Notification' ) {
$fileupload_fields = GFCommon::get_fields_by_type( $form, array( 'fileupload' ) );
if(!is_array($fileupload_fields))
return $notification;
$attachments = array();
$upload_root = RGFormsModel::get_upload_root();
foreach( $fileupload_fields as $field ) {
$url = $entry[ $field['id'] ];
$attachment = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $url );
if ( $attachment ) {
$attachments[] = $attachment;
}
}
$notification['attachments'] = $attachments;
}
return $notification;
}
Based on that code, something like this should work. Replace the $url value with the URL to your PDF.
add_filter( 'gform_notification', 'change_user_notification_attachments', 10, 3 );
function change_user_notification_attachments( $notification, $form, $entry ) {
if ( $notification['name'] == 'User Notification' ) {
$url = 'http://yoursite.com/path/to/file.pdf';
$notification['attachments'][] = $url;
}
return $notification;
}

CGI::Session Randomly Logging Users Out

Here is my authentication logic:
sub user_logon {
my ($dbh, $cgi, $cache, $logout) = #_;
#use Log::Log4perl qw(:easy);
#Log::Log4perl->easy_init($DEBUG);
my $session = new CGI::Session("driver:MySQL", $cgi, {Handle=>$dbh});
$session->expires("+3h");
my $auth = new CGI::Session::Auth::DBI({
CGI => $cgi,
Session => $session,
IPAuth => 1,
DBHandle => $dbh,
#Log => 1,
});
if($logout) {
$auth->logout();
}
else {
$auth->authenticate();
if($auth->loggedIn) {
my $user = Cherry::Schema::ResultSet::Employee::get_employee($dbh, $cache, { number => $auth->{userid} });
if (!$user->{active}) {
return { error => $user->{name} . ' is not an active employee.' };
}
$user->{cookie} = $auth->sessionCookie();
return $user;
}
elsif($cgi->param('action') eq 'logon') {
if($cgi->param('log_username') && $cgi->param('log_username')) {
return { error => 'Your username and/or password did not match.' };
}
elsif(!$cgi->param('log_username') || !$cgi->param('log_username')) {
return { error => 'Please enter a username and a password.' };
}
}
else {
return { error => 'You are not logged in' };
}
}
}
sub handle_authentication {
my ($dbh, $cache, $config, $params, $cgi) = #_;
if(($cgi->param('auth') || '') eq 'super_user') { # for automation
return;
}
if(($params->{action} || '') eq 'log_off') {
user_logon($dbh, $cgi, $cache, 1); # 1 means log out
login_form($config, 'Successfully logged out', $params->{login_url}, $params->{title});
}
my $user = user_logon($dbh, $cgi, $cache);
if(exists $user->{error}) {
login_form($config, $user->{error}, $params->{login_url}, $params->{title});
}
elsif($user->{number}) {
return $user;
}
}
Then in my code, every time I print a header, it looks something like this:
my $user = Cherry::Authentication::handle_authentication(
$dbh,
$cache,
\%config,
{
action => $FORM{action},
username => $FORM{log_username},
password => $FORM{log_password},
auth => $FORM{auth}
},
$cgi
);
print header(
-type => 'application/json',
-cookie => $user->{cookie}
);
The problem is that this code seems to work very well about 80% of the time. The other 20%, users are getting kicked out (and not after being stale for 3 hours).
Are there any obvious flaws in this code? Have I left any crucial code out?
If you feel is there not enough information here to give a viable solution, do you have any general suggestions on what can be done to troubleshoot these types of issues?
With this particular problem, there was some code in play that I was unaware of.
$cookie = CGI::Cookie->new(
-name => $session->name, # problem line
-value => $session->id, # problem line
-expires => '+1y',
-path => '/',
-secure => 0,
);
my #header = (
-cookie => $cookie,
-type => 'text/html',
-status => $status
);
print $cgi->header( #header );
The lines with the comments #problem line were assigning a new session even when one already existed.
I installed Fiddler HTTP Debugger on the user's computer that seemed to have the issue the most. Then, once the user was unexpectedly logged out, I reviewed the logs. I was able to find a correlation between the user visiting one url, and the unexpected log out on the next request.

how to query eXist using XPath?

I decided to use eXist as a database for an application that I am writing in Perl and
I am experimenting with it. The problem is that I have stored a .xml document with the following structure
<foo-bar00>
<perfdata datum="GigabitEthernet3_0_18">
<cli cmd="whatsup" detail="GigabitEthernet3/0/18" find="" given="">
<input_rate>3</input_rate>
<output_rate>3</output_rate>
</cli>
</perfdata>
<timeline>2011-5-23T11:15:33</timeline>
</foo-bar00>
and it is located in the "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" collection.
I can successfully query it, like
my $xquery = 'doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")' ;
or $xquery can be equal to
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/perfdata/cli/data(output_rate)
or
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/data(timeline)
my ($rc1, $set) = $eXist->executeQuery($xquery) ;
my ($rc2, $count) = $eXist->numberOfResults($set) ;
my ($rc3, #data) = $eXist->retrieveResults($set) ;
$eXist->releaseResultSet($set) ;
print Dumper(#data) ;
And the result is :
$VAR1 = {
'hitCount' => 1,
'foo-bar00' => {
'perfdata' => {
'cli' => {
'given' => '',
'detail' => 'GigabitEthernet3/0/18',
'input_rate' => '3',
'cmd' => 'whatsup',
'output_rate' => '3',
'find' => ''
},
'datum' => 'GigabitEthernet3_0_18'
},
'timeline' => '2011-5-23T11:15:33'
}
};
---> Given that I know the xml document that I want to retrieve info from.
---> Given that I want to retrieve the timeline information.
When I am writing :
my $db_xml_doc = "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" ;
my ($db_rc, $db_datum) = $eXist->queryXPath("/foo-bar00/timeline", $db_xml_doc, "") ;
print Dumper($db_datum) ;
The result is :
$VAR1 = {
'hash' => 1717362942,
'id' => 3,
'results' => [
{
'node_id' => '1.2',
'document' => '/db/LAB/foo-bar00/2011/5/23/11_15_33.xml'
}
]
};
The question is : How can I retrieve the "timeline" info ? Seems that the "node_id" variable (=1.2) can points to the "timeline" info, but how can I use it ?
Thank you.
use XML::LibXML qw( );
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('a.xml');
my $root = $doc->documentElement();
my ($timeline) = $root->findnodes('timeline');
if ($timeline) {
print("Exists: ", $timeline->textContent(), "\n");
}
or
my ($timeline) = $root->findnodes('timeline/text()');
if ($timeline) {
print("Exists: ", $timeline->getValue(), "\n");
}
I could have used /foo-bar00/timeline instead of timeline, but I didn't see the need.
Don't know if you're still interested, but you could either retrieve the doc as DOM and apply an xquery to the DOM, or, probably better, only pull out the info you want in the query that you submit to the server.
Something like this:
for $p in doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")//output_rate
return
<vlaue>$p</value>