Drupal module permissions - ajax

When I run the code with an admin user, the module returns what it should. However, when I run it with a normal user, I get a 403 error. The module returns data from an AJAX call. I've already tried adding a 'access callback' => 'user_access'); line to the exoticlang_chat_logger_menu() function. I'd appreciate any pointers you might have.
Thanks for the help
The AJAX call:
jQuery.ajax({
type: 'POST',
url: '/chatlog',
success: exoticlangAjaxCompleted,
data:'messageLog=' + privateMessageLogJson,
dataType: 'json'
});
The module code:
function exoticlang_chat_logger_init(){
drupal_add_js('misc/jquery.form.js');
drupal_add_library('system', 'drupal.ajax');
}
function exoticlang_chat_logger_permission() {
return array(
'Save chat data' => array(
'title' => t('Save ExoticLang Chat Data'),
'description' => t('Send private message on chat close')
),
);
}
/**
* Implementation of hook_menu().
*/
function exoticlang_chat_logger_menu() {
$items = array();
$items['chatlog'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'exoticlang_chat_log_ajax',
'access arguments' => 'Save chat data');
//'access callback' => 'user_access');
return $items;
}
function exoticlang_chat_logger_ajax(){
$messageLog=stripslashes($_POST['messageLog']);
$chatLog= 'Drupal has processed this. Message log is: '.$messageLog;
$chatLog=str_replace('":"{[{','":[{',$chatLog);
$chatLog=str_replace(',,',',',$chatLog);
$chatLog=str_replace('"}"','"}',$chatLog);
$chatLog=str_replace('"}]}"','"}]',$chatLog);
echo json_encode(array('messageLog' => $chatLog));
// echo $chatLog;
echo print_r(privatemsg_new_thread(array(user_load(1)), 'The subject', 'The body text'));
drupal_exit();
}

access arguments needs to be an array:
$items['chatlog'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'exoticlang_chat_log_ajax',
'access arguments' => array('Save chat data')
);

Related

Drupal 7 hook_menu() throws a 404

I have tried to acces it through an ajax call and by simply going to it by url,
It always give me a 404
i have flushed my caches multiple times and even tried to remove and re-add the module (as i have had the problem with other modules and read on other responses on the problem)
i also have looked it up on internet, but i can't seem to find any solution
(module name : TTK_rest)
.module:
function TTK_rest_menu() {
$items = array();
$items['TTK_rest_api/TTK_task_progression'] = array(
'page callback' => 'TTK_task_progression_view',
'access arguments' => array('access content'),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function TTK_task_progression_view(){
return '{"pom":"pom"}';
}
and the ajax call to it:
$.ajax({
url:'/TTK_rest_api/TTK_task_progression',
data: {"getProgress": "true"},//, "event_id":settings['TTK_task_progression']['jsEvent_id']
type: "POST",
contentType: "JSON",
success: function(data){
var $data = $(data);
console.log(data);
},
error: function(err){
console.log("neupe, try again");
}
});
finally found the solution (posted the question after multiple hours of searching, if i've known i would have find an answer this quick i wouldn't have asked it.. still going to leave it up with a response in case there is someone with the same problem
solution to the problem was that i had to have my function name had to have the module name prefix
note: i have an other module called 'TTK_task_progression', might be the origin of the problem i had
solution:
function TTK_rest_menu() {
$items = array();
$items['TTK_rest_api/TTK_task_progression'] = array(
'page callback' => 'TTK_rest_progression', // <- changed
'access arguments' => array('access content'),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function TTK_rest_progression(){ // <- changed
return '{"pom":"pom"}';
}

ZF2 using inputFilter

I wonder what I've made wrong, I want to save in db some values whats not come form POST or GET:
public function saveAction()
{
$wikiTable = $this->getServiceLocator()->get('WikiTable');
$data = array('source' => $someVal);
$form = new WikiForm();
$inputFilter = new \MyApp\Form\WikiFilter();
$form->setInputFilter($inputFilter);
$form->setData($data);
$this->saveWiki($form->getData());
//$this->saveWiki($data);
}
WikiFilter:
$this->add(
array(
'name' => 'source',
'required' => false,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
)
)
);
And Form:
$this->add(array(
'name' => 'source',
'type' => 'Zend\Form\Element\Hidden',
'options' => array(
'label' => 'source',
)
));
In response I recive error:
Zend\Form\Form::getData cannot return data as validation has not yet
occurred
After this line:
$form->setData($data);
You need to put the rest of your code into something like this:
if($form->isValid()){
$this->saveWiki($form->getData());
}
Otherwise your form isn't validated and you won't get any data back from it by calling $form->getData()
So whenever you work with a form (not matter if the data come from a POST request or not) make sure to call the function isValid() on the form variable because otherwise you won't get the data back and you will get the error you wrote before

How to execute a method in AJAX with Symfony2 when passing JavaScript arguments?

I'm getting confused by AJAX/S2 when I need to pass some arguments retrieved with JavaScript to a method in the controller.
In my script I have at some point, I get the position var:
function handle_geolocation_query(position){
alert('Lat: ' + position.coords.latitude + ' ' +
'Lon: ' + position.coords.longitude);
$.when( getLakes(position.coords.latitude, position.coords.longitude)).done(function(result1) {
console.log(result1);
});
};
function getLakes(lat, long) {
return $.ajax({
url: "{{ path('getLakes') }}",
data: { lat:lat, lng: lng },
dataType: 'jsonp'
});
};
then the router is set that way:
getLakes:
pattern: /lakes
defaults: { _controller: PondipGeolocBundle:Default:getLakesSurrounding }
And In my controller I'm supposed to return an array:
public function getLakesSurrounding($lat=0, $lng=0, $limit = 50, $distance = 50, $unit = 'km')
{
$lat = $this->getRequest()->get('lat');
$lng = $this->getRequest()->get('lont');
$return= array( '1'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'2'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'3'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'4'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'5'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4')
);
$return=json_encode($return); //jscon encode the array
return new Response($return,200,array('Content-Type'=>'application/json')); //make sure it has the correct content type
}
And then I'd like to pass it to another function that would set up the template with moustache to print it in the view (I'm not here yet ..)
My question is: I can't pass the needed lat and long data to my function. the router gets mad, the controller doesnt get anything and I don't get anything back from that script.
EDIT:I found my way to pass the variables, but I still can't get any response from my controller, nohing happen and the $.when does not execute any callback
I'm fairly new with AJAX, please advise.
Have a look at FOSJsRoutingBundle. With it you can use router from JS:
Routing.generate('my_route_to_expose', { "id": 10, "foo": "bar" });

Hook_menu selective menu tab display

I am using the following code to include a custom tab for my node types:
function mymodule_menu(){
$items['node/%node/register'] = array(
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK,
'title' => 'Register',
);
return $items;
}
This has the effect of including a register tab for every node type. However, I need to include that tab for only page types and exclude it on all other type like article types etc.
What other directions can I consider?
The easiest way would be to provide your own access callback that checks the node type, e.g.
function mymodule_menu(){
$items['node/%node/register'] = array(
'page arguments' => array(1),
'access callback' => 'mymodule_node_register_tab_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'title' => 'Register',
);
return $items;
}
function mymodule_node_register_tab_access($node) {
$valid_types = array('page');
return in_array($node->type, $valid_types);
}

How to "print" a theme during AJAX request (Drupal)

When users click on a button (with id graph), I'd like to fill the default Drupal content div (<div class="content">) with a graphael instance.
The JavaScript:
jQuery(document).ready(function($) {
$('#toggle #graph').click(function() {
$.ajax({
url: "http://www.mysite.com/?q=publications/callback",
type: 'POST',
data: {
'format' : 'graph'
},
success: function(response) {
$('div#content div.content').html(response);
}
});
});
});
The PHP:
$items['publications/callback'] = array(
'type' => MENU_CALLBACK,
'title' => 'All Publications Callback',
'page callback' => '_process_publications',
'page arguments' => array(t('journal')),
'access callback' => TRUE,
);
which leads to the page callback: (I'm concerned with the if code block)
function _process_publications($venue) {
if( isset($_POST['format']) && $_POST['format'] == "graph" ){
_make_bar_chart($venue);
}
elseif( isset($_POST['format']) && $_POST['format'] == "list" ) {
_make_list($venue);
}
else{
return("<p>blah</p>");
}
}
and finally the function called within the callback function:
function _make_bar_chart($venue) {
// get active database connection
$mysql = Database::getConnection();
// if connection is successful, proceed
if($mysql){
// do stuff
$graphael = array(
'method' => 'bar',
'values' => $ycoordinates,
'params' => array(
'colors' => $colors,
'font' => '10px Arial, sans-serif',
'opts' => array(
'gutter' => '20%',
'type' => 'square',
),
'label' => array(
'values' => $xcoordinates,
'isBottom' => true,
),
),
'extend' => array(
'label' => array(
'values' => $ycoordinates,
'params' => array('attrText' => array(
'fill' => '#aaa',
'font' => '10px Arial, sans-serif',
)),
),
),
);
return theme('graphael', $graphael);
}
// else, connection was unsuccessful
else{
print("<p>bad connection</p>");
}
}
THE PROBLEM: returning a theme doesn't really send anything back to the AJAX request (unlike print statements). I tried to print the theme, but that produces a white screen of death. How would I generate the graph without printing something?
Much thanks to nevets on the Drupal forums for the helpful hint: http://drupal.org/node/1664798#comment-6177944
If you want to use AJAX with Drupal, you are best off actually using Drupal-specific AJAX-related functions. In my theme's page.tpl.php file, I added the following to make the links which would call AJAX:
<?php
// drupal_add_library is invoked automatically when a form element has the
// '#ajax' property, but since we are not rendering a form here, we have to
// do it ourselves.
drupal_add_library('system', 'drupal.ajax');
// The use-ajax class is special, so that the link will call without causing
// a page reload. Note the /nojs portion of the path - if javascript is
// enabled, this part will be stripped from the path before it is called.
$link1 = l(t('Graph'), 'ajax_link_callback/graph/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link2 = l(t('List'), 'ajax_link_callback/list/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link3 = l(t('Create Alert'), 'ajax_link_callback/alert/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$output = "<span>$link1</span><span>$link2</span><span>$link3</span><div id='myDiv'></div>";
print $output;
?>
When one of the links above is clicked, the callback function is called (e.g. ajax_link_callback/graph):
// A menu callback is required when using ajax outside of the Form API.
$items['ajax_link_callback/graph'] = array(
'page callback' => 'ajax_link_response_graph',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
.. and the callback to which it refers:
function ajax_link_response_graph($type = 'ajax') {
if ($type == 'ajax') {
$output = _make_bar_chart('journal');
$commands = array();
// See ajax_example_advanced.inc for more details on the available commands
// and how to use them.
$commands[] = ajax_command_html('div#content div.content', $output);
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
else {
$output = t("This is some content delivered via a page load.");
return $output;
}
}
This replaces any HTML within <div class="content"> with the graphael chart returned from _make_bar_chart above.

Resources