You are here

vkxp.module in VK CrossPoster 6.2

Same filename and directory in other branches
  1. 8 vkxp.module
  2. 6.3 vkxp.module
  3. 6 vkxp.module
  4. 7.2 vkxp.module
  5. 7 vkxp.module

File

vkxp.module
View source
<?php

/**
 * Implementation of hook_help().
 */
function vkxp_help($path, $arg) {
  switch ($path) {
    case 'admin/settings/vkxp':
      return t('Vkontakte CrossPoster module allows users to post nodes automatically to social network vkontakte.ru.');
    case 'admin/help#vkxp':
      $output = '';
      $output .= '<p>' . t('Vkontakte CrossPoster module allows users to post nodes automatically to social network vkontakte.ru.') . '</p>';
      $output .= '<p>' . t('It requires creating standalone application http://vkontakte.ru/apps.php?act=add&site=1') . '</p>';
      $output .= '<p>' . t('After creating application you should go to module settings page and put there secret code and application ID') . '</p>';
      return $output;
  }
}

/**
 * Implementation of hook_menu().
 */
function vkxp_menu() {
  $items = array();
  $items['admin/settings/vkxp'] = array(
    'title' => 'VKontakte CrossPoster',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'vkxp_admin_main_settings',
    ),
    'access arguments' => array(
      'administer vkontakte crossposter',
    ),
    'file' => 'vkxp.admin.inc',
  );
  $items['admin/settings/vkxp/main'] = array(
    'title' => 'Main settings',
    'file' => 'vkxp.admin.inc',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  $items['admin/settings/vkxp/node'] = array(
    'title' => 'Node settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'vkxp_admin_node_settings',
    ),
    'access arguments' => array(
      'administer vkontakte crossposter',
    ),
    'file' => 'vkxp.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 1,
  );
  $items['admin/settings/vkxp/images'] = array(
    'title' => 'Images settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'vkxp_admin_images_settings',
    ),
    'access arguments' => array(
      'administer vkontakte crossposter',
    ),
    'file' => 'vkxp.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 2,
  );
  $items['vkxp/captcha'] = array(
    'page callback' => 'vkxp_captcha_page',
    'access arguments' => array(
      'post to vkontakte',
    ),
    'file' => 'vkxp.pages.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implementation of hook_perm().
 */
function vkxp_perm() {
  return array(
    'administer vkontakte crossposter',
    'post to vkontakte',
  );
}

/**
 * Implementation of hook_form_alter().
 */
function vkxp_form_alter(&$form, &$form_state, $form_id) {
  $node_types = _vkxp_get_selected_node_types();
  foreach ($node_types as $node_type) {
    if ($form_id == $node_type . '_node_form') {
      _vkxp_process_node_form($form);
    }
  }
}

/**
 * Implementation of hook_init().
 */
function vkxp_init() {
  if (isset($_SESSION['vkxp']) && count($_SESSION['vkxp'])) {

    // Get first script from session.
    $script = array_shift($_SESSION['vkxp']);

    // Add settings for node crosspost.
    drupal_add_js(array(
      'vkxp' => array(
        'app_id' => variable_get('vkxp_app_id', ''),
        'owner_id' => $script['owner_id'],
        'message' => $script['message'],
        'from_group' => $script['from_group'],
        'attachments' => $script['attachments'],
      ),
    ), 'setting');
    drupal_add_js(drupal_get_path('module', 'vkxp') . '/vkxp.js');

    // Add jquery ui dialog (for captcha).
    drupal_add_css(jquery_ui_get_path() . '/themes/default/ui.all.css');
    jquery_ui_add('ui.dialog');
  }
}

/**
 * Add vkxp fieldset to node forms.
 * @param $form: node form.
 */
function _vkxp_process_node_form(&$form) {
  if (user_access('post to vkontakte')) {
    $form['vkxp'] = array(
      '#type' => 'fieldset',
      '#title' => t('VKontakte crossposter'),
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
      '#weight' => 0,
    );
    $form['vkxp']['vkxp_post_this_node'] = array(
      '#type' => 'checkbox',
      '#title' => t('Post this node to vkontakte.ru'),
      '#default_value' => variable_get('vkxp_enabled_default', 0),
    );
    if (!function_exists('curl_init')) {
      $form['vkxp']['vkxp_post_this_node']['#disabled'] = TRUE;
      $form['vkxp']['vkxp_post_this_node']['#value'] = 0;
      $form['vkxp']['vkxp_post_this_node']['#description'] = t("You can't crosspost nodes until cURL library is not installed on your server");
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function vkxp_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if ($op == 'insert' || $op == 'update') {

    // Collect data and access to post node.
    $access_token = variable_get('vkxp_access_token', '');
    $vkxp_enabled = variable_get('vkxp_enable', 0);
    $user_access = user_access('post to vkontakte');
    $post_node = FALSE;
    if (isset($node->vkxp_post_this_node)) {
      $post_node = $node->vkxp_post_this_node;
    }

    // Check requiered data to post.
    if ($access_token && $vkxp_enabled && $user_access && $post_node) {
      $selected_types = _vkxp_get_selected_node_types();

      // If current node related to selected types list - crosspost it.
      if (in_array($node->type, $selected_types)) {

        // Clear cached data if user wants to add link to this page.
        // If cache will not be cleared, vkontakte may not post this node due to unaccessable web url.
        if (variable_get('vkxp_add_link', 0) && CACHE_DISABLED !== variable_get('cache', CACHE_DISABLED) && $op == 'insert') {
          cache_clear_all(NULL, 'cache_page');
        }

        // Get absolute node uri.
        $url = url('node/' . $node->nid, array(
          'absolute' => TRUE,
        ));

        // Get message from node.
        if (variable_get('vkxp_post_object', 'body') == 'body') {
          $message = trim(strip_tags($node->body));
        }
        elseif (variable_get('vkxp_post_object', 'body') == 'title') {
          $message = trim(check_plain($node->title));
        }
        else {
          $message = trim(check_plain($node->title)) . "\n\n" . trim(strip_tags($node->body));
        }

        // Trim message if needed.
        if (variable_get('vkxp_cut_body', 1)) {
          $length = variable_get('vkxp_cut_body_length', 255);
          if (drupal_strlen($message) > $length) {
            $message = drupal_substr($message, 0, $length - 3) . '...';
          }
        }

        // Decode special symbols.
        $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8');
        $message = htmlspecialchars_decode($message);

        // Post node to vk.
        $images = _vkxp_get_node_images($node);
        $image_ids = '';
        if ($images) {
          $upload_url = _vkxp_get_upload_server();
          $image_ids = _vkxp_upload_images($upload_url, $images);
        }
        _vkxp_post_to_wall($message, $image_ids, $url, $node);
      }
    }
  }
}

/**
 * Function makes query to vk.com.
 * Allows using hook_vkxp_query_alter() for altering query params.
 */
function vkxp_query($method, $params, $request_url = 'https://api.vkontakte.ru/method/') {

  // Collect params for request.
  $query = array();
  $query['method'] = $method;
  $query['params'] = $params;
  $query['request_url'] = $request_url;
  drupal_alter('vkxp_query', $query);

  // cURL request.
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $query['request_url'] . $query['method']);
  curl_setopt($curl, CURLOPT_POST, 1);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $query['params']);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  $result = curl_exec($curl);
  curl_close($curl);
  return json_decode($result, TRUE);
}

/**
 * Get images realpath from selected imagefield.
 * @param $node: node object.
 * @return array: array with images for uploading.
 */
function _vkxp_get_node_images($node) {
  $images = array();
  $image_amount = variable_get($node->type . '_image_amount', 0);
  if ($image_amount) {
    $field = variable_get($node->type . '_image_field', '');
    if ($field && isset($node->{$field})) {
      $i = 0;
      foreach ($node->{$field} as $image) {
        if ($image['filepath']) {
          if ($i++ == $image_amount) {
            break;
          }
          $images[] = '@' . realpath($image['filepath']);
        }
      }
    }
  }
  return $images;
}

/**
 * @return array: node types selected for crossposting.
 */
function _vkxp_get_selected_node_types() {

  // Get node types that should be crossposted.
  $types = variable_get('vkxp_node_types', array());
  $selected_types = array();
  foreach ($types as $key => $type) {
    if ($type) {
      $selected_types[$key] = $type;
    }
  }
  return $selected_types;
}

/**
 * Makes http query to api server to get upload uri.
 * @return upload url on success or FALSE on failure.
 */
function _vkxp_get_upload_server() {
  $params = array();
  if (variable_get('vkxp_wall_owner', 'group') == 'group') {
    $params['gid'] = variable_get('vkxp_group_id', '');
  }
  else {
    $params['uid'] = variable_get('vkxp_group_id', '');
  }
  $params['access_token'] = variable_get('vkxp_access_token', '');
  $result = vkxp_query('photos.getWallUploadServer', $params);
  if ($result['response']['upload_url']) {
    return $result['response']['upload_url'];
  }
  elseif ($result['error']) {
    _vkxp_watchdog(array(
      'text' => t('Unable to recieve upload server. Error: !error', array(
        '!error' => $result['error']['error_msg'],
      )),
      'severity' => 'error',
    ));
  }
  return FALSE;
}

/**
 * Upload and save images to vk server.
 * @param  $upload_url: url of upload server.
 * @param  $images: array of images to upload.
 * @return string with uploaded image IDs separated by comma. Example: photo312312_3123123,photo312312_3123124.
 */
function _vkxp_upload_images($upload_url, $images) {

  // Array with saved image IDs.
  $image_ids = array();
  foreach ($images as $image) {

    // Upload photo.
    $upload_result = vkxp_query('', array(
      'photo' => $image,
    ), $upload_url);

    // If photo was uploaded it should be saved.
    if ($upload_result['server'] && $upload_result['photo'] && $upload_result['hash']) {
      $params = array();
      $params['access_token'] = variable_get('vkxp_access_token', '');
      $params['server'] = $upload_result['server'];
      $params['photo'] = $upload_result['photo'];
      $params['hash'] = $upload_result['hash'];
      if (variable_get('vkxp_wall_owner', 'group') == 'group') {
        $params['gid'] = variable_get('vkxp_group_id', '');
      }
      else {
        $params['uid'] = variable_get('vkxp_group_id', '');
      }
      $save_result = vkxp_query('photos.saveWallPhoto', $params);

      // If image was successfully saved it returns photo ID in format 'photoXXXXXXX_XXXXXXX'.
      if ($save_result['response'][0]['id']) {
        $image_ids[] = $save_result['response'][0]['id'];
      }
    }
  }
  if ($image_ids) {
    return implode(',', $image_ids);
  }
  return '';
}

/**
 * Post node message with uploaded images to wall.
 * @param  $message: text to post.
 * @param  $images: string with photo IDs to post.
 * @param  $url: absolute link to posted node.
 * @return array: server response.
 */
function _vkxp_post_to_wall($message, $images, $url, $node) {
  $params = array();
  $params['from_group'] = variable_get('vkxp_official', 1);
  if (variable_get('vkxp_wall_owner', 'group') == 'group') {
    $params['owner_id'] = '-' . variable_get('vkxp_group_id', '');
  }
  else {
    $params['owner_id'] = variable_get('vkxp_group_id', '');
  }
  $params['message'] = $message;
  $params['attachments'] = $images;
  if (variable_get('vkxp_add_link', 0)) {
    if ($images) {
      $params['attachments'] .= ',' . $url;
    }
    else {
      $params['attachments'] = $url;
    }
  }
  $params['application_id'] = variable_get('vkxp_app_id', '');

  // Add script that will be shown on the first node load.
  $_SESSION['vkxp'][$node->nid] = $params;
}

/**
 * Log messages and print it on the screen.
 * @param $message: array with message and it severity.
 * @param $link: link to view node.
 */
function _vkxp_watchdog($message, $link = NULL) {
  drupal_set_message($message['text'], $message['severity']);
  if ($message['severity'] == 'status') {
    $severity = WATCHDOG_INFO;
  }
  elseif ($message['severity'] == 'warning') {
    $severity = WATCHDOG_WARNING;
  }
  else {
    $severity = WATCHDOG_ERROR;
  }
  watchdog('vkxp', $message['text'], array(), $severity, $link);
}

Functions

Namesort descending Description
vkxp_form_alter Implementation of hook_form_alter().
vkxp_help Implementation of hook_help().
vkxp_init Implementation of hook_init().
vkxp_menu Implementation of hook_menu().
vkxp_nodeapi Implementation of hook_nodeapi().
vkxp_perm Implementation of hook_perm().
vkxp_query Function makes query to vk.com. Allows using hook_vkxp_query_alter() for altering query params.
_vkxp_get_node_images Get images realpath from selected imagefield.
_vkxp_get_selected_node_types
_vkxp_get_upload_server Makes http query to api server to get upload uri.
_vkxp_post_to_wall Post node message with uploaded images to wall.
_vkxp_process_node_form Add vkxp fieldset to node forms.
_vkxp_upload_images Upload and save images to vk server.
_vkxp_watchdog Log messages and print it on the screen.