You are here

vkxp.module in VK CrossPoster 6

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/editapp?act=create&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,
  );
  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);
    }
  }
}

/**
 * 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') {

    // If access token is recieved, if crossposting enabled, if user has access to crosspost nodes, if user checked this node to post:
    if (variable_get('vkxp_access_token', '') && variable_get('vkxp_enable', 0) && user_access('post to vkontakte') && $node->vkxp_post_this_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 node url
        if (variable_get('vkxp_add_link', 0) && CACHE_DISABLED !== variable_get('cache', CACHE_DISABLED)) {
          cache_clear_all(NULL, 'cache_page');
        }

        // Get node url
        $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 = htmlspecialchars_decode(html_entity_decode($message, ENT_QUOTES, 'UTF-8'));

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

/**
 * Function makes query to vkontakte.ru
 * Allows using hook_vkxp_query_alter() for altering query params
 */
function vkxp_query($method, $params, $request_url = 'https://api.vkontakte.ru/method/') {
  $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 page
 * @return array: server response
 */
function _vkxp_post_to_wall($message, $images, $url, $node) {
  $params = array();
  if (variable_get('vkxp_wall_owner', 'group') == 'group') {
    $params['owner_id'] = '-' . variable_get('vkxp_group_id', '');
    $params['from_group'] = variable_get('vkxp_official', 1);
  }
  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['access_token'] = variable_get('vkxp_access_token', '');
  $result = vkxp_query('wall.post', $params);
  if ($result['response']['post_id'] || $result['response']['processing']) {
    _vkxp_watchdog(array(
      'text' => t('Node "!title"was successfully posted to vkontakte.ru', array(
        '!title' => $node->title,
      )),
      'severity' => 'status',
    ), l(t('View'), 'node/' . $node->nid));
  }
  elseif ($result['error']) {
    _vkxp_watchdog(array(
      'text' => t('Node was not posted to vkontakte.ru. Error: !error', array(
        '!error' => $result['error']['error_msg'],
      )),
      'severity' => 'error',
    ), l($node->title, 'node/' . $node->nid));
  }
}

/**
 * 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_menu Implementation of hook_menu()
vkxp_nodeapi Implementation of hook_nodeapi
vkxp_perm Implementation of hook_perm()
vkxp_query Function makes query to vkontakte.ru 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