Drupal 7 hook_menu() throws a 404 - ajax

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"}';
}

Related

CanĀ“t add products to CodeIgniter Cart from another view

I am using codeigniter 2.2.2 with HMVC and a custom session library
I have two views I'll call them V1.php and V2.php for simplicity
and in each view I have a product that can be added to the cart via ajax when you click on the button:
<button class="add-to-cart" id="123" type="button" class="btn btn-fefault cart">
both V1.php and V2.php are sending product details to a controller cart.php to the method add() via ajax
and here is the ajax call in both V1.php and V2.php
$(".add-to-cart").click(function()
{
var target_url = '<?php echo(base_url()."cart/add") ; ?>';
var prod_id = $(this).attr("id");
var qty = 1;
// prepare the data to be sent
var ProductData = {product_id:prod_id,quantity:qty};
$.ajax(
{
url : target_url,
type: "POST",
data : ProductData,
success: function(data)
{
cart = JSON && JSON.parse(data) || $.parseJSON(data);
$("#cart_num").html("( " + cart.num_of_items + " )");
},
error: function(jqXHR, textStatus, errorThrown)
{
$("#cart_notice").show();
$("#cart_notice").html('<pre><code class="prettyprint">AJAX Request Failed<br/> textStatus='+textStatus+', errorThrown='+errorThrown+'</code></pre>');
}
});
// prevent default
return false;
});
and here is the controller cart.php
public function add()
{
$product_id = $this->input->post('product_id');
$quantity = $this->input->post('quantity');
// prepare the array for the cart
$data = array(
'id' => $product_id,
'qty' => $quantity,
'price' => 39.95,
'name' => 'T-Shirt',
'options' => array('Size' => 'L', 'Color' => 'Red')
);
// insert the array in the cart
$cart_flag = $this->cart->insert($data);
//$cart_flag returns false if something went wrong
//$cart_flag returns an id if everything is ok
// prepare the array for the ajax callback function
$cart = array(
'num_of_items' => $this->cart->total_items(),
'total_price' => $this->cart->total()
);
echo json_encode($cart);
}
thanks to debugging tools I could see that :
1.when I add the product from V1.php everything is fine ($cart_flag returns an id)
but
2.when I add the product from V2.php it doesn't add anything ($cart_flag returns FALSE ) although $data is the same in both cases
what I'm I doing wrong ?
the answer was casting, it really gave me a hard time but at last I found it,
the $data looked the same but the type was not
this fixes the problem
$data = array(
'id' => (int)$product_id,
'qty' => (int)$quantity,
'price' => 39.95,
'name' => 'T-Shirt',
'options' => array('Size' => 'L', 'Color' => 'Red')
);
hope this helps someone else with the same issue

Need JSON to pass values to AJAX from specific content type fields

Im new to PHP.
I'd like to build a module and i need json to pass specific content type fields.
Im trying with this but i dont know how to deal with callback function.
here is my ajax in .js
$.ajax({
type: 'GET',
url: '/mappy/ajax/poi',
data: {
nid: nid
},
dataType: 'json',
success: function(data){
alert(data)
}
});
})
here is my php in .module
function mappy_menu() {
$items = array();
$items['/mappy/ajax/poi'] = array(
'title' => 'Mappy Pois',
'page callback' => 'mappy_get',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mpapy_get() {
$nid = $_GET('nid');
$title = field_get_items('node', $node, 'field_title');
$result = json_encode(
db_query("SELECT nid,title FROM {node}", $nid)
);
drupal_json_output($result);
print $result;
}
Many thanks for advice.
Once you get the JSON response you need to convert it to a javascript array. For that, you can do:
var javaArray = $.parseJSON(data);
Now you can retrieve the data, using code like javaArray['key1']['key2'], etc.
.js
$.ajax({
type: 'GET',
// Do not use slash at the beginning, use Drupal.settings.basePath instead
url: Drupal.settings.basePath + 'mappy/ajax/poi',
data: {
nid: nid
},
dataType: 'json',
success: function(data) {
alert(data)
}
});
.module
function mappy_menu() {
$items = array();
// Never use slash at the beginning in hook_menu
$items['mappy/ajax/poi'] = array(
'title' => 'Mappy Pois',
'page callback' => 'mappy_get',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mappy_get() {
$node = node_load($_GET('nid'));
// Or equivalent
/* $node = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->condition('n.nid', $_GET('nid')))
->execute()
->fetchAll(); */
$values = array(
'nid' => $node->nid,
'title' => $node->title
);
#$result = json_encode(
# db_query("SELECT nid,title FROM {node}", $nid)
#);
// drupal_json_output already print the value
// print $result;
drupal_json_output($values);
drupal_exit();
}

Drupal module permissions

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')
);

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.

Drupal menu arguments flexibility

I am using hook_menu to setup a link which I'm calling via JQUERY from an AJAX application.
My hook implementation is as follows:
function staff_filter_menu(){
$items = array();
$items['staff/filtering/results/%'] = array(
'page callback' => 'staff_filter_function',
'page arguments' => array(3),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'delivery callback' => 'staff_filter_deliver',
);
return $items;
}
This link is the point of contact for my ajax app which is a simple textfield where users type in some input. *staff_filter_function* searches the database and returns some matching data. Ajax code is as follows:
$.ajax({
url: Drupal.settings.CALL_BACK + '/' + $(this).val(),
success: function($data){
.... more stuff done here
}
});
It all works perfectly well but for one small detail.
I want to allow a shortcut which will allow all results to display. This shortcut is simply typing a single space.
But, because hook_menu is expecting an argument at the end of the url, my ajax request fails whenever I type in a space. It works perfectly when I type in real content.
This is just for completeness and it a nice to have feature ... if anyone can share some ideas, I'll be very great greatful.
Maybe you don't need to add an argument at the end of the URL.
Just make change you code to the following:
function staff_filter_menu(){
$items = array();
$items['staff/filtering/results'] = array(
'page callback' => 'staff_filter_function',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'delivery callback' => 'staff_filter_deliver',
);
return $items;
and make a slight change to your page callback function
function staff_filter_function($my_arg = "")
{
// your code goes here
}
and you can treat $my_arg as your page argument.
Hope it works,
Muhammad

Resources