[Решено] Как открыть доступ к полю после покупки продукта?

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

Аватар пользователя meloff meloff 11 июня 2013 в 13:34

У меня казалось бы довольно простая задача..

В Ubercart'е есть класс продукта, он же тип ноды "Видеокурс". Создано несколько нод типа "Видеокурс". В ноде есть несколько полей в том числе и поле "ссылка на скачивание". Нужно закрыть доступ к этому полю для тех, кто не купил продукт и открыть видимость поля для тех кто купил.

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

Нашел наиболее близкий модуль к решению задачи - uc_cck_access. Он в принципе дает нужный функционал, добавлением features к продукту, в котором можно указать sku продукта к которому дается доступ, id ноды к которой дается доступ и поле к которому дается доступ после покупки. И вроде все работает.. Но беда в том что у него нет дефолтных настроек (как например в variable price или add to cart tweaks) и features нужно добавлять для каждого продукта вручную. Мне это не подходит, так как на моем сайте будет множество продавцов и я хотел бы дать им максимально простой функционал, без расписывания огромных мануалов "как пользоваться системой", тем более не хочется чтобы они дали доступ к совсем другому полю в другой ноде.

Вот собственно вопрос.. как можно решить данную задачку? Неужели ничего не придумано на эту тему.. Кодить почти не умею.

Да и вот задал еще вопрос автору модуля https://drupal.org/node/2016537 может ответит..

Комментарии

Аватар пользователя serega111 serega111 11 июня 2013 в 13:57

При покупке продукта юзер получает определенную роль, у которой есть разрешение на доступ к полю. Роль можно менять через rules. Давать разрешение отдельному юзеру не совсем логично, тем более у вас таких юзеров будет много.
Доступ к полю настраиваете через этот модуль https://drupal.org/project/field_permissions

Аватар пользователя meloff meloff 11 июня 2013 в 14:46

serega111 wrote:
При покупке продукта юзер получает определенную роль

Спасибо за ответ! Но у меня будет не один продукт класса "видеокурс", а несколько. И если дать купившему роль на доступ к полю, то получится, что при покупке одного продукта пользователь будет получать доступ к тем же полям всех остальных продуктов класса "видеокурс". Так что это, увы, не подойдет... если только не задавать на каждый продукт отдельную роль..

Думаю попробовать поковырять flags.. может им удастся решить задачку..

Аватар пользователя meloff meloff 11 июня 2013 в 16:31

ХулиGUN wrote:
1. Добавляем к порфилю m2m поле с релейтед по товару
2. Создаём правило, что при покупке товара, он добавляется в это поле
3. Выводем "ссылку на скачивание" по условию, что этот товар есть в m2m поле текущего пользователя

Мне кажется это как раз то что нужно, но я немножко не понял где что взять) Вы не могли бы немножко расшифровать, какие модули нужны для этого способа.. в частности что такое m2m и где его взять.. Это относится к flags и выводу через views?

serega111 wrote:
Интересная задачка. Собственным модулем можно решить, но вы не кодер, как я понял ))
Может это поможет, в конце есть какое то решение, то выглядит громоздко https://drupal.org/node/1316228[/quote]

Ага, спасибо, судя по всему данный код делает примерно то же самое, что и способ описанный ХулиGUN'ом.. Создает поле в Profile2 и добавляет в него энтити через рулсы насколько я понимаю.. Если не получится сделать без кодинга, то попробую) Обычно у меня с кодингом все плохо))

Аватар пользователя meloff meloff 11 июня 2013 в 18:04

imarat wrote:
при покупке товара просто отправляйте файл пользователю на почтовый ящик, и не надо никаких ссылок

Я хотел бы скрыть ссылку какими-нибудь путями дабы обезопаситься от копипаста.. незнаю насколько у меня это получится, но если отправлять ссылку на почту, то скрыть её точно никак не получится..

Аватар пользователя serega111 serega111 11 июня 2013 в 18:21

"meloff" wrote:
Я хотел бы скрыть ссылку какими-нибудь путями дабы обезопаситься от копипаста.. незнаю насколько у меня это получится, но если отправлять ссылку на почту, то скрыть её точно никак не получится..

Если вы откроете ссылку, то копипастить ее точно можно. Тут вам нужно ограничить именно скачивание файла

Аватар пользователя meloff meloff 11 июня 2013 в 20:09

А как тогда ограничить скачивание, при условии, что файл расположен на стороннем сервере? Я думал может есть какой способ скрыть именно ссылку, но дать возможность скачивать сам файл. Т.е. кнопка есть, но куда она ведет, знает лишь друпал и ссыль нигде не прослеживается. Ну и ссыль естественно прямая сразу на файл.. Что-то типа такого я хотел реализовать..

Мне сейчас больше интересно что это за m2m поле такое и где его взять.. никто не подскажет? Smile

Аватар пользователя serega111 serega111 11 июня 2013 в 20:20

Хотя даже ссылку видеть не обязательно. Юзер скачал файл и если захочет, сам его будет раздавать.

"meloff" wrote:
Мне сейчас больше интересно что это за m2m поле такое и где его взять.. никто не подскажет? :)

Скорее всего это поле типа entity reference с неограниченным количеством значений. Не знаю, почему m2m, но если использовать такое поле, вроде как должно получится то, что имел ввиду ХулиGUN

Аватар пользователя meloff meloff 12 июня 2013 в 1:01

serega111 wrote:
Скорее всего это поле типа entity reference с неограниченным количеством значений. Не знаю, почему m2m, но если использовать такое поле, вроде как должно получится то, что имел ввиду ХулиGUN

Ох.. у этих entity reference столько параметров и столько вариантов комбинаций этих параметров с rules, что без пол-литра не разберешься,.. а потом еще и с views их надо увязать на вывод.. да.. буду пробовать варианты.. Спасибо Smile О результате отпишусь.. Пока что вроде создать этити в рулсах получается, но сохранить в нужное место не выходит, селектор выдает не то что нужно.. хм..

Аватар пользователя meloff meloff 12 июня 2013 в 20:25

С entity reference все оказалось довольно просто.. Добавил поле field-purchased-products, в rules прописал правило:

{ "rules_add_node_to_customer_profile_entity_field" : {
    "LABEL" : "rules_add_node_to_customer_profile_entity_field",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "uc_order" ],
    "ON" : [ "uc_order_status_update" ],
    "IF" : [
      { "data_is" : { "data" : [ "order:order-status" ], "value" : "payment_received" } },
      { "uc_order_condition_has_product_class" : {
          "order" : [ "updated-order" ],
          "product_classes" : { "value" : { "videocourse" : "videocourse" } },
          "required" : 0,
          "forbidden" : 0
        }
      }
    ],
    "DO" : [
      { "LOOP" : {
          "USING" : { "list" : [ "updated-order:products" ] },
          "ITEM" : { "list_item_in_order" : "List products" },
          "DO" : [
            { "list_add" : {
                "list" : [ "site:current-user:field-purchased-products" ],
                "item" : [ "list-item-in-order:node" ]
              }
            }
          ]
        }
      }
    ]
  }
}

Покупаемые ноды автоматом добавляются в поле field-purchased-products.. все хорошо с этим. И теперь я немножко в ступоре как это дело на практике применить, потому что модулей для сокрытия полей через рулсы я что-то не найду.. Выводить всё вьювсом и в файле темизации прописывать условие?

Аватар пользователя meloff meloff 13 июня 2013 в 14:06

Ладно, вопрос по сути. Есть следующий файл темизации:


<?php foreach ($fields as $id => $field): ?>

<?php 
if($id=='picture'){$avatar=$field->content;}
if(
$id=='field_name_user'){$name_user=$field->content;}
if(
$id=='created'){$date_created=$field->content;}
if(
$id=='title'){$title=$field->content;}
if(
$id=='body'){$body=$field->content;}
if(
$id=='comments_link'){$comments_link=$field->content;}
if(
$id=='view_node'){$view_node=$field->content;}
if(
$id=='field_image_video_courses'){$field_image_video_courses=$field->content;}
if(
$id=='field_link'){$field_link=$field->content;}
?>

<?php endforeach; ?>

<div class="teaser_videoc" style="height:200px;">
    <div class="pull-right" style="width:200px; margin-left:30px;">
        <?=$field_image_video_courses?> 
    </div>
    <div>
        <div class="pull-right">
            <button class="btn btn-success btn-normal">Купить за 1000 руб.</button>
        </div>
        <div style="">
            <div style="margin: 0 10px 0 0;" class="pull-left">
                    <?=$avatar?>
            </div>
            <div class="author_teaser">
                <span><?=$name_user?></span>
                <span><?=$date_created?></span> 
            </div>
        </div>
              <div class="title_tiser" style="overflow:hidden; white-space: nowrap;">
            <h3>
                 <?=$title?>
            </h3>
        </div>
        <div style="overflow:hidden; height:80px;">
            <?=$body?>
        </div>
        <div class="pull-right" style="padding: 10px 0 0 0;">
            <ul class="links inline">
                <li class="node-readmore first ">
                    <?=$view_node?> 
                </li>
                <li class="comment-add last ">
                    <?=$comments_link?>
                </li>
            </ul>
        </div>
        <div class="links pull-left" style="padding: 10px 0 0 0;">
            <?=$field_link?>
        </div>
    </div>
</div>
?>

Нужно выполнить следующий фрагмент кода,...:

<?php
        
<div class="links pull-left" style="padding: 10px 0 0 0;">
            <?=
$field_link?>
        </div>
?>

...при условии, что выводимая нода присутствует в профиле текущего пользователя (обычном, НЕ Profile2) в поле "field-purchased-products", созданным модулем entity reference. (Поле, как я понимаю, это массив в виде list,содержащий entity нод. При просмотре профиля поле выводит id нод.)

Каким кодом можно это осуществить? И дополнительный вопрос - не сильно ли будет тормозить сайт от таких запросов?

Аватар пользователя meloff meloff 13 июня 2013 в 17:17

Почти разобрался. Переработал код по ссылке данной serega111, вот что получилось:
<?php
if($id=='nid'){$nid=$field->content;}

global $user;
$profile = user_load($user->uid);
if (isset($profile->field_purchased_products['und'])) {
$posicion = 0;
$count = count($profile->field_purchased_products['und']);
while ($posicion < $count ) {
$tid = $profile->field_purchased_products['und'][$posicion]['target_id'];
if ($nid == $tid) {
print t("Зашибись") ;
}
else {
$posicion++;
print t("Обломайхтунг") ;
}
}
}
?>

Пользователь купил 2 ноды и обе они у него в поле field_purchased_products. $count работает как надо, выдает 2, $tid тоже работает, выдает id нод. $nid и $tid обе две целые числа, проверял..
Но код выдает - "ОбломайхтунгОбломайхтунг" и ни разу не выдаёт Зашибись.. Где ошибка зарыта?

Аватар пользователя meloff meloff 13 июня 2013 в 18:26

А, нет.. плохо проверял, $nid и $tid оба два string.. как бы их преобразовать..

Добавлено

Не, все равно не работает... добавил
<?php
$tid_int = (int)$tid;
$nid_int = (int)$nid;

if ($nid_int == $tid_int) {
?>
и по прежнему "ОбломайхтунгОбломайхтунг"

Добавлено

Все, разобрался, нужно было в настройках вывода поля nid во views включить все настройки форматирования и выставить на none, отметить Strip HTML tags и Remove whitespace. И теперь nid стал действительно строкой, а не кучей дивов и спанов)
Код вроде как работает.. даже без преобразования в int, выдает ОбломайхтунгЗашибись Smile Теперь можно попробовать позакрывать поля Acute

Аватар пользователя meloff meloff 13 июня 2013 в 21:37

Итак, мой временно-финальный код вывода views, с условием на скрытие поля в еще не купленной ноде:

<?php foreach ($fields as $id => $field): ?>
<?php
if($id=='picture'){$avatar=$field->content;}
if($id=='field_name_user'){$name_user=$field->content;}
if($id=='created'){$date_created=$field->content;}
if($id=='title'){$title=$field->content;}
if($id=='body'){$body=$field->content;}
if($id=='comments_link'){$comments_link=$field->content;}
if($id=='view_node'){$view_node=$field->content;}
if($id=='field_image_video_courses'){$field_image_video_courses=$field->content;}
if($id=='field_link'){$field_link=$field->content;}
if($id=='nid'){$nid=$field->content;}
?>

<?php endforeach; ?>

<?php
global $user;
$profile = user_load($user->uid);
$node_purchased = false;
if (isset($profile->field_purchased_products['und'])) {
        $posicion = 0;
        $count = count($profile->field_purchased_products['und']);    
        while ($posicion < $count ) {
                $tid = $profile->field_purchased_products['und'][$posicion]['target_id'];
                if ($nid == $tid) {
                        $posicion = $count + 1;
                        $node_purchased = true;
                }
                else {
                        $posicion++;
                }
        }
}
?>

<div class="teaser_videoc" style="height:200px;">
        <div class="pull-right" style="width:200px; margin-left:30px;">
                <?=$field_image_video_courses?>
        </div>
        <div>
                <div class="pull-right">
                        <button class="btn btn-success btn-normal">Купить за 1000 руб.</button>
                </div>
                <div style="">
                        <div style="margin: 0 10px 0 0;" class="pull-left">
                                        <?=$avatar?>
                        </div>
                        <div class="author_teaser">
                                <span><?=$name_user?></span>
                                <span><?=$date_created?></span>
                        </div>
                </div>
                <div class="title_tiser" style="overflow:hidden; white-space: nowrap;">
                        <h3>
                                <?=$title?>
                        </h3>
                </div>
                <div style="overflow:hidden; height:80px;">
                        <?=$body?>
                </div>
                <div class="pull-right" style="padding: 10px 0 0 0;">
                        <ul class="links inline">
                                <li class="node-readmore first ">
                                        <?=$view_node?>
                                </li>
                                <li class="comment-add last ">
                                        <?=$comments_link?>
                                </li>
                        </ul>
                </div>
                <?php if ($node_purchased) { ?>
                <div class="links pull-left" style="padding: 10px 0 0 0;">
                        <?=$field_link?>
                </div>
                <?php } ?>
        </div>
</div>

Теперь можно выводить поля как хочется Smile К примеру даже заменить кнопку "Купить" на кнопку "Уже куплено". Класс! Всем спасибо кто помог! Smile Если что можно улучшить, буду рад узнать как Smile

Аватар пользователя serega111 serega111 13 июня 2013 в 21:46

<?php
if (isset($profile->field_purchased_products['und'])) {
$posicion = 0;
$count = count($profile->field_purchased_products['und']);
while ($posicion < $count ) {
$tid = $profile->field_purchased_products['und'][$posicion]['target_id'];
if ($nid == $tid) {
$posicion = $count + 1;
$node_purchased = true;
}
else {
$posicion++;
}
}
}
?>
заменить на
<?php
$products = field_get_items('user', $profile, 'field_purchased_product');
if ($products) {
foreach ($products as $delta => $item) {
if ($item['target_id'] == $nid) {
$node_purchased = true;
break;
}
}
}
?>

Аватар пользователя meloff meloff 13 июня 2013 в 22:21

Спасибо, serega111! Работает! Smile Твой вариант безусловно лучше моего )

Для тех, кто будет бездумно копипастить, добавьте s в конец "field_purchased_products" Wink