t('Only this website'), 'public' => t('World - www.scribd.com'));
}
define ('DEFAULT_PRIVATE', 'private');
function ipaper_license_options() {
return array(
'ns' => t('Unspecified - no licensing information shown'),
'by' => t('By attribution'),
'by-nc' => t('By attribution, non-commercial'),
'by-nc-nd' => t('By attribution, non-commercial, non-derivative'),
'by-nc-sa' => t('By attribution, non-commercial, share like'),
'by-nd' => t('By attribution, non-derivative'),
'by-sa' => t('By attribution, share alike'),
'pd' => t('Public domain'),
'c' => t('Copyright - all rights reserved'),
);
}
define ('DEFAULT_LICENSE', 'by-nc');
/**
* Implementation of hook_help().
*/
function ipaper_help($path, $arg) {
switch ($path) {
case 'admin/modules#description':
return t('Allows you to embed iPaper objects hosted at scribd.com.');
case 'node/add#ipaper':
return t('Add a paper.');
}
}
/**
* Implementation of hook_perm().
*/
function ipaper_perm() {
return array("create ipaper", "view ipapers", "edit own ipapers", "edit ipapers", "delete own ipapers", "delete ipapers", "embed ipapers", "embed own ipapers", "download ipapers", "edit ipaper parameters");
}
/**
* Implementation of hook_node_info().
*/
function ipaper_node_info() {
return array('ipaper' => array(
'name' => 'iPaper',
'description' => t('An iPaper is a document hosted on the scribd website.'),
'module' => 'ipaper'));
}
/**
* Implementation of hook_access().
*/
function ipaper_access($op, $node, $account) {
switch ($op) {
case 'create':
return user_access('create ipaper');
case 'view':
if ($node->uid == $account->uid && $account->uid != 0)
return TRUE;
if ($node->status == 0)
return user_access('administer nodes');
return user_access('view ipapers');
case 'update':
if ($account->uid == $node->uid && user_access("edit own ipapers")) {
return TRUE;
}
else {
return user_access("edit ipapers");
}
case 'delete':
if ($account->uid == $node->uid && user_access("delete own ipapers")) {
return TRUE;
}
else {
return user_access("delete ipapers");
}
default:
return FALSE;
}
}
/**
* Implementation of hook_form().
* This function is called to retrieve the form that is displayed when one attempts
* to create/edit an ipaper
*/
function ipaper_form(&$node) {
$type = node_get_types('type', 'ipaper');
$form['title'] = array(
'#type' => 'textfield',
'#title' => $type->title_label,
'#default_value' => $node->title,
'#required' => TRUE,
'#weight' => -10,
);
$form['body'] = array(
'#type' => $type->has_body ? 'textarea': 'hidden',
'#title' => $type->body_label,
'#default_value' => $node->body,
'#description' => t('This text is displayed with your document.'),
'#weight' => -5,
);
$form['private'] = array(
'#type' => variable_get('ipaper_choose_private', 1) ? 'select' : 'hidden',
'#title' => t('Visibility'),
'#options' => ipaper_private_options(),
'#default_value' => ($node->private) ? $node->private : variable_get('ipaper_default_private', DEFAULT_PRIVATE),
'#description' => t('Private documents are only available through this website. Public documents are also available on scribd.com and are indexed by search engines.'),
'#weight' => -1,
);
$form['license'] = array(
'#type' => variable_get('ipaper_choose_license', 1) ? 'select' : 'hidden',
'#title' => t('License'),
'#options' => ipaper_license_options(),
'#default_value' => ($node->license) ? $node->license : variable_get('ipaper_default_license', DEFAULT_LICENSE),
'#description' => t('The license under which the document is published. For more information about licenses, see http://creativecommons.org/'),
'#weight' => -1,
);
//these parameters are to be shown and edited only by administrators unless you want your users to create ipapers by entering these parameters
if (user_access("edit ipaper parameters")) {
$form['doc_id'] = array(
'#type' => 'textfield',
'#title' => t('doc_id'),
'#default_value' => $node->doc_id,
'#description' => t('Scribd document ID. Required unless you are attaching a file.'),
'#required' => FALSE,
'#weight' => 0,
);
$form['secret_password'] = array(
'#type' => 'textfield',
'#title' => t('secret_password'),
'#default_value' => $node->secret_password,
'#description' => t('Scribd secret password'),
'#required' => FALSE,
'#weight' => 0,
);
$form['access_key'] = array(
'#type' => 'textfield',
'#title' => t('access_key'),
'#default_value' => $node->access_key,
'#description' => t('Scribd document access key. Required unless you are attaching a file.'),
'#required' => FALSE,
'#weight' => 0,
);
$form['fid'] = array(
'#type' => 'hidden',
//change type to textfield if you want to be able to edit this
'#title' => t('fid'),
'#default_value' => $node->fid,
'#description' => t('Drupal upload file ID. This is updated automatically by the module to track which file was last uploaded to scribd.'),
'#required' => FALSE,
'#weight' => 0,
);
} //if (user_access...
return $form;
}
/**
* Implementation of hook_validate().
*/
function ipaper_validate($node) {
//check to make sure that there are attachments
$files = $node->files;
if (!$files && !($node->doc_id && $node->access_key)) {
form_set_error('files[upload]', t('You must upload an attachment to create an iPaper.'));
return;
}
//also show a message if there is more than one attachment
if (count($files)>1) {
drupal_set_message(t('iPapers are created from a single document. The iPaper that is displayed will always be generated from your most recent upload.'), 'notice');
}
}
/**
* Database hooks when loading, inserting, updating or deleting an ipaper
*/
function ipaper_load($node) {
$paper = db_fetch_object(db_query('SELECT * FROM {ipaper} WHERE nid = %d', $node->nid));
return $paper;
}
function ipaper_insert($node) {
db_query("INSERT INTO {ipaper} (nid, fid, doc_id, secret_password, access_key, private, license) VALUES (%d, %d, %d, '%s', '%s', '%s', '%s')", $node->nid, $node->fid, $node->doc_id, $node->secret_password, $node->access_key, $node->private, $node->license);
$_REQUEST['destination'] = "ipaper_transfer/$node->nid";
//using drupal_goto would redirect before the node is saved
}
function ipaper_update($node) {
ipaper_dbupdate($node);
$_REQUEST['destination'] = "ipaper_transfer/$node->nid";
}
function ipaper_dbupdate($node) {
//used when a node is saved/submitted in Drupal as well as when the scribd.com API returns keys.
if (user_access('edit ipaper parameters')) {
_ipaper_dbupdate_params($node);
}
return db_query("UPDATE {ipaper} SET private = '%s', license = '%s' WHERE nid = %d", $node->private, $node->license, $node->nid);
}
function _ipaper_dbupdate_params($node) {
//used when when the scribd.com API returns keys.
return db_query("UPDATE {ipaper} SET fid = %d, doc_id = %d, secret_password = '%s', access_key = '%s' WHERE nid = %d", $node->fid, $node->doc_id, $node->secret_password, $node->access_key, $node->nid);
}
function _ipaper_dbupdate_full_text($node) {
//save full text for searching.
return db_query("UPDATE {ipaper} SET full_text = '%s' WHERE nid = %d", $node->full_text, $node->nid);
}
function ipaper_delete($node) {
db_query('DELETE FROM {ipaper} WHERE nid = %d', $node->nid);
$scribd = ipaper_scribd_init();
$result = $scribd->delete($node->doc_id);
if (!$result) ipaper_report_error($scribd);
}
/**
* Implementation of hook_menu().
*/
function ipaper_menu() {
$items = array();
$items['admin/settings/ipaper'] = array(
'title' => t('iPaper module configuration'),
'description' => t('iPaper API keys and configuration.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('ipaper_config_form'),
'access callback' => 'user_access',
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
$items['ipaper_transfer/%node'] = array(
'title' => t('Please wait...'),
'access callback' => 'node_access',
'access arguments' => array('update', 1),
'page callback' => 'ipaper_transfer',
'page arguments' => array(1),
'type' => MENU_CALLBACK,
);
$items['ipaper_upload/%node'] = array(
'title' => t('Please wait...'),
'access callback' => 'node_access',
'access arguments' => array('update', 1),
'page callback' => 'ipaper_upload',
'page arguments' => array(1),
'type' => MENU_CALLBACK,
);
$items['ipaper_download/%node'] = array(
'title' => t('Redirecting...'),
'access callback' => 'user_access',
'access arguments' => array('download ipapers'),
'page callback' => 'ipaper_download',
'page arguments' => array(1),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Menu callback: ipaper_transfer
* This function is called each time an ipaper node is created/updated and has the role of
* synchronizing the document on the scribd server with the Drupal node.
* Note that these operations happen at a menu callback page rather than in _update or _insert because:
* 1. within _update and _insert the attachments have not been saved
* 2. nodes should be saved regardless of whether the 'transfer' succeeds (a timeout or error for the
* API at scribd.com should not affect the node update
* 3. it helps to display a progress bar while the file is transferred to scribd.com, since this could take a while
*/
function ipaper_transfer($node) {
if ($node->type != 'ipaper') {drupal_access_denied(); return;}
$files = $node->files;
if ($files) $file = end($files);
//returns the most recent upload for this node
if (!($file)) {
drupal_goto("node/$node->nid");
return;
}
if ($node->fid == $file->fid && $node->doc_id) {
//The current version is already on scribd.
$scribd = ipaper_scribd_init();
global $base_url;
$docpath = $base_url ."/node/$node->nid";
//if license is unspecified, don't send anything to scribd
if ($node->license=='ns') $node->license = NULL;
$result = $scribd->changeSettings($node->doc_id, $node->title, '', $node->private, $node->license, NULL, NULL, NULL, $docpath);
if (!$result) ipaper_report_error($scribd);
//refresh the thumbnail, just in case a pdf or word icon was given by scribd initially
@file_delete(_ipaper_get_thumb_path($node->doc_id));
_ipaper_save_thumb($node->doc_id, $scribd);
drupal_goto("node/$node->nid");
return;
}
//the file on scribd needs to be updated/created set the stage for a file upload
$dest = url("ipaper_upload/$node->nid");
drupal_set_html_head('');
$text = theme('progress_bar', NULL, t('Preparing document...'));
$text .= t('This can take a while, depending on the size of your upload.');
return $text;
}
function ipaper_upload($node) {
$starttime = time();
if ($node->type != 'ipaper') {drupal_access_denied(); return;}
$files = $node->files;
if ($files) $file = end($files);
//returns the most recent upload for this node
$scribd = ipaper_scribd_init();
$url = $file->filepath;
$doc_type = NULL;
$access = $node->private;
//adds a new revision to an existing scribd document, if it exists
if ($node->doc_id) {
$rev_id = $node->doc_id;
}
else $rev_id = NULL;
$data = $scribd->upload($url, $doc_type, $access, $rev_id);
if ($data) {
$res=$scribd->getdocresult();
$node->fid = $file->fid;
$node->doc_id = $res->doc_id;
$node->access_key = $res->access_key;
$node->secret_password = $res->secret_password;
//save to database
_ipaper_dbupdate_params($node);
if ($rev_id) {
drupal_set_message(t('A new version of your document has been uploaded. It may take a few minutes until the most recent version is displayed.'));
file_delete(_ipaper_get_thumb_path($node->doc_id));
}
//set license settings (access/visibility settings were set at the time of the upload)
global $base_url;
$docpath = $base_url ."/node/$node->nid";
$scribd->changeSettings($node->doc_id, $node->title, '', $node->private, $node->license, NULL, NULL, NULL, $docpath);
//wait for conversion to complete so that we can fetch the full text for the search index
$stat = $scribd->getConversionStatus($node->doc_id);
while ($stat != "DONE") {
if ($stat == "ERROR") {
drupal_set_message(t("Your document could not be successfully converted to an iPaper. See the message in the document display for more information"), 'error');
watchdog("ipaper", "Scribd failed conversion for document", NULL, WATCHDOG_ERROR, l($node->title, "node/$node->nid"));
drupal_goto("node/$node->nid");
return;
}
//don't let the script run until php times out or more than 57 seconds
if (time() - $starttime > min(ini_get('max_execution_time'), 57) ) {
//drupal_set_message(t("Your document is taking unusually long to convert."));
$message = "Exceeded time limit waiting for document to complete conversion: %time seconds. Full text will be retrieved on next cron run.";
watchdog("ipaper", $message, array('%time' => time() - $starttime), WATCHDOG_NOTICE, l($node->title, "node/$node->nid"));
drupal_goto("node/$node->nid");
return;
}
sleep(2);
$stat = $scribd->getConversionStatus($node->doc_id);
}
ipaper_get_full_text($node, $scribd);
}
else ipaper_report_error($scribd);
drupal_goto("node/$node->nid");
}
function ipaper_get_full_text($node, $scribd){
//get full text for search index
$texturl = $scribd->getDownloadURL($node->doc_id, 'txt');
//for some reason, the URL comes back with leading and trailing spaces
$texturl = trim($texturl);
$full_text = _ipaper_request($texturl);
$full_text = htmlspecialchars($full_text);
$full_text = preg_replace('|(?)\s*\n|', "
\n", $full_text); // make line breaks
if ($full_text) {
$node->full_text = $full_text;
_ipaper_dbupdate_full_text($node);
return TRUE;
}
}
function ipaper_download($node) {
$doc_id = $node->doc_id;
if ($doc_id) {
$scribd = ipaper_scribd_init();
$format = variable_get('ipaper_download_format', 'pdf');
$link = $scribd->getDownloadURL($node->doc_id, $format);
$link = trim($link);
if ($link) {
drupal_goto($link);
return;
}
}
drupal_set_message("Not an iPaper or the download link is not available", 'error');
drupal_goto("node/$nid");
}
function ipaper_scribd_init() {
if (variable_get('scribd_api_key', '') == '') {
drupal_set_message(t('The iPaper module has not yet been configured. You need to set an API key obtained from scribd.com/platform/start before you can use the module'), 'error');
}
require_once drupal_get_path('module', 'ipaper') .'/scribd.php';
$scribd_api_key = variable_get('scribd_api_key', '');
$scribd_secret = variable_get('scribd_secret_key', '');
$scribd = new Scribd($scribd_api_key, $scribd_secret);
//uncomment this if you want to store documents under the virtual accounts for each user
//note that files created for virtual users are only accessible through the API
//global $user;
//$scribd->my_user_id = $user->name; // The user ID of one of your users
return $scribd;
}
function ipaper_report_error($scribd) {
drupal_set_message("Scribd error #". $scribd->geterror() .": ". $scribd->geterrormsg(), 'error');
watchdog('ipaper', "Scribd error #%number: %msg", array('%number' => $scribd->geterror(), '%msg' => $scribd->geterrormsg()), WATCHDOG_ERROR);
}
/**
* Implementation of hook_view().
*/
function ipaper_view($node, $teaser = FALSE, $page = FALSE) {
$node = node_prepare($node, $teaser);
drupal_add_css(drupal_get_path('module', 'ipaper') .'/ipaper.css');
if ($teaser == FALSE) {
$type = node_get_types('type', 'ipaper');
$fs = array(
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => $type->body_label,
'#value' => $node->content['body']['#value'],
);
if ($type->has_body && $node->content['body']['#value']!='') {
$node->content['body']['#value'] = theme('fieldset', $fs);
}
$node->content['viewer'] = array(
'#value' => theme('ipaper_viewer', $node),
'#weight' => 2,
);
if (user_access("download ipapers")) {
$node->content['download_link'] = array(
'#value' => theme('ipaper_download_link', $node),
'#weight' => 3,
);
}
if (variable_get('ipaper_show_scribd_link', 0)) {
$node->content['scribd_link'] = array(
'#value' => theme('ipaper_scribd_link', $node),
'#weight' => 4,
);
}
if (user_access("embed ipapers") || (user_access("embed own ipapers") && $node->uid == $user->uid)) {
$node->content['embed_code'] = array(
'#value' => theme('ipaper_embed_code', $node),
'#weight' => 5,
);
}
if (variable_get('ipaper_show_full_text', 1) || variable_get('cron_semaphore', FALSE)) {
$node->content['full_text'] = array(
'#value' => theme('ipaper_full_text', $node),
'#weight' => 6,
);
}
$node->content['license'] = array(
'#value' => theme('ipaper_license', $node),
'#weight' => 8,
);
}//if teaser=false
else{
$node->content['body']['#value'] = "