[РЕШЕНО] Переменные и функции, видимые в своем модуле

Главные вкладки

Аватар пользователя Shipovnix Shipovnix 28 февраля 2017 в 10:32

Как сделать так, чтобы в самописном модуле в mymodule.module стало возможным видеть и обращаться к глобальным переменным и функциям, видимым из шаблонов? Например, $user, db_update() и т.п.

Комментарии

Аватар пользователя Shipovnix Shipovnix 28 февраля 2017 в 13:09

Нет, db_update я не юзаю в шаблонах. Собрался вот только юзать в модуле. Но функция не видна в mymodule.module.
Конструкция


<?php
global $user;
?>

тоже результатов не дала,

<?php
var_dump
($user);
?>

возвращает NULL.

Аватар пользователя bumble bumble 28 февраля 2017 в 14:21
1

Поясните, что вообще означает "функция не видна в mymodule.module"? Звучит немного бредово...

И, ну, наверно примеры Вашего модуля позволят установить ошибку, так что - лучше выкладывайте код с пояснениями.

Аватар пользователя Shipovnix Shipovnix 28 февраля 2017 в 20:24

Например, вот:

<?php
/**
 * Update product status.
 */
function mymodule_update_product_status($um_pid$um_rid$um_pstatus) {
  if (
$um_pid && $um_rid):
    switch (
$um_pstatus) {
      case 
1:
        
db_update('commerce_product')
          ->
fields(array('status' => 0))
          ->
condition('product_id'$um_pid)
          ->
execute();
        
db_update('commerce_product_revision')
          ->
fields(array('status' => 0))
          ->
condition('revision_id'$um_rid)
          ->
execute();
        echo 
'<div class="goods-sold-wrapper">';
        echo 
t('The goods are sold');
        echo 
'</div>';
        break;
      default:
        
db_update('commerce_product')
          ->
fields(array('status' => 1))
          ->
condition('product_id'$um_pid)
          ->
execute();
        
db_update('commerce_product_revision')
          ->
fields(array('status' => 1))
          ->
condition('revision_id'$um_rid)
          ->
execute();
        echo 
'<div class="goods-published-wrapper">';
        echo 
t('The goods are published');
        echo 
'</div>';
        break;
    }
  else:
    echo 
'<div class="goods-published-wrapper">';
    echo 
t('Update error!');
    echo 
'</div>';
  endif;
}
?>

Это и есть весь модуль. Вызов db_update дает:
Fatal error: Call to undefined function db_update() in Z:\home\uberfish.local\www\sites\all\modules\mymodule\mymodule.module on line 8

Аватар пользователя Andruxa Andruxa 28 февраля 2017 в 20:40
1

Странно.
db_update() определена в файле database.inc и он должен инклудиться во время бутстрапа
http://cgit.drupalcode.org/drupal/tree/includes/bootstrap.inc?h=7.x#n2730

mymodule_update_product_status() когда и откуда вызывается?

И не проще ли было сделать:

$product = commerce_product_load($um_pid);
$product->status = FALSE;
commerce_product_save($product);
Аватар пользователя Shipovnix Shipovnix 28 февраля 2017 в 21:03

Цепочка такова (наверняка много чего сделано неправильно).
С шаблона ноды по событию onclick на input-кнопке вызывается js-функция с ajax-запросом:


<?php
$module_path 
drupal_get_path('module''mymodule');
drupal_add_js($module_path '/js/updstatus.js');
$updst_param $pid "," $p_revid "," $p_status ",'" $module_path "/func/updstatus.php'";
echo 
'<div class="sell-product">';
echo 
'<input class="button-sell-product" value="' t('Selling goods') . '" onclick="sellGoods(' $updst_param ')" type="button" />';
?>

Сама js-функция:

function sellGoods(pid,rid,pstatus,updstphp) {
        nocache = Math.random();
        http.open('get', '/' + updstphp + '?pid=' + pid + '&rid=' + rid + '&pstatus=' + pstatus + '&nocache= ' + nocache);
        http.onreadystatechange = insertReply;
        http.send(null);
}

http - объект XMLHttpRequest. По http-open открывается /mymodule/func/updstatus.php:


<?php
include '../mymodule.module';
$get_pid intval(filter_input(INPUT_GET'pid'));
$get_rid intval(filter_input(INPUT_GET'rid'));
$get_pstatus = (bool) filter_input(INPUT_GET'pstatus');
echo 
'<br/>';
echo 
'PID=' $get_pid ', RID=' $get_rid ', Current PStatus = ' $get_pstatus;
echo 
'<br/>';
mymodule_update_product_status($get_pid$get_rid$get_pstatus);
?>

Ну и здесь уже и запускаем функцию из модуля.

Аватар пользователя Andruxa Andruxa 28 февраля 2017 в 21:18
1

Ага, ясно.
У вас модуль дёргается в обход бутстрапа.
Объявите коллбек через hook_menu()
И было бы неплохо проверять права-роль пользователя, а то все желающие будут публиковать-депубликовать продукты.

Аватар пользователя Andruxa Andruxa 28 февраля 2017 в 21:28
1

В шаблоне - недостаточно.
Путь /func/updstatus.php - существует независимо от того, выводится он в шаблоне или нет.

Аватар пользователя Shipovnix Shipovnix 28 февраля 2017 в 21:42

Само собой, в шаблоне проверка роли нужна больше для необходимости отрисовки доп. контролов для админа, а отправить /mymodule/func/updstatus.php?pid=1&rid=1&status=1 сможет любой школьник. Поэтому только в модуль.

Аватар пользователя Andruxa Andruxa 28 февраля 2017 в 21:37
1

Shipovnix wrote:

С шаблона ноды по событию onclick на input-кнопке вызывается js-функция с ajax-запросом:

Вы в node.tpl.php добавляете input?
Если он не находится внутри формы - это невалидное решение.
Если же вы в шаблоне добавляете html-код формы, то решение неправильное.
Почитатйте про Form API
Кстати, если делать форму правильно, то можно навесить на элементы формы свои ajax-коллбеки, и hook_menu не потребуется.

Аватар пользователя Shipovnix Shipovnix 1 марта 2017 в 7:50

Через hook_menu - не получилось. Sad
Понял, что иду неправильным путем. Если не трудно, объясните мне цепочку действий для реализации такой схемы:
Шаблон ноды -> Если есть роль, то надо отрисовать форму с input'ом, на onclick которого навешивается js-функция с ajax-запросом на сервер -> На сервере выполняется php-функция, которая совершит манипуляции с БД.

Аватар пользователя Andruxa Andruxa 1 марта 2017 в 8:42
1

В hook_menu() объявляется путь и функция, которая будет вызываться по GET-запросу по этому пути:

<?php
/**
 * Implements hook_menu().
 */
function mymodule_menu() {
  
$items = array();
  
$items['mymodule/func/updstatus'] = array(
    
'title' => 'my module callback',
    
'page callback' => 'mymodule_callback_function'// функция, которая будет вызываться
    
'access arguments' => array('mymodule callback access'), // права доступа для пользовательской роли
    
'type' => MENU_CALLBACK,
  );
  return 
$items;
}
?>

Соотвественно, право доступа 'mymodule callback access' надо указать в hook_permission()

<?php
/**
 * Implements hook_permission().
 */
function mymodule_permission() {
  
$permissions = array(
    
'mymodule callback access' => array(
      
'title' => t('Change product status by mymodule'),
      
'description' => t('Change product status by mymodule'),
    ),
  );
  return 
$permissions;
}
?>

И, разумеется, надо определить сам коллбек:

<?php
function mymodule_callback_function() {
   
//something to do
}?>

После сброса кеша, при GET-запросе по пути /mymodule/func/updstatus будет либо вызываться функция mymodule_callback_function(), либо будет отдаваться 403 - если у пользователя нет права 'Change product status by mymodule'

Аватар пользователя gun_dose gun_dose 1 марта 2017 в 9:44
1

Не будет работать по двум причинам:
1. В хук меню надо добавить
<?php 'delivery callback' => 'ajax_deliver',?>
2. Там где выводим аяксовый элемент, надо добавить библиотеку
<?php drupal_add_library('system''drupal.ajax'); ?>

Это если без форм. Если с формой, то да, хук меню не нужен. Но саму форму нужно объявить в отдельной функции, потом в шаблоне или препроцессе вызвать её через drupal_get_form.

А вот это:
«Что касается инпута на странице ноды - самый простой вариант сделать его div'ом чтобы html оставался валидным, разукрасить его под кнопку и навесить js-обработчик на клик.»
полный бред.

Аватар пользователя Andruxa Andruxa 1 марта 2017 в 8:49
1

Что касается инпута на странице ноды - самый простой вариант сделать его div'ом чтобы html оставался валидным, разукрасить его под кнопку и навесить js-обработчик на клик.

Аватар пользователя Shipovnix Shipovnix 1 марта 2017 в 8:59

Andruxa, огромное человеческое спасибо. Разложено по полочкам, что никак не удавалось разложить самому при чтении с англоязычных ресурсов.