and one or more channels
piotre@7: if (count($channels)) {
piotre@7: $where = array('(ISNULL(acn.chid) OR acn.chid IN (%s))');
piotre@7: $args = array(implode(',', $channels));
piotre@7: }
piotre@7: else {
piotre@7: $where = array('ISNULL(acn.chid)');
piotre@7: }
piotre@7: return array('join' => $join, 'where' => $where, 'args' => $args);
piotre@7: }
piotre@7: // Filtering by one or more channels
piotre@7: else {
piotre@7: $join = array('LEFT JOIN {ad_channel_node} acn ON acn.nid = a.aid');
piotre@7: $where = array('acn.chid IN (%s)');
piotre@7: $args = array(implode(',', $_SESSION['ad_report_channel']));
piotre@7: return array('join' => $join, 'where' => $where, 'args' => $args);
piotre@7: }
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Implement hook _adapi.
pierre@1: */
pierre@1: function ad_channel_adapi($op, &$node) {
pierre@1: switch ($op) {
pierre@1: case 'admin_filters':
pierre@1: $channels = _ad_channel_get_channels();
pierre@1: $options = array();
pierre@1: foreach ($channels as $channel) {
pierre@1: $key = 'channel-'. $channel->chid;
pierre@1: $options[$key] = $channel->name;
pierre@1: }
pierre@1: $filters['channel'] = array(
pierre@1: 'title' => t('channel'),
pierre@1: 'options' => $options,
pierre@1: );
pierre@1: $options = array(
pierre@1: '0' => t('false'),
pierre@1: '1' => t('true'));
pierre@1: $filters['premiere'] = array(
pierre@1: 'title' => t('premiere'),
pierre@1: 'options' => $options,
pierre@1: );
piotre@7: $filters['remnant'] = array(
piotre@7: 'title' => t('remnant'),
piotre@7: 'options' => $options,
piotre@7: );
pierre@1: return $filters;
pierre@1: case 'admin_filter_query':
pierre@1: if (is_array($node)) {
pierre@1: list($key, $value) = $node;
pierre@1: if ($key == 'channel') {
pierre@1: list($key, $value) = explode('-', $value, 2);
pierre@1: return array(
pierre@1: 'channel' => array(
pierre@1: 'where' => 'c.chid = %d',
pierre@1: 'join' => 'INNER JOIN {ad_channel_node} c ON n.nid = c.nid ',
pierre@1: 'value' => $value,
pierre@1: ));
pierre@1: }
pierre@1: else if ($key == 'premiere') {
pierre@1: return array(
pierre@1: 'premiere' => array(
pierre@1: 'where' => 'p.priority = %d',
pierre@1: 'join' => 'INNER JOIN {ad_priority} p ON n.nid = p.aid ',
pierre@1: 'value' => $value,
pierre@1: ));
pierre@1: }
piotre@7: else if ($key == 'remnant') {
piotre@7: return array(
piotre@7: 'remnant' => array(
piotre@7: 'where' => 'r.remnant = %d',
piotre@7: 'join' => 'INNER JOIN {ad_channel_remnant} r ON n.nid = r.aid ',
piotre@7: 'value' => $value,
piotre@7: ));
piotre@7: }
pierre@1: }
pierre@1: break;
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Implementation of hook_nodeapi().
pierre@1: */
pierre@1: function ad_channel_nodeapi($node, $op, $arg = 0) {
pierre@1: switch ($op) {
pierre@1: case 'view':
pierre@1: return _ad_channel_view_node($node);
pierre@1: case 'load':
pierre@1: return _ad_channel_load_node($node);
pierre@1: case 'insert':
pierre@1: case 'update':
piotre@7: if (is_object($node) && isset($node->adtype) && isset($node->nid)) {
pierre@1: return _ad_channel_save_node($node);
pierre@1: }
sly@4: break;
pierre@1: case 'delete':
pierre@1: return _ad_channel_delete_node($node);
pierre@1: case 'validate':
pierre@1: return _ad_channel_validate_nodes($node);
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Implementation of hook_ad_build_cache().
pierre@1: */
pierre@1: function ad_channel_ad_build_cache() {
pierre@1: $cache = array();
pierre@1: $ads = array();
pierre@1: $active = db_query("SELECT aid FROM {ads} WHERE adstatus = 'active'");
pierre@1: while ($ad = db_fetch_object($active)) {
pierre@1: // cache channel<->node relation
pierre@1: $result = db_query('SELECT chid FROM {ad_channel_node} WHERE nid = %d', $ad->aid);
pierre@1: while ($channel = db_fetch_object($result)) {
pierre@1: $ads[$ad->aid][$channel->chid] = $channel->chid;
pierre@1: //$ads[$channel->chid][$ad->aid] = $ad->aid;
pierre@1: }
pierre@1: }
pierre@1: $channels = array();
piotre@7: $result = db_query('SELECT chid, display, urls, no_channel_percent, inventory FROM {ad_channel}');
pierre@1: while ($channel = db_fetch_object($result)) {
pierre@1: $channels[$channel->chid] = $channel;
pierre@1: }
pierre@1: $result = db_query("SELECT p.aid, p.priority FROM {ads} a LEFT JOIN {ad_priority} p ON a.aid = p.aid WHERE a.adstatus = 'active' AND p.priority = 1");
pierre@1: $premiere = array();
pierre@1: while ($priority = db_fetch_object($result)) {
pierre@1: $premiere[$priority->aid] = $priority->aid;
pierre@1: }
piotre@7: $result = db_query("SELECT r.aid, r.remnant FROM {ads} a LEFT JOIN {ad_channel_remnant} r ON a.aid = r.aid WHERE a.adstatus = 'active' AND r.remnant = 1");
piotre@7: $remnants = array();
piotre@7: while ($remnant = db_fetch_object($result)) {
piotre@7: $remnants[$remnant->aid] = $remnant->aid;
piotre@7: }
pierre@1: $cache['channel']['ads'] = $ads;
pierre@1: $cache['channel']['channels'] = $channels;
pierre@1: $cache['channel']['display'] = variable_get('ad_channel_display', 0);
pierre@1: $cache['premiere'] = $premiere;
piotre@7: $cache['remnant'] = $remnants;
pierre@1:
pierre@1: $cache['channel']['hook_filter'] = array(
pierre@1: 'weight' => 0,
pierre@1: 'file' => drupal_get_path('module', 'ad_channel') .'/ad_channel.inc',
pierre@1: 'function' => 'ad_channel_cache_filter',
pierre@1: );
pierre@1:
pierre@1: return $cache;
pierre@1: }
pierre@1:
pierre@1: /***/
pierre@1:
pierre@1: /**
pierre@1: * Settings form.
pierre@1: */
pierre@1: function ad_channel_admin_settings() {
pierre@1: $form = array();
pierre@1:
pierre@1: $form['ad_channel_display'] = array(
pierre@1: '#type' => 'radios',
pierre@1: '#title' => t('Display advertisements not assigned to any channel'),
pierre@1: '#options' => array(t('Only if no matching advertisements are found in the active channels'), t('Always'), t('Never')),
pierre@1: '#default_value' => variable_get('ad_channel_display', 0),
pierre@1: '#description' => t('By default, advertisements will first be selected out of the active channels, and if none are found they will be selected out of advertisements not assigned to any channel. If you select "Always", advertisements will be selected out of the active channels and from advertisements not assigned to any channels. If you select "Never", advertisements will only be selected out of the active channels, and advertisements not assigned to any channel will not ever be displayed.'),
pierre@1: );
pierre@1: $form['ad_channel_admin_list'] = array(
pierre@1: '#type' => 'radios',
pierre@1: '#title' => t('Display channels on administrative ads overview listing'),
pierre@1: '#options' => array(t('In addition to groups'), t('In place of groups'), t('Not at all')),
pierre@1: '#default_value' => variable_get('ad_channel_admin_list', AD_CHANNEL_LIST_CHANNEL),
pierre@1: '#description' => t('By default, channels will be listed along with groups on the administrative ads list. You can optionally disable either the groups column (by selecting "in place of groups"), or the channel column (by selecting "not at all").'),
pierre@1: );
sly@2: $options = array(0 => t('No limit')) + drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
sly@2: $form['ad_channel_ad_limit'] = array(
sly@2: '#type' => 'select',
sly@2: '#title' => t('Maximum number of channels that can be assigned to a single ad'),
sly@2: '#options' => $options,
sly@2: '#default_value' => variable_get('ad_channel_ad_limit', 0),
sly@2: '#description' => t('Optionally limit the number of channels that a single advertisement can be assigned to.'),
sly@2: );
pierre@1:
pierre@1: return system_settings_form($form);
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Add channel information when viewing node.
pierre@1: */
pierre@1: function _ad_channel_view_node($node) {
pierre@1: if (isset($node->adtype) && user_access('administer channels')) {
pierre@1: if (isset($node->channel) && is_array($node->channel) && !empty($node->channel)) {
pierre@1: $channels = array();
pierre@1: foreach ($node->channel as $chid) {
pierre@1: $channel = _ad_channel_get_channels($chid);
pierre@1: $channels[] = $channel->name;
pierre@1: }
pierre@1: $node->content['channel'] = array(
pierre@1: '#value' => theme('box', t('Channels'), theme('item_list', $channels)),
pierre@1: '#weight' => 1,
pierre@1: );
pierre@1: }
pierre@1: if (isset($node->premiere)) {
pierre@1: if (isset($node->premiere) && $node->premiere == 1) {
pierre@1: $output = t('This is a premiere advertisement.');
pierre@1: }
pierre@1: else {
pierre@1: $output = t('This is not a premiere advertisement.');
pierre@1: }
pierre@1: $node->content['premiere'] = array(
pierre@1: '#value' => theme('box', t('Premiere'), $output),
pierre@1: '#weight' => 1,
pierre@1: );
pierre@1: }
piotre@7: if (isset($node->remnant)) {
piotre@7: if (isset($node->remnant) && $node->remnant == 1) {
piotre@7: $output = t('This is a remnant advertisement.');
piotre@7: $node->content['remnant'] = array(
piotre@7: '#value' => theme('box', t('Remnant'), $output),
piotre@7: '#weight' => 1,
piotre@7: );
piotre@7: }
piotre@7: }
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Load channels associated with specified node.
pierre@1: */
pierre@1: function _ad_channel_load_node($node) {
pierre@1: $result = db_query('SELECT chid FROM {ad_channel_node} WHERE nid = %d', $node->nid);
pierre@1: $output['channel'] = array();
pierre@1: while ($chid = db_fetch_object($result)) {
pierre@1: $output['channel'][$chid->chid] = $chid->chid;
pierre@1: }
pierre@1: // currently 0 or 1, with one being a 'premiere' advertisement.
pierre@1: $output['premiere'] = (int)db_result(db_query('SELECT priority FROM {ad_priority} WHERE aid = %d', $node->nid));
piotre@7: $output['remnant'] = (int)db_result(db_query('SELECT remnant FROM {ad_channel_remnant} WHERE aid = %d', $node->nid));
pierre@1: return $output;
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Save channels associated with added or updated node.
pierre@1: */
pierre@1: function _ad_channel_save_node($node) {
pierre@1: // delete old channel information, then add new
pierre@1: db_query('DELETE FROM {ad_channel_node} WHERE nid = %d', $node->nid);
pierre@1: $channels = _ad_channel_get_enabled($node);
pierre@1: foreach ($channels as $chid) {
pierre@1: db_query('INSERT INTO {ad_channel_node} (chid, nid) VALUES(%d, %d)', $chid, $node->nid);
pierre@1: }
sly@2: if (user_access('configure ad premier status')) {
pierre@1: db_query('UPDATE {ad_priority} SET priority = %d WHERE aid = %d', isset($node->premiere) ? $node->premiere : 0, $node->nid);
pierre@1: if (!db_affected_rows()) {
pierre@1: db_query('INSERT INTO {ad_priority} (aid, priority) VALUES(%d, %d)', $node->nid, isset($node->premiere) ? $node->premiere : 0);
pierre@1: }
pierre@1: }
piotre@7: db_query('UPDATE {ad_channel_remnant} SET remnant = %d WHERE aid = %d', isset($node->remnant) ? $node->remnant : 0, $node->nid);
piotre@7: if (!db_affected_rows()) {
piotre@7: db_query('INSERT INTO {ad_channel_remnant} (aid, remnant) VALUES(%d, %d)', $node->nid, isset($node->remnant) ? $node->remnant : 0);
piotre@7: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Delete channel information associated with node.
pierre@1: */
pierre@1: function _ad_channel_delete_node($node) {
pierre@1: if ($node->nid) {
pierre@1: db_query('DELETE FROM {ad_channel_node} WHERE nid = %d', $node->nid);
pierre@1: db_query('DELETE FROM {ad_priority} WHERE aid = %d', $node->nid);
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Be sure that the enabled channels actually can be enabled.
pierre@1: */
pierre@1: function _ad_channel_validate_nodes($node) {
pierre@1: $channels = _ad_channel_get_enabled($node);
piotre@7:
piotre@7: foreach ($channels as $chid) {
piotre@7: $channel = _ad_channel_get_channels($chid);
piotre@7: if(isset($channel->inventory) && $channel->inventory > 0) {
piotre@7: $num_ads = _ad_channel_get_channel_active_ad_count($chid);
piotre@7: if ($num_ads + 1 >= $channel->inventory) {
piotre@7: form_set_error("channel[$channel->conid][channel-$chid]", t('You may not assign more than !inventory to %name.', array('!inventory' => format_plural($channel->inventory, '1 advertisement', '@count advertisements'), '%name' => $channel->name)));
piotre@7: }
piotre@7: }
piotre@7: }
piotre@7:
sly@2: $limit = variable_get('ad_channel_ad_limit', 0);
sly@2: if ($limit && sizeof($channels) > $limit) {
sly@2: $quantity_error = TRUE;
sly@2: }
sly@2: else {
sly@2: $quantity_error = FALSE;
sly@2: }
pierre@1: foreach ($channels as $chid) {
pierre@1: $channel = _ad_channel_get_channels($chid);
sly@2: if ($quantity_error) {
sly@2: $quantity_error = FALSE;
sly@2: form_set_error("channel[$channel->conid][channel-$chid]", t('You can not assign this advertisement to more than !limit.', array('!limit' => format_plural(sizeof($limit), '1 channel', '@count channels'))));
sly@2: }
pierre@1: $taxonomy = is_array($node->taxonomy) ? $node->taxonomy : array();
pierre@1: $groups = unserialize($channel->groups);
pierre@1: if (!empty($groups)) {
pierre@1: $enabled = FALSE;
pierre@1: foreach($groups as $group) {
pierre@1: if ($group) {
pierre@1: $enabled = TRUE;
pierre@1: break;
pierre@1: }
pierre@1: }
pierre@1: if ($enabled) {
pierre@1: $ad_groups = taxonomy_get_tree(_ad_get_vid());
pierre@1: foreach ($ad_groups as $ad_group) {
pierre@1: if (is_array($taxonomy[$ad_group->vid]) &&
pierre@1: isset($taxonomy[$ad_group->vid][$ad_group->tid]) &&
pierre@1: isset($groups[$ad_group->tid]) && !$groups[$ad_group->tid] &&
pierre@1: !isset($groups[''])) {
pierre@1: form_set_error("channel[$channel->conid][channel-$chid]", t('The %channel channel does not allow advertisements from the %group group.', array('%channel' => $channel->name, '%group' => $ad_group->name)));
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Retrive list of enabled channels from node object.
pierre@1: */
pierre@1: function _ad_channel_get_enabled($node) {
pierre@1: static $enabled = array();
pierre@1: if (!isset($enabled[$node->nid])) {
pierre@1: $enabled[$node->nid] = array();
pierre@1: if (isset($node->channel) && is_array($node->channel) && !empty($node->channel)) {
pierre@1: foreach ($node->channel as $conid => $channels) {
pierre@1: foreach ($channels as $id => $enable) {
pierre@1: if ($enable) {
pierre@1: $chid = explode('-', $id);
pierre@1: $enabled[$node->nid][] = $chid[1];
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1: }
pierre@1: return $enabled[$node->nid];
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Display containers and channels.
pierre@1: */
pierre@1: function ad_channel_admin_overview() {
pierre@1: drupal_add_css(drupal_get_path('module', 'ad_channel') .'/ad_channel.css');
pierre@1:
pierre@1: $containers = _ad_channel_get_containers();
pierre@1: $rows = array();
pierre@1: if (count($containers)) {
piotre@7: $header = array(t('Name'), t('Inventory'), t('Options'));
pierre@1: $output = '';
pierre@1: foreach ($containers as $conid => $container) {
pierre@1: $channels = _ad_channel_get_container_channels($conid);
pierre@1: if ($conid > 0 || count($channels)) {
pierre@1: if ($conid > 0) {
pierre@1: $description = '
'. l($container->name, "admin/content/ad/channel/container/$conid/edit") . "
\n";
pierre@1: }
pierre@1: else {
pierre@1: $description = '
'. $container->name . "
\n";
pierre@1: }
pierre@1: if ($container->description) {
pierre@1: $description .= '
'. filter_xss_admin($container->description) ."
\n";
pierre@1: }
piotre@7: $rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => 3));
pierre@1: }
pierre@1: foreach ($channels as $chid => $channel) {
pierre@1: $description = "
\n";
pierre@1: $description .= '
' . $channel->name . "
\n";
pierre@1: if ($channel->description) {
pierre@1: $description .= '
'. filter_xss_admin($channel->description) ."
\n";
pierre@1: }
pierre@1: $description .= "
\n";
piotre@7: $inventory = '
' . $channel->inventory . "
\n";
pierre@1: $rows[] = array(
pierre@1: array('data' => $description, 'class' => 'channel'),
piotre@7: array('data' => $inventory, 'class' => 'channel'),
pierre@1: l(t('edit'), "admin/content/ad/channel/channel/$channel->chid/edit") .' '. l(t('delete'), "admin/content/ad/channel/channel/$channel->chid/delete"),
pierre@1: );
pierre@1: }
pierre@1: }
pierre@1: $output .= theme('table', $header, $rows);
pierre@1: $output .= '
';
pierre@1: }
pierre@1:
pierre@1: return $output;
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Load one or more containers, caching the results.
pierre@1: */
pierre@1: function _ad_channel_get_containers($conid = 0) {
pierre@1: static $cache;
pierre@1: if (!isset($cache[$conid])) {
pierre@1: if ($conid) {
pierre@1: $cache[$conid] = db_fetch_object(db_query('SELECT * FROM {ad_channel_container} WHERE conid = %d', $conid));
pierre@1: }
pierre@1: else {
pierre@1: // Get all manually defined channels.
pierre@1: $result = db_query('SELECT conid, name, description, weight FROM {ad_channel_container} ORDER BY weight ASC');
pierre@1: while ($container = db_fetch_object($result)) {
pierre@1: $containers[$container->conid] = $container;
pierre@1: }
pierre@1: // Define default 'No container'.
pierre@1: $none->conid = 0;
pierre@1: $none->name = t('No container');
pierre@1: $none->weight = 0;
pierre@1: $containers[0] = $none;
pierre@1: $cache[$conid] = $containers;
pierre@1: }
pierre@1: }
pierre@1: return $cache[$conid];
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Load one or more channels, caching the results.
pierre@1: */
pierre@1: function _ad_channel_get_container_channels($conid = 0) {
pierre@1: static $cache;
pierre@1: if (!isset($cache[$conid])) {
pierre@1: $channels = array();
piotre@7: $result = db_query('SELECT chid, name, description, weight, inventory FROM {ad_channel} WHERE conid = %d ORDER BY weight ASC', $conid);
pierre@1: while ($channel = db_fetch_object($result)) {
pierre@1: $channels[$channel->chid] = $channel;
pierre@1: }
pierre@1: $cache[$conid] = $channels;
pierre@1: }
pierre@1: return $cache[$conid];
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Load one or more channels.
pierre@1: */
pierre@1: function _ad_channel_get_channels($chid = 0) {
pierre@1: if ($chid) {
pierre@1: return db_fetch_object(db_query('SELECT * FROM {ad_channel} WHERE chid = %d', $chid));
pierre@1: }
pierre@1: else {
pierre@1: $channels = array();
pierre@1: $result = db_query('SELECT chid, name, description FROM {ad_channel}');
pierre@1: while ($channel = db_fetch_object($result)) {
pierre@1: $channels[$channel->chid] = $channel;
pierre@1: }
pierre@1: return $channels;
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Administrative page for creating or editing containers.
pierre@1: */
pierre@1: function ad_channel_admin_container($form_state, $conid = 0) {
pierre@1: $form = array();
pierre@1:
pierre@1: if ($conid) {
pierre@1: $container = _ad_channel_get_containers($conid);
pierre@1: if (empty($container)) {
pierre@1: drupal_goto('admin/content/ad/channel');
pierre@1: }
pierre@1: $form['conid'] = array(
pierre@1: '#type' => 'hidden',
pierre@1: '#value' => $conid,
pierre@1: );
pierre@1: }
pierre@1:
pierre@1: $form['name'] = array(
pierre@1: '#type' => 'textfield',
pierre@1: '#title' => t('Container name'),
pierre@1: '#required' => TRUE,
pierre@1: '#description' => t('Channel containers can be used to help organize channels, but they are not required.'),
pierre@1: '#default_value' => $conid ? $container->name : '',
pierre@1: );
pierre@1: $form['description'] = array(
pierre@1: '#type' => 'textarea',
pierre@1: '#title' => t('Description'),
pierre@1: '#description' => t('The channel container description can be used to help you define the purpose of your different channels. The descriptions are only visible to advertisement administrators.'),
pierre@1: '#default_value' => $conid ? $container->description : '',
pierre@1: );
pierre@1: $form['weight'] = array(
pierre@1: '#type' => 'weight',
pierre@1: '#title' => t('Weight'),
pierre@1: '#description' => t('When listing containers, those with the lighter (smaller) weights get listed before containers with heavier (larger) weights. Containers with equal weights are sorted alphabetically.'),
pierre@1: '#default_value' => $conid ? $container->weight : 0,
pierre@1: );
pierre@1:
pierre@1: if ($conid) {
pierre@1: $form['update'] = array(
pierre@1: '#type' => 'submit',
pierre@1: '#value' => t('Update'),
pierre@1: );
pierre@1: $form['delete'] = array(
pierre@1: '#type' => 'submit',
pierre@1: '#value' => t('Delete'),
pierre@1: );
pierre@1: }
pierre@1: else {
pierre@1: $form['create'] = array(
pierre@1: '#type' => 'submit',
pierre@1: '#value' => t('Create'),
pierre@1: );
pierre@1: }
pierre@1: $form['cancel'] = array(
pierre@1: '#type' => 'markup',
pierre@1: '#value' => l(t('Cancel'), 'admin/content/ad/channel'),
pierre@1: );
pierre@1:
pierre@1: return $form;
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Validate the container.
pierre@1: */
pierre@1: function ad_channel_admin_container_validate($form, &$form_state) {
pierre@1: $conid = 0;
pierre@1: if ($form_state['values']['op'] == t('Create')) {
pierre@1: $conid = db_result(db_query("SELECT conid FROM {ad_channel_container} WHERE name = '%s'", $form_state['values']['name']));
pierre@1: }
pierre@1: else if ($form_state['values']['op'] == t('Update')) {
pierre@1: $conid = db_result(db_query("SELECT conid FROM {ad_channel_container} WHERE name = '%s' AND conid != %d", $form_state['values']['name'], $form_state['values']['conid']));
pierre@1: }
pierre@1: if ($conid) {
pierre@1: form_set_error('name', t('A container named %name already exists.', array('%name' => $form_state['values']['name'])));
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Save the container.
pierre@1: */
pierre@1: function ad_channel_admin_container_submit($form, &$form_state) {
pierre@1: switch ($form_state['values']['op']) {
pierre@1: case t('Create'):
pierre@1: db_query("INSERT INTO {ad_channel_container} (name, description, weight) VALUES('%s', '%s', %d)", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['weight']);
pierre@1: drupal_set_message(t('The %name container has been created.', array('%name' => $form_state['values']['name'])));
pierre@1: break;
pierre@1: case t('Update'):
pierre@1: db_query("UPDATE {ad_channel_container} SET name = '%s', description = '%s', weight = '%s' WHERE conid = %d", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['weight'], $form_state['values']['conid']);
pierre@1: drupal_set_message(t('The %name container has been updated.', array('%name' => $form_state['values']['name'])));
pierre@1: break;
pierre@1: case t('Delete'):
pierre@1: drupal_goto('admin/content/ad/channel/container/'. $form_state['values']['conid'] .'/delete');
pierre@1: }
pierre@1: drupal_goto('admin/content/ad/channel');
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Confirm whether or not to delete container, and the contained channels.
pierre@1: */
sly@2: function ad_channel_admin_confirm_delete_container($form_state, $container) {
pierre@1: $form = array();
pierre@1:
pierre@1: $form['conid'] = array(
pierre@1: '#type' => 'value',
sly@2: '#value' => $container->conid,
pierre@1: );
pierre@1:
pierre@1: return confirm_form(
pierre@1: $form,
pierre@1: t('Are you sure you want to delete the %name container?', array('%name' => $container->name)),
pierre@1: 'admin/content/ad/channel',
pierre@1: t('Any channels currently assigned to the %name container will not be deleted, they will be reassigned. This action can not be undone.', array('%name' => $container->name)),
pierre@1: t('Delete'),
pierre@1: t('Cancel'));
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Delete a container.
pierre@1: */
pierre@1: function ad_channel_admin_confirm_delete_container_submit($form, &$form_state) {
pierre@1: $container = _ad_channel_get_containers($form_state['values']['conid']);
pierre@1: if ($container->conid) {
pierre@1: db_query('UPDATE {ad_channel} SET conid = 0 WHERE conid = %d', $container->conid);
pierre@1: db_query('DELETE FROM {ad_channel_container} WHERE conid = %d', $container->conid);
pierre@1: drupal_set_message(t('The %name container has been deleted.', array('%name' => $container->name)));
pierre@1: }
pierre@1: drupal_goto('admin/content/ad/channel');
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Administrative page for creating or editing channels.
pierre@1: */
pierre@1: function ad_channel_admin_channel($form_state, $chid = 0) {
pierre@1: $form = array();
pierre@1:
pierre@1: if ($chid) {
pierre@1: $channel = _ad_channel_get_channels($chid);
pierre@1: if (empty($channel)) {
pierre@1: drupal_goto('admin/content/ad/channel');
pierre@1: }
pierre@1: $form['chid'] = array(
pierre@1: '#type' => 'hidden',
pierre@1: '#value' => $chid,
pierre@1: );
pierre@1: }
pierre@1:
pierre@1: $form['name'] = array(
pierre@1: '#type' => 'textfield',
pierre@1: '#required' => TRUE,
pierre@1: '#title' => t('Channel name'),
pierre@1: '#description' => t('Enter a short, descriptive name for your channel.'),
pierre@1: '#default_value' => $chid ? $channel->name : '',
pierre@1: );
pierre@1: $form['description'] = array(
pierre@1: '#type' => 'textarea',
pierre@1: '#title' => t('Description'),
pierre@1: '#description' => t('Enter a full description of your channel.'),
pierre@1: '#default_value' => $chid ? $channel->description : '',
pierre@1: );
pierre@1: $result = db_query('SELECT conid, name FROM {ad_channel_container} ORDER BY weight ASC');
pierre@1: $containers = array(t(''));
pierre@1: while ($container = db_fetch_object($result)) {
pierre@1: $containers[$container->conid] = $container->name;
pierre@1: }
pierre@1: if (sizeof($containers) == 1) {
pierre@1: $containers = array(t('No containers have been created.'));
pierre@1: }
pierre@1: $form['conid'] = array(
pierre@1: '#type' => 'select',
pierre@1: '#title' => t('Container'),
pierre@1: '#options' => $containers,
pierre@1: '#description' => t('Optionally assign your channel to a container. Containers can be used to help organize your channels, but they are not required.'),
pierre@1: '#default_value' => $chid ? $channel->conid : 0,
pierre@1: );
pierre@1: $form['weight'] = array(
pierre@1: '#type' => 'weight',
pierre@1: '#title' => t('Weight'),
pierre@1: '#description' => t('When listing channels, those with the lighter (smaller) weights get listed before channels with heavier (larger) weights. Channels with equal weights are sorted alphabetically.'),
pierre@1: '#default_value' => $chid ? $channel->weight : 0,
pierre@1: );
pierre@1:
piotre@7: // Inventory for remnant management
piotre@7: $form['channel_inventory'] = array(
piotre@7: '#type' => 'fieldset',
piotre@7: '#title' => t('Inventory'),
piotre@7: '#collapsible' => TRUE,
piotre@7: '#collapsed' => FALSE
piotre@7: );
piotre@7: $form['channel_inventory']['inventory'] = array(
piotre@7: '#type' => 'textfield',
piotre@7: '#title' => t('Level'),
piotre@7: '#size' => 10,
piotre@7: '#maxlength' => 10,
piotre@7: '#required' => FALSE,
piotre@7: '#description' => t('Entering an inventory value will limit the number of advertisements that may be assigned to this channel. As well, if fewer advertisements than the inventory value are assigned to this channel, advertisements marked as remnants will be used to reach the assigned inventory level.'),
piotre@7: '#default_value' => $chid ? $channel->inventory : 0,
piotre@7: );
piotre@7:
pierre@1: // URL rules
pierre@1: $form['URL_rules'] = array(
pierre@1: '#type' => 'fieldset',
pierre@1: '#title' => t('URL rules'),
pierre@1: '#collapsible' => TRUE,
pierre@1: '#collasped' => FALSE,
pierre@1: );
pierre@1: $form['URL_rules']['display'] = array(
pierre@1: '#type' => 'radios',
pierre@1: '#title' => t('Display advertisements from this channel on specific URLs'),
pierre@1: '#options' => array(t('Display advertisements on every URL except the listed URLs.'), t('Display advertisements only on the listed URLs.')),
pierre@1: '#default_value' => $chid ? $channel->display : 0,
pierre@1: );
pierre@1: $form['URL_rules']['urls'] = array(
pierre@1: '#type' => 'textarea',
pierre@1: '#title' => t('Paths'),
sly@8: '#description' => t("Enter one URL per line. If serving ads locally use Drupal relative paths. If serving ads remotely include the 'http://' or 'https:/'. Use '<front>' to specify the front page. The '*' character is a wildcard. Example URLs are blog for the blog page and blog/* for every personal blog on your local website. When specifying local paths you must enter the raw path (ie 'node/123') and not the url alias (ie 'my/custom/path'), if any."),
pierre@1: '#default_value' => $chid ? unserialize($channel->urls) : '',
pierre@1: );
pierre@1:
pierre@1: // Group rules
pierre@1: $groups = taxonomy_get_tree(_ad_get_vid());
pierre@1: $collapsed = is_array($groups) && !empty($groups) ? FALSE : TRUE;
pierre@1: $form['group_rules'] = array(
pierre@1: '#type' => 'fieldset',
pierre@1: '#title' => t('Ad group rules'),
pierre@1: '#collapsible' => TRUE,
pierre@1: '#collapsed' => $collapsed,
pierre@1: );
pierre@1: if (!$collapsed) {
pierre@1: foreach ($groups as $group) {
pierre@1: $options[$group->tid] = $group->name;
pierre@1: }
pierre@1: $form['group_rules']['groups'] = array(
pierre@1: '#type' => 'checkboxes',
pierre@1: '#title' => t('Allow advertisements from specific ad groups'),
pierre@1: '#options' => $options,
pierre@1: '#prefix' => '',
pierre@1: '#suffix' => '
',
pierre@1: '#description' => t('By selecting one or more groups, only advertisements from the selected group(s) will be allowed to be added to this channel. If no groups are selected, any advertisement can be added to this channel regardless of its group.'),
pierre@1: '#default_value' => $chid ? unserialize($channel->groups) : array(),
pierre@1: );
pierre@1: }
pierre@1: else {
pierre@1: $form['group_rules']['none'] = array(
pierre@1: '#type' => 'markup',
pierre@1: '#value' => t('No ad groups have been created.'),
pierre@1: '#prefix' => '',
pierre@1: '#suffix' => '
',
pierre@1: );
pierre@1: }
pierre@1:
sly@2: $collapsed = (variable_get('ad_channel_display', 0) == 1) ? 0 : 1;
sly@2: $form['nonchannel_rules'] = array(
sly@2: '#type' => 'fieldset',
sly@2: '#title' => t('Not-in-channel ad rules'),
sly@2: '#collapsible' => TRUE,
sly@2: '#collapsed' => $collapsed,
sly@2: );
sly@2: if ($collapsed) {
sly@2: $form['nonchannel_rules']['info'] = array(
sly@2: '#type' => 'markup',
sly@2: '#prefix' => '',
sly@2: '#suffix' => '
',
sly@2: '#value' => t('You will need to set "!variable" to %value for these %type ad rules to be applicable. Currently these settings are doing nothing.', array('!variable' => l(t('display advertisements not assigned to any channel'), 'admin/content/ad/channel/settings'), '%value' => t('always'), '%type' => 'not-in-channel')),
sly@2: );
sly@2: }
piotre@7: $form['nonchannel_rules']['no_channel_percent'] = array(
sly@2: '#type' => 'select',
piotre@7: '#title' => t('Percentage'),
piotre@7: '#options' => _ad_channel_percentages(),
piotre@7: '#default_value' => $chid ? $channel->no_channel_percent : 10,
piotre@7: '#description' => t('Choose the maximum percentage of not-in-channel advertisements allowable for display. For instance, selecting 10% indicates that 1 out of 10 advertisements will be selected from those not assigned to this channel.'),
sly@2: );
pierre@1: if ($chid) {
pierre@1: $form['update'] = array(
pierre@1: '#type' => 'submit',
pierre@1: '#value' => t('Update'),
pierre@1: );
pierre@1: $form['delete'] = array(
pierre@1: '#type' => 'submit',
pierre@1: '#value' => t('Delete'),
pierre@1: );
pierre@1: }
pierre@1: else {
pierre@1: $form['submit'] = array(
pierre@1: '#type' => 'submit',
pierre@1: '#value' => t('Create'),
pierre@1: );
pierre@1: }
pierre@1: $form['cancel'] = array(
pierre@1: '#type' => 'markup',
pierre@1: '#value' => l(t('Cancel'), 'admin/content/ad/channel'),
pierre@1: );
pierre@1:
pierre@1: return $form;
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Validate the channel.
pierre@1: */
pierre@1: function ad_channel_admin_channel_validate($form, &$form_state) {
pierre@1: $chid = 0;
pierre@1: if ($form_state['values']['op'] == t('Create')) {
pierre@1: $chid = db_result(db_query("SELECT chid FROM {ad_channel} WHERE name = '%s'", $form_state['values']['name']));
pierre@1: }
pierre@1: else if ($form_state['values']['op'] == t('Update')) {
pierre@1: $chid = db_result(db_query("SELECT chid FROM {ad_channel} WHERE name = '%s' AND chid != %d", $form_state['values']['name'], $form_state['values']['chid']));
pierre@1: }
pierre@1: if ($chid) {
pierre@1: form_set_error('name', t('A channel named %name already exists.', array('%name' => $form_state['values']['name'])));
pierre@1: }
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Save the channel.
pierre@1: */
pierre@1: function ad_channel_admin_channel_submit($form, &$form_state) {
sly@2: // remove extraneous white space from url list which can break matching
sly@2: $url_array = explode("\n", $form_state['values']['urls']);
sly@2: if (is_array($url_array)) {
sly@2: foreach ($url_array as $url) {
sly@2: $urls[] = trim($url);
sly@2: }
sly@2: $urls = implode("\n", $urls);
sly@2: }
sly@2: else {
sly@2: $urls = '';
sly@2: }
pierre@1: switch ($form_state['values']['op']) {
pierre@1: case t('Create'):
piotre@7: db_query("INSERT INTO {ad_channel} (name, description, conid, weight, display, no_channel_percent, urls, groups, inventory) VALUES('%s', '%s', %d, %d, %d, '%s', '%s', %d, %d)", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['conid'], $form_state['values']['weight'], $form_state['values']['display'], $form_state['values']['no_channel_percent'], serialize($urls), serialize($form_state['values']['groups']), $form_state['values']['inventory']);
pierre@1: drupal_set_message(t('The %name channel has been created.', array('%name' => $form_state['values']['name'])));
pierre@1: break;
pierre@1: case t('Update'):
pierre@1: $groups = array();
pierre@1: // Don't store information about groups that no longer exist.
pierre@1: if (is_array($form_state['values']['groups'])) {
pierre@1: $ad_groups = taxonomy_get_tree(_ad_get_vid());
pierre@1: foreach ($ad_groups as $ad_group) {
pierre@1: if (isset($form_state['values']['groups'][$ad_group->tid])) {
pierre@1: $groups[$ad_group->tid] = $form_state['values']['groups'][$ad_group->tid];
pierre@1: }
pierre@1: }
pierre@1: }
piotre@7: db_query("UPDATE {ad_channel} SET name = '%s', description = '%s', conid = %d, weight = %d, display = %d, urls = '%s', groups = '%s', no_channel_percent = %d, inventory = %d WHERE chid = %d", $form_state['values']['name'], $form_state['values']['description'], $form_state['values']['conid'], $form_state['values']['weight'], $form_state['values']['display'], serialize($urls), serialize($groups), $form_state['values']['no_channel_percent'], $form_state['values']['inventory'], $form_state['values']['chid']);
pierre@1: drupal_set_message(t('The %name channel has been updated.', array('%name' => $form_state['values']['name'])));
pierre@1: break;
pierre@1: case t('Delete'):
pierre@1: drupal_goto('admin/content/ad/channel/channel/'. $form_state['values']['chid'] .'/delete');
pierre@1: }
pierre@1: drupal_goto('admin/content/ad/channel');
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Confirm whether or not to delete container, and the contained channels.
pierre@1: */
sly@2: function ad_channel_admin_confirm_delete_channel($form_state, $channel) {
pierre@1: $form = array();
pierre@1:
pierre@1: $form['chid'] = array(
pierre@1: '#type' => 'value',
sly@2: '#value' => $channel->chid,
pierre@1: );
pierre@1:
pierre@1: return confirm_form(
pierre@1: $form,
pierre@1: t('Are you sure you want to delete the %name channel?', array('%name' => $channel->name)),
pierre@1: 'admin/content/ad/channel',
pierre@1: t('Any advertisements currently assigned to the %name channel will not be deleted, they will be reassigned. This action can not be undone.', array('%name' => $channel->name)),
pierre@1: t('Delete'),
pierre@1: t('Cancel'));
pierre@1: }
pierre@1:
pierre@1: /**
pierre@1: * Delete a channel.
pierre@1: */
pierre@1: function ad_channel_admin_confirm_delete_channel_submit($form, &$form_state) {
pierre@1: $channel = _ad_channel_get_channels($form_state['values']['chid']);
pierre@1: if ($channel->chid) {
pierre@1: db_query('DELETE FROM {ad_channel} WHERE chid = %d', $channel->chid);
pierre@1: drupal_set_message(t('The %name channel has been deleted.', array('%name' => $channel->name)));
pierre@1: }
pierre@1: drupal_goto('admin/content/ad/channel');
pierre@1: }
pierre@1:
sly@2: /**
sly@2: * Available probabilities.
sly@2: */
sly@2: function _ad_channel_probabilities() {
sly@2: return array(
sly@2: 25 => t('1/4'),
sly@2: 33 => t('1/3'),
sly@2: 50 => t('1/2'),
sly@2: 100 => t('1'),
sly@2: 200 => t('2'),
sly@2: 300 => t('3'),
sly@2: 400 => t('4'),
sly@2: );
sly@2: }
piotre@7:
piotre@7: /**
piotre@7: * Available percentages
piotre@7: */
piotre@7: function _ad_channel_percentages() {
piotre@7: $options = array();
piotre@7: for($i = 5; $i <= 95; $i += 5) {
piotre@7: $options[$i] = t($i.'%');
piotre@7: }
piotre@7: return $options;
piotre@7: }
piotre@7:
piotre@7: function _ad_channel_get_channel_active_ad_count($chid) {
piotre@7: if ($chid) {
piotre@7: $count = db_result(db_query("SELECT COUNT(nid) AS count FROM {ad_channel_node} acn LEFT JOIN {ads} a ON acn.nid = a.aid WHERE acn.chid = %d AND a.adstatus = 'active'", $chid));
piotre@7: }
piotre@7: return $count;
piotre@7: }