| 1 |
<?php
|
| 2 |
// $Id: wlw_blogapi.module,v 1.15 2008/12/10 02:22:40 jrglasgow Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Enable users to post using applications that support XML-RPC blog APIs.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Implementation of hook_help().
|
| 11 |
*/
|
| 12 |
function wlw_blogapi_help($path, $arg) {
|
| 13 |
switch ($path) {
|
| 14 |
case 'admin/help#blogapi':
|
| 15 |
$output = '<p>'. t('The blog API module enables a post to be posted to a site via external GUI applications. Many users prefer to use external tools to improve their ability to read and post responses in a customized way. The blog api provides users the freedom to use the blogging tools they want but still have the blogging server of choice.') .'</p>';
|
| 16 |
$output .= '<p>'. t('When this module is enabled and configured you can use programs like <a href="@external-http-ecto-kung-foo-tv">Ecto</a> to create and publish posts from your desktop. Blog API module supports several XML-RPC based blogging APIs such as the <a href="@-">Blogger API</a>, <a href="@external-http-www-xmlrpc-com-metaWeblogApi">MetaWeblog API</a>, and most of the <a href="@external-http-www-movabletype-org-docs-mtmanual_programmatic-html">Movable Type API</a>. Any desktop blogging tools or other services (e.g. <a href="@external-http-www-flickr-com">Flickr\'s</a> "post to blog") that support these APIs should work with this site.', array('@external-http-ecto-kung-foo-tv' => 'http://ecto.kung-foo.tv/', '@-' => url('http://www.blogger.com/developers/api/1_docs/'), '@external-http-www-xmlrpc-com-metaWeblogApi' => 'http://www.xmlrpc.com/metaWeblogApi', '@external-http-www-movabletype-org-docs-mtmanual_programmatic-html' => 'http://www.movabletype.org/docs/mtmanual_programmatic.html', '@external-http-www-flickr-com' => 'http://www.flickr.com')) .'</p>';
|
| 17 |
$output .= '<p>'. t('This module also allows site administrators to configure which content types can be posted via the external applications. So, for instance, users can post forum topics as well as blog posts. Where supported, the external applications will display each content type as a separate "blog".') .'</p>';
|
| 18 |
$output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@blogapi">BlogApi page</a>.', array('@blogapi' => 'http://drupal.org/handbook/modules/blogapi/')) .'</p>';
|
| 19 |
return $output;
|
| 20 |
}
|
| 21 |
}
|
| 22 |
|
| 23 |
/**
|
| 24 |
* Implementation of hook_perm().
|
| 25 |
*/
|
| 26 |
function wlw_blogapi_perm() {
|
| 27 |
return array('administer content with blog api');
|
| 28 |
}
|
| 29 |
|
| 30 |
/**
|
| 31 |
* Implementation of hook_xmlrpc().
|
| 32 |
*/
|
| 33 |
function wlw_blogapi_xmlrpc() {
|
| 34 |
return array(
|
| 35 |
array(
|
| 36 |
'blogger.getUsersBlogs',
|
| 37 |
'wlw_blogapi_blogger_get_users_blogs',
|
| 38 |
array('array', 'string', 'string', 'string'),
|
| 39 |
t('Returns a list of weblogs to which an author has posting privileges.')),
|
| 40 |
array(
|
| 41 |
'blogger.getUserInfo',
|
| 42 |
'wlw_blogapi_blogger_get_user_info',
|
| 43 |
array('struct', 'string', 'string', 'string'),
|
| 44 |
t('Returns information about an author in the system.')),
|
| 45 |
array(
|
| 46 |
'blogger.newPost',
|
| 47 |
'wlw_blogapi_blogger_new_post',
|
| 48 |
array('string', 'string', 'string', 'string', 'string', 'string', 'boolean'),
|
| 49 |
t('Creates a new post, and optionally publishes it.')),
|
| 50 |
array(
|
| 51 |
'blogger.editPost',
|
| 52 |
'wlw_blogapi_blogger_edit_post',
|
| 53 |
array('boolean', 'string', 'string', 'string', 'string', 'string', 'boolean'),
|
| 54 |
t('Updates the information about an existing post.')),
|
| 55 |
array(
|
| 56 |
'blogger.getPost',
|
| 57 |
'wlw_blogapi_blogger_get_post',
|
| 58 |
array('struct', 'string', 'string', 'string', 'string'),
|
| 59 |
t('Returns information about a specific post.')),
|
| 60 |
array(
|
| 61 |
'blogger.deletePost',
|
| 62 |
'wlw_blogapi_blogger_delete_post',
|
| 63 |
array('boolean', 'string', 'string', 'string', 'string', 'boolean'),
|
| 64 |
t('Deletes a post.')),
|
| 65 |
array(
|
| 66 |
'blogger.getRecentPosts',
|
| 67 |
'wlw_blogapi_blogger_get_recent_posts',
|
| 68 |
array('array', 'string', 'string', 'string', 'string', 'int'),
|
| 69 |
t('Returns a list of the most recent posts in the system.')),
|
| 70 |
array(
|
| 71 |
'metaWeblog.newPost',
|
| 72 |
'wlw_blogapi_metaweblog_new_post',
|
| 73 |
array('string', 'string', 'string', 'string', 'struct', 'boolean'),
|
| 74 |
t('Creates a new post, and optionally publishes it.')),
|
| 75 |
array(
|
| 76 |
'metaWeblog.editPost',
|
| 77 |
'wlw_blogapi_metaweblog_edit_post',
|
| 78 |
array('boolean', 'string', 'string', 'string', 'struct', 'boolean'),
|
| 79 |
t('Updates information about an existing post.')),
|
| 80 |
array(
|
| 81 |
'metaWeblog.getPost',
|
| 82 |
'wlw_blogapi_metaweblog_get_post',
|
| 83 |
array('struct', 'string', 'string', 'string'),
|
| 84 |
t('Returns information about a specific post.')),
|
| 85 |
array(
|
| 86 |
'metaWeblog.newMediaObject',
|
| 87 |
'wlw_blogapi_metaweblog_new_media_object',
|
| 88 |
array('string', 'string', 'string', 'string', 'struct'),
|
| 89 |
t('Uploads a file to your webserver.')),
|
| 90 |
array(
|
| 91 |
'metaWeblog.getCategories',
|
| 92 |
'wlw_blogapi_metaweblog_get_category_list',
|
| 93 |
array('struct', 'string', 'string', 'string'),
|
| 94 |
t('Returns a list of all categories to which the post is assigned.')),
|
| 95 |
array(
|
| 96 |
'metaWeblog.getRecentPosts',
|
| 97 |
'wlw_blogapi_metaweblog_get_recent_posts',
|
| 98 |
array('array', 'string', 'string', 'string', 'int'),
|
| 99 |
t('Returns a list of the most recent posts in the system.')),
|
| 100 |
array(
|
| 101 |
'mt.getRecentPostTitles',
|
| 102 |
'wlw_blogapi_mt_get_recent_post_titles',
|
| 103 |
array('array', 'string', 'string', 'string', 'int'),
|
| 104 |
t('Returns a bandwidth-friendly list of the most recent posts in the system.')),
|
| 105 |
array(
|
| 106 |
'mt.getCategoryList',
|
| 107 |
'wlw_blogapi_mt_get_category_list',
|
| 108 |
array('array', 'string', 'string', 'string'),
|
| 109 |
t('Returns a list of all categories defined in the weblog.')),
|
| 110 |
array(
|
| 111 |
'mt.getPostCategories',
|
| 112 |
'wlw_blogapi_mt_get_post_categories',
|
| 113 |
array('array', 'string', 'string', 'string'),
|
| 114 |
t('Returns a list of all categories to which the post is assigned.')),
|
| 115 |
array(
|
| 116 |
'mt.setPostCategories',
|
| 117 |
'wlw_blogapi_mt_set_post_categories',
|
| 118 |
array('boolean', 'string', 'string', 'string', 'array'),
|
| 119 |
t('Sets the categories for a post.')),
|
| 120 |
array(
|
| 121 |
'mt.supportedMethods',
|
| 122 |
'xmlrpc_server_list_methods',
|
| 123 |
array('array'),
|
| 124 |
t('Retrieve information about the XML-RPC methods supported by the server.')),
|
| 125 |
array(
|
| 126 |
'mt.supportedTextFilters',
|
| 127 |
'wlw_blogapi_mt_supported_text_filters',
|
| 128 |
array('array'),
|
| 129 |
t('Retrieve information about the text formatting plugins supported by the server.')),
|
| 130 |
array(
|
| 131 |
'mt.publishPost',
|
| 132 |
'wlw_blogapi_mt_publish_post',
|
| 133 |
array('boolean', 'string', 'string', 'string'),
|
| 134 |
t('Publish (rebuild) all of the static files related to an entry from your weblog. Equivalent to saving an entry in the system (but without the ping).')));
|
| 135 |
}
|
| 136 |
|
| 137 |
/**
|
| 138 |
* Blogging API callback. Finds the URL of a user's blog.
|
| 139 |
*/
|
| 140 |
|
| 141 |
function wlw_blogapi_blogger_get_users_blogs($appid, $username, $password) {
|
| 142 |
|
| 143 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 144 |
if ($user->uid) {
|
| 145 |
$types = _wlw_blogapi_get_node_types();
|
| 146 |
$structs = array();
|
| 147 |
foreach ($types as $type) {
|
| 148 |
if (strcmp($type, 'blog') == 0) {
|
| 149 |
$url = 'blog/'. $user->uid;
|
| 150 |
$blogName = $user->name .': '. $type;
|
| 151 |
}
|
| 152 |
else {
|
| 153 |
$url = 'node';
|
| 154 |
$blogName = $user->name .': '. $type;
|
| 155 |
}
|
| 156 |
$structs[] = array('url' => url($url, array('absolute' => TRUE)), 'blogid' => $type, 'blogName' => $blogName);
|
| 157 |
}
|
| 158 |
return $structs;
|
| 159 |
}
|
| 160 |
else {
|
| 161 |
return wlw_blogapi_error($user);
|
| 162 |
}
|
| 163 |
}
|
| 164 |
|
| 165 |
/**
|
| 166 |
* Blogging API callback. Returns profile information about a user.
|
| 167 |
*/
|
| 168 |
function wlw_blogapi_blogger_get_user_info($appkey, $username, $password) {
|
| 169 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 170 |
|
| 171 |
if ($user->uid) {
|
| 172 |
$name = explode(' ', $user->realname ? $user->realname : $user->name, 2);
|
| 173 |
return array(
|
| 174 |
'userid' => $user->uid,
|
| 175 |
'lastname' => $name[1],
|
| 176 |
'firstname' => $name[0],
|
| 177 |
'nickname' => $user->name,
|
| 178 |
'email' => $user->mail,
|
| 179 |
'url' => url('blog/'. $user->uid, array('absolute', TRUE)));
|
| 180 |
}
|
| 181 |
else {
|
| 182 |
return wlw_blogapi_error($user);
|
| 183 |
}
|
| 184 |
}
|
| 185 |
|
| 186 |
/**
|
| 187 |
* Blogging API callback. Inserts a new blog post as a node.
|
| 188 |
*/
|
| 189 |
function wlw_blogapi_blogger_new_post($appkey, $blogid, $username, $password, $content, $publish) {
|
| 190 |
$args = func_get_args();
|
| 191 |
// since some modules assume that the user is logged in in their hook_nodeapi()
|
| 192 |
// wlw_blogapi has to set the global variable
|
| 193 |
global $user;
|
| 194 |
if (!$user->uid) {
|
| 195 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 196 |
}
|
| 197 |
if (!$user->uid) {
|
| 198 |
return wlw_blogapi_error($user);
|
| 199 |
}
|
| 200 |
|
| 201 |
$edit = array();
|
| 202 |
$edit['type'] = _wlw_blogapi_blogid($blogid);
|
| 203 |
// get the node type defaults
|
| 204 |
$node_type_default = variable_get('node_options_'. $edit['type'], array('status', 'promote'));
|
| 205 |
$edit['uid'] = $user->uid;
|
| 206 |
$edit['name'] = $user->name;
|
| 207 |
$edit['promote'] = in_array('promote', $node_type_default);
|
| 208 |
$edit['comment'] = variable_get('comment_'. $edit['type'], 2);
|
| 209 |
$edit['revision'] = in_array('revision', $node_type_default);
|
| 210 |
$edit['format'] = FILTER_FORMAT_DEFAULT;
|
| 211 |
$edit['status'] = $publish;
|
| 212 |
//watchdog('wlw_blogapi', 'content = <pre>$content</pre>', array('$content' => print_r($content, true)), WATCHDOG_DEBUG);
|
| 213 |
// check for bloggerAPI vs. metaWeblogAPI
|
| 214 |
if (is_array($content)) {
|
| 215 |
$edit['title'] = $content['title'];
|
| 216 |
$edit['body'] = $content['description'];
|
| 217 |
_wlw_blogapi_mt_extra($edit, $content);
|
| 218 |
}
|
| 219 |
else {
|
| 220 |
$edit['title'] = wlw_blogapi_blogger_title($content);
|
| 221 |
$edit['body'] = $content;
|
| 222 |
}
|
| 223 |
|
| 224 |
if (!node_access('create', $edit['type'])) {
|
| 225 |
return wlw_blogapi_error(t('You do not have permission to create the type of post you wanted to create.'));
|
| 226 |
}
|
| 227 |
|
| 228 |
if (user_access('administer nodes') && !isset($edit['date'])) {
|
| 229 |
$edit['date'] = format_date(time(), 'custom', 'Y-m-d H:i:s O');
|
| 230 |
}
|
| 231 |
$edit['body'] = _wlw_blogapi_filter_extra_code($edit['body']);
|
| 232 |
$edit['title'] = _wlw_blogapi_filter_extra_code($edit['title']);
|
| 233 |
node_invoke_nodeapi($edit, 'blogapi new');
|
| 234 |
|
| 235 |
node_validate($edit);
|
| 236 |
if ($errors = form_get_errors()) {
|
| 237 |
return wlw_blogapi_error(implode("\n", $errors));
|
| 238 |
}
|
| 239 |
|
| 240 |
$node = node_submit($edit);
|
| 241 |
node_save($node);
|
| 242 |
if ($node->nid) {
|
| 243 |
watchdog('content', '@type: added %title using WLW Blog API.', array('@type' => t($node->type), '%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
|
| 244 |
// blogger.newPost returns a string so we cast the nid to a string by putting it in double quotes:
|
| 245 |
return "$node->nid";
|
| 246 |
}
|
| 247 |
|
| 248 |
return wlw_blogapi_error(t('Error storing post.'));
|
| 249 |
}
|
| 250 |
|
| 251 |
/**
|
| 252 |
* Blogging API callback. Modifies the specified blog node.
|
| 253 |
*/
|
| 254 |
function wlw_blogapi_blogger_edit_post($appkey, $postid, $username, $password, $content, $publish) {
|
| 255 |
// since some modules assume that the user is logged in in their hook_nodeapi()
|
| 256 |
// wlw_blogapi has to set the global variable
|
| 257 |
global $user;
|
| 258 |
if (!$user->uid) {
|
| 259 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 260 |
}
|
| 261 |
if (!$user->uid) {
|
| 262 |
return wlw_blogapi_error($user);
|
| 263 |
}
|
| 264 |
|
| 265 |
$node = node_load($postid);
|
| 266 |
if (!$node) {
|
| 267 |
return wlw_blogapi_error(t('n/a'));
|
| 268 |
}
|
| 269 |
// Let the teaser be re-generated.
|
| 270 |
unset($node->teaser);
|
| 271 |
|
| 272 |
if (!node_access('update', $node)) {
|
| 273 |
return wlw_blogapi_error(t('You do not have permission to update this post.'));
|
| 274 |
}
|
| 275 |
|
| 276 |
$node->status = $publish;
|
| 277 |
|
| 278 |
// check for bloggerAPI vs. metaWeblogAPI
|
| 279 |
if (is_array($content)) {
|
| 280 |
$node->title = $content['title'];
|
| 281 |
$node->body = $content['description'];
|
| 282 |
_wlw_blogapi_mt_extra($node, $content);
|
| 283 |
}
|
| 284 |
else {
|
| 285 |
$node->title = blogapi_blogger_title($content);
|
| 286 |
$node->body = $content;
|
| 287 |
}
|
| 288 |
|
| 289 |
node_invoke_nodeapi($node, 'blogapi edit');
|
| 290 |
|
| 291 |
node_validate($node);
|
| 292 |
if ($errors = form_get_errors()) {
|
| 293 |
return wlw_blogapi_error(implode("\n", $errors));
|
| 294 |
}
|
| 295 |
|
| 296 |
if (user_access('administer nodes') && !isset($edit['date'])) {
|
| 297 |
$node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
|
| 298 |
}
|
| 299 |
$node->body = _wlw_blogapi_filter_extra_code($node->body);
|
| 300 |
$node->title = _wlw_blogapi_filter_extra_code($node->title);
|
| 301 |
$node = node_submit($node);
|
| 302 |
node_save($node);
|
| 303 |
if ($node->nid) {
|
| 304 |
watchdog('content', '@type: updated %title using WLW Blog API.', array('@type' => t($node->type), '%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), "node/$node->nid"));
|
| 305 |
return TRUE;
|
| 306 |
}
|
| 307 |
|
| 308 |
return wlw_blogapi_error(t('Error storing post.'));
|
| 309 |
}
|
| 310 |
|
| 311 |
/**
|
| 312 |
* Blogging API callback. Returns a specified blog node.
|
| 313 |
*/
|
| 314 |
function wlw_blogapi_blogger_get_post($appkey, $postid, $username, $password) {
|
| 315 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 316 |
if (!$user->uid) {
|
| 317 |
return wlw_blogapi_error($user);
|
| 318 |
}
|
| 319 |
|
| 320 |
$node = node_load($postid);
|
| 321 |
|
| 322 |
return _wlw_blogapi_get_post($node, TRUE);
|
| 323 |
}
|
| 324 |
|
| 325 |
/**
|
| 326 |
* Blogging API callback. Removes the specified blog node.
|
| 327 |
*/
|
| 328 |
function wlw_blogapi_blogger_delete_post($appkey, $postid, $username, $password, $publish) {
|
| 329 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 330 |
if (!$user->uid) {
|
| 331 |
return wlw_blogapi_error($user);
|
| 332 |
}
|
| 333 |
|
| 334 |
node_delete($postid);
|
| 335 |
return TRUE;
|
| 336 |
}
|
| 337 |
|
| 338 |
/**
|
| 339 |
* Blogging API callback. Returns the latest few postings in a user's blog. $bodies TRUE
|
| 340 |
* <a href="http://movabletype.org/docs/mtmanual_programmatic.html#item_mt%2EgetRecentPostTitles">
|
| 341 |
* returns a bandwidth-friendly list</a>.
|
| 342 |
*/
|
| 343 |
function wlw_blogapi_blogger_get_recent_posts($appkey, $blogid, $username, $password, $number_of_posts, $bodies = TRUE) {
|
| 344 |
// Remove unused appkey (from bloggerAPI).
|
| 345 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 346 |
if (!$user->uid) {
|
| 347 |
return wlw_blogapi_error($user);
|
| 348 |
}
|
| 349 |
|
| 350 |
$type = _wlw_blogapi_blogid($blogid);
|
| 351 |
if ($bodies) {
|
| 352 |
$result = db_query_range("SELECT n.nid, n.title, r.body, r.format, n.comment, n.created, u.name FROM {node} n, {node_revisions} r, {users} u WHERE n.uid = u.uid AND n.vid = r.vid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $number_of_posts);
|
| 353 |
}
|
| 354 |
else {
|
| 355 |
$result = db_query_range("SELECT n.nid, n.title, n.created, u.name FROM {node} n, {users} u WHERE n.uid = u.uid AND n.type = '%s' AND n.uid = %d ORDER BY n.created DESC", $type, $user->uid, 0, $number_of_posts);
|
| 356 |
}
|
| 357 |
$blogs = array();
|
| 358 |
while ($blog = db_fetch_object($result)) {
|
| 359 |
$blogs[] = _wlw_blogapi_get_post($blog, $bodies);
|
| 360 |
}
|
| 361 |
return $blogs;
|
| 362 |
}
|
| 363 |
|
| 364 |
function wlw_blogapi_metaweblog_new_post($blogid, $username, $password, $content, $publish) {
|
| 365 |
$args = func_get_args();
|
| 366 |
return wlw_blogapi_blogger_new_post('0123456789ABCDEF', $blogid, $username, $password, $content, $publish);
|
| 367 |
}
|
| 368 |
|
| 369 |
function wlw_blogapi_metaweblog_edit_post($postid, $username, $password, $content, $publish) {
|
| 370 |
return wlw_blogapi_blogger_edit_post('0123456789ABCDEF', $postid, $username, $password, $content, $publish);
|
| 371 |
}
|
| 372 |
|
| 373 |
function wlw_blogapi_metaweblog_get_post($postid, $username, $password) {
|
| 374 |
return wlw_blogapi_blogger_get_post('01234567890ABCDEF', $postid, $username, $password);
|
| 375 |
}
|
| 376 |
|
| 377 |
/**
|
| 378 |
* Blogging API callback. Inserts a file into Drupal.
|
| 379 |
*/
|
| 380 |
function wlw_blogapi_metaweblog_new_media_object($blogid, $username, $password, $file) {
|
| 381 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 382 |
if (!$user->uid) {
|
| 383 |
return wlw_blogapi_error($user);
|
| 384 |
}
|
| 385 |
|
| 386 |
$usersize = 0;
|
| 387 |
$uploadsize = 0;
|
| 388 |
|
| 389 |
$roles = array_intersect(user_roles(0, 'administer content with blog api'), $user->roles);
|
| 390 |
|
| 391 |
foreach ($roles as $rid => $name) {
|
| 392 |
$extensions .= ' '. strtolower(variable_get("blogapi_extensions_$rid", variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp')));
|
| 393 |
$usersize= max($usersize, variable_get("blogapi_usersize_$rid", variable_get('blogapi_usersize_default', 1)) * 1024 * 1024);
|
| 394 |
$uploadsize = max($uploadsize, variable_get("blogapi_uploadsize_$rid", variable_get('blogapi_uploadsize_default', 1)) * 1024 * 1024);
|
| 395 |
}
|
| 396 |
|
| 397 |
$filesize = strlen($file['bits']);
|
| 398 |
|
| 399 |
if ($filesize > $uploadsize) {
|
| 400 |
return wlw_blogapi_error(t('It is not possible to upload the file, because it exceeded the maximum filesize of @maxsize.', array('@maxsize' => format_size($uploadsize))));
|
| 401 |
}
|
| 402 |
|
| 403 |
if (_wlw_blogapi_space_used($user->uid) + $filesize > $usersize) {
|
| 404 |
return wlw_blogapi_error(t('The file can not be attached to this post, because the disk quota of @quota has been reached.', array('@quota' => format_size($usersize))));
|
| 405 |
}
|
| 406 |
|
| 407 |
// Only allow files with whitelisted extensions and convert remaining dots to
|
| 408 |
// underscores to prevent attacks via non-terminal executable extensions with
|
| 409 |
// files such as exploit.php.jpg.
|
| 410 |
|
| 411 |
$whitelist = array_unique(explode(' ', trim($extensions)));
|
| 412 |
|
| 413 |
$name = basename($file['name']);
|
| 414 |
|
| 415 |
if ($extension_position = strrpos($name, '.')) {
|
| 416 |
$filename = drupal_substr($name, 0, $extension_position);
|
| 417 |
$final_extension = drupal_substr($name, $extension_position + 1);
|
| 418 |
|
| 419 |
if (!in_array(strtolower($final_extension), $whitelist)) {
|
| 420 |
return wlw_blogapi_error(t('It is not possible to upload the file, because it is only possible to upload files with the following extensions: @extensions', array('@extensions' => implode(' ', $whitelist))));
|
| 421 |
}
|
| 422 |
|
| 423 |
$filename = str_replace('.', '_', $filename);
|
| 424 |
$filename .= '.'. $final_extension;
|
| 425 |
}
|
| 426 |
|
| 427 |
$data = $file['bits'];
|
| 428 |
|
| 429 |
if (!$data) {
|
| 430 |
return wlw_blogapi_error(t('No file sent.'));
|
| 431 |
}
|
| 432 |
|
| 433 |
if (!$file = file_save_data($data, $filename)) {
|
| 434 |
return wlw_blogapi_error(t('Error storing file.'));
|
| 435 |
}
|
| 436 |
|
| 437 |
db_query("INSERT INTO {blogapi_files} (uid, filepath, filesize) VALUES (%d, '%s', %d)", $user->uid, $file, $filesize);
|
| 438 |
|
| 439 |
// Return the successful result.
|
| 440 |
return array('url' => file_create_url($file), 'struct');
|
| 441 |
}
|
| 442 |
|
| 443 |
/**
|
| 444 |
* Blogging API callback. Returns a list of the taxonomy terms that can be
|
| 445 |
* associated with a blog node.
|
| 446 |
*/
|
| 447 |
function wlw_blogapi_metaweblog_get_category_list($blogid, $username, $password) {
|
| 448 |
$type = _wlw_blogapi_blogid($blogid);
|
| 449 |
$vocabularies = module_invoke('taxonomy', 'get_vocabularies', $type, 'vid');
|
| 450 |
$categories = array();
|
| 451 |
if ($vocabularies) {
|
| 452 |
foreach ($vocabularies as $vocabulary) {
|
| 453 |
$terms = module_invoke('taxonomy', 'get_tree', $vocabulary->vid, 0, -1);
|
| 454 |
foreach ($terms as $term) {
|
| 455 |
$term_name = $term->name;
|
| 456 |
foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
|
| 457 |
$term_name = $parent->name .'/'. $term_name;
|
| 458 |
}
|
| 459 |
$categories[] = array('categoryName' => $term_name, 'categoryId' => $term->tid);
|
| 460 |
}
|
| 461 |
}
|
| 462 |
}
|
| 463 |
return $categories;
|
| 464 |
}
|
| 465 |
|
| 466 |
function wlw_blogapi_metaweblog_get_recent_posts($blogid, $username, $password, $number_of_posts) {
|
| 467 |
return wlw_blogapi_blogger_get_recent_posts('0123456789ABCDEF', $blogid, $username, $password, $number_of_posts, TRUE);
|
| 468 |
}
|
| 469 |
|
| 470 |
// see above
|
| 471 |
function wlw_blogapi_mt_get_recent_post_titles($blogid, $username, $password, $number_of_posts) {
|
| 472 |
return wlw_blogapi_blogger_get_recent_posts('0123456789ABCDEF', $blogid, $username, $password, $number_of_posts, FALSE);
|
| 473 |
}
|
| 474 |
|
| 475 |
/* **** */
|
| 476 |
function wlw_blogapi_mt_get_category_list($blogid, $username, $password) {
|
| 477 |
return wlw_blogapi_metaweblog_get_category_list($blogid, $username, $password);
|
| 478 |
}
|
| 479 |
|
| 480 |
/**
|
| 481 |
* Blogging API callback. Returns a list of the taxonomy terms that are
|
| 482 |
* assigned to a particular node.
|
| 483 |
*/
|
| 484 |
function wlw_blogapi_mt_get_post_categories($postid, $username, $password) {
|
| 485 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 486 |
if (!$user->uid) {
|
| 487 |
return wlw_blogapi_error($user);
|
| 488 |
}
|
| 489 |
|
| 490 |
$terms = module_invoke('taxonomy', 'node_get_terms', $postid, 'tid');
|
| 491 |
$categories = array();
|
| 492 |
foreach ($terms as $term) {
|
| 493 |
$term_name = $term->name;
|
| 494 |
foreach (module_invoke('taxonomy', 'get_parents', $term->tid, 'tid') as $parent) {
|
| 495 |
$term_name = $parent->name .'/'. $term_name;
|
| 496 |
}
|
| 497 |
$categories[] = array('categoryName' => $term_name, 'categoryId' => $term->tid, 'isPrimary' => TRUE);
|
| 498 |
}
|
| 499 |
return $categories;
|
| 500 |
}
|
| 501 |
|
| 502 |
/**
|
| 503 |
* Blogging API callback. Assigns taxonomy terms to a particular node.
|
| 504 |
*/
|
| 505 |
function wlw_blogapi_mt_set_post_categories($postid, $username, $password, $categories) {
|
| 506 |
global $user;
|
| 507 |
if (!$user->uid) {
|
| 508 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 509 |
}
|
| 510 |
if (!$user->uid) {
|
| 511 |
return wlw_blogapi_error($user);
|
| 512 |
}
|
| 513 |
|
| 514 |
$node = node_load($postid);
|
| 515 |
$node->taxonomy = array();
|
| 516 |
foreach ($categories as $category) {
|
| 517 |
$node->taxonomy[] = $category['categoryId'];
|
| 518 |
}
|
| 519 |
node_save($node);
|
| 520 |
return TRUE;
|
| 521 |
}
|
| 522 |
|
| 523 |
/**
|
| 524 |
* Blogging API callback. Sends a list of available input formats.
|
| 525 |
*/
|
| 526 |
function wlw_blogapi_mt_supported_text_filters() {
|
| 527 |
// NOTE: we're only using anonymous' formats because the MT spec
|
| 528 |
// does not allow for per-user formats.
|
| 529 |
$formats = filter_formats();
|
| 530 |
|
| 531 |
$filters = array();
|
| 532 |
foreach ($formats as $format) {
|
| 533 |
$filter['key'] = $format->format;
|
| 534 |
$filter['label'] = $format->name;
|
| 535 |
$filters[] = $filter;
|
| 536 |
}
|
| 537 |
|
| 538 |
return $filters;
|
| 539 |
}
|
| 540 |
|
| 541 |
/**
|
| 542 |
* Blogging API callback. Publishes the given node
|
| 543 |
*/
|
| 544 |
function wlw_blogapi_mt_publish_post($postid, $username, $password) {
|
| 545 |
$user = wlw_blogapi_validate_user($username, $password);
|
| 546 |
if (!$user->uid) {
|
| 547 |
return wlw_blogapi_error($user);
|
| 548 |
}
|
| 549 |
$node = node_load($postid);
|
| 550 |
if (!$node) {
|
| 551 |
return wlw_blogapi_error(t('Invalid post.'));
|
| 552 |
}
|
| 553 |
|
| 554 |
$node->status = 1;
|
| 555 |
if (!node_access('update', $node)) {
|
| 556 |
return wlw_blogapi_error(t('You do not have permission to update this post.'));
|
| 557 |
}
|
| 558 |
|
| 559 |
node_save($node);
|
| 560 |
|
| 561 |
return TRUE;
|
| 562 |
}
|
| 563 |
|
| 564 |
/**
|
| 565 |
* Prepare an error message for returning to the XMLRPC caller.
|
| 566 |
*/
|
| 567 |
function wlw_blogapi_error($message) {
|
| 568 |
static $xmlrpcusererr;
|
| 569 |
if (!is_array($message)) {
|
| 570 |
$message = array($message);
|
| 571 |
}
|
| 572 |
|
| 573 |
$message = implode(' ', $message);
|
| 574 |
|
| 575 |
return xmlrpc_error($xmlrpcusererr + 1, strip_tags($message));
|
| 576 |
}
|
| 577 |
|
| 578 |
/**
|
| 579 |
* Ensure that the given user has permission to edit a blog.
|
| 580 |
*/
|
| 581 |
function wlw_blogapi_validate_user($username, $password) {
|
| 582 |
global $user;
|
| 583 |
|
| 584 |
$user = user_authenticate(array('name' => $username, 'pass' => $password));
|
| 585 |
if ($user->uid) {
|
| 586 |
if (user_access('administer content with blog api', $user)) {
|
| 587 |
return $user;
|
| 588 |
}
|
| 589 |
else {
|
| 590 |
return t("You either tried to edit somebody else's blog or you don't have permission to edit your own blog.");
|
| 591 |
}
|
| 592 |
}
|
| 593 |
else {
|
| 594 |
return t('Wrong username or password.');
|
| 595 |
}
|
| 596 |
}
|
| 597 |
|
| 598 |
/**
|
| 599 |
* For the blogger API, extract the node title from the contents field.
|
| 600 |
*/
|
| 601 |
function wlw_blogapi_blogger_title(&$contents) {
|
| 602 |
if (eregi('<title>([^<]*)</title>', $contents, $title)) {
|
| 603 |
$title = strip_tags($title[0]);
|
| 604 |
$contents = ereg_replace('<title>[^<]*</title>', '', $contents);
|
| 605 |
}
|
| 606 |
else {
|
| 607 |
list($title, $contents) = explode("\n", $contents, 2);
|
| 608 |
}
|
| 609 |
return $title;
|
| 610 |
}
|
| 611 |
|
| 612 |
function wlw_blogapi_admin_settings_form() {
|
| 613 |
$node_types = array_map('check_plain', node_get_types('names'));
|
| 614 |
$defaults = isset($node_types['blog']) ? array('blog' => 1) : array();
|
| 615 |
$form['blogapi_node_types'] = array(
|
| 616 |
'#type' => 'checkboxes',
|
| 617 |
'#title' => t('Blog types'),
|
| 618 |
'#required' => TRUE,
|
| 619 |
'#default_value' => variable_get('blogapi_node_types', $defaults),
|
| 620 |
'#options' => $node_types,
|
| 621 |
'#description' => t('Select the content types for which you wish to enable posting via blogapi. Each type will appear as a different "blog" in the client application (if supported).')
|
| 622 |
);
|
| 623 |
$menus = array('none' => 'None');
|
| 624 |
$menus += menu_get_menus(TRUE);
|
| 625 |
$form['menu_settings'] = array(
|
| 626 |
'#type' => 'fieldset',
|
| 627 |
'#title' => 'Menu Settings',
|
| 628 |
'#description' => 'When a node is added it can be automatically added to a menu. Choose which menu nodes of each type wil be added to.',
|
| 629 |
'#collapsible' => TRUE,
|
| 630 |
'#collapsed' => FALSE,
|
| 631 |
);
|
| 632 |
foreach ($node_types as $key => $value) {
|
| 633 |
$form['menu_settings']['wlw_blogapi_menu_'. $key] = array(
|
| 634 |
'#type' => 'select',
|
| 635 |
'#options' => $menus,
|
| 636 |
'#default_value' => variable_get('wlw_blogapi_menu_'. $key, 'none'),
|
| 637 |
'#title' => $value,
|
| 638 |
);
|
| 639 |
}
|
| 640 |
$form['blogapi_excerpt'] = array(
|
| 641 |
'#type' => 'checkbox',
|
| 642 |
'#title' => t('Use Excerpt'),
|
| 643 |
'#description' => t('Will you use the excerpt field to input your teaser?'),
|
| 644 |
'#default_value' => variable_get('blogapi_excerpt', 0),
|
| 645 |
);
|
| 646 |
|
| 647 |
$blogapi_extensions_default = variable_get('blogapi_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp');
|
| 648 |
$blogapi_uploadsize_default = variable_get('blogapi_uploadsize_default', 1);
|
| 649 |
$blogapi_usersize_default = variable_get('blogapi_usersize_default', 1);
|
| 650 |
|
| 651 |
$form['settings_general'] = array(
|
| 652 |
'#type' => 'fieldset',
|
| 653 |
'#title' => t('File settings'),
|
| 654 |
'#collapsible' => TRUE,
|
| 655 |
);
|
| 656 |
|
| 657 |
$form['settings_general']['blogapi_extensions_default'] = array(
|
| 658 |
'#type' => 'textfield',
|
| 659 |
'#title' => t('Default permitted file extensions'),
|
| 660 |
'#default_value' => $blogapi_extensions_default,
|
| 661 |
'#maxlength' => 255,
|
| 662 |
'#description' => t('Default extensions that users can upload. Separate extensions with a space and do not include the leading dot.'),
|
| 663 |
);
|
| 664 |
|
| 665 |
$form['settings_general']['blogapi_uploadsize_default'] = array(
|
| 666 |
'#type' => 'textfield',
|
| 667 |
'#title' => t('Default maximum file size per upload'),
|
| 668 |
'#default_value' => $blogapi_uploadsize_default,
|
| 669 |
'#size' => 5,
|
| 670 |
'#maxlength' => 5,
|
| 671 |
'#description' => t('The default maximum file size a user can upload.'),
|
| 672 |
'#field_suffix' => t('MB')
|
| 673 |
);
|
| 674 |
|
| 675 |
$form['settings_general']['blogapi_usersize_default'] = array(
|
| 676 |
'#type' => 'textfield',
|
| 677 |
'#title' => t('Default total file size per user'),
|
| 678 |
'#default_value' => $blogapi_usersize_default,
|
| 679 |
'#size' => 5,
|
| 680 |
'#maxlength' => 5,
|
| 681 |
'#description' => t('The default maximum size of all files a user can have on the site.'),
|
| 682 |
'#field_suffix' => t('MB')
|
| 683 |
);
|
| 684 |
|
| 685 |
$form['settings_general']['upload_max_size'] = array('#value' => '<p>'. t('Your PHP settings limit the maximum file size per upload to %size.', array('%size' => format_size(file_upload_max_size()))) .'</p>');
|
| 686 |
|
| 687 |
$roles = user_roles(0, 'administer content with blog api');
|
| 688 |
$form['roles'] = array('#type' => 'value', '#value' => $roles);
|
| 689 |
|
| 690 |
|
| 691 |
|
| 692 |
foreach ($roles as $rid => $role) {
|
| 693 |
$form['settings_role_'. $rid] = array(
|
| 694 |
'#type' => 'fieldset',
|
| 695 |
'#title' => t('Settings for @role', array('@role' => $role)),
|
| 696 |
'#collapsible' => TRUE,
|
| 697 |
'#collapsed' => TRUE,
|
| 698 |
);
|
| 699 |
$form['settings_role_'. $rid]['blogapi_extensions_'. $rid] = array(
|
| 700 |
'#type' => 'textfield',
|
| 701 |
'#title' => t('Permitted file extensions'),
|
| 702 |
'#default_value' => variable_get('blogapi_extensions_'. $rid, $blogapi_extensions_default),
|
| 703 |
'#maxlength' => 255,
|
| 704 |
'#description' => t('Extensions that users in this role can upload. Separate extensions with a space and do not include the leading dot.'),
|
| 705 |
);
|
| 706 |
$form['settings_role_'. $rid]['blogapi_uploadsize_'. $rid] = array(
|
| 707 |
'#type' => 'textfield',
|
| 708 |
'#title' => t('Maximum file size per upload'),
|
| 709 |
'#default_value' => variable_get('blogapi_uploadsize_'. $rid, $blogapi_uploadsize_default),
|
| 710 |
'#size' => 5,
|
| 711 |
'#maxlength' => 5,
|
| 712 |
'#description' => t('The maximum size of a file a user can upload (in megabytes).'),
|
| 713 |
);
|
| 714 |
$form['settings_role_'. $rid]['blogapi_usersize_'. $rid] = array(
|
| 715 |
'#type' => 'textfield',
|
| 716 |
'#title' => t('Total file size per user'),
|
| 717 |
'#default_value' => variable_get('blogapi_usersize_'. $rid, $blogapi_usersize_default),
|
| 718 |
'#size' => 5,
|
| 719 |
'#maxlength' => 5,
|
| 720 |
'#description' => t('The maximum size of all files a user can have on the site (in megabytes).'),
|
| 721 |
);
|
| 722 |
}/**
|
| 723 |
$form['submit'] = array(
|
| 724 |
'#type' => 'submit',
|
| 725 |
'#value' => 'Submit',
|
| 726 |
);
|
| 727 |
$form['submit'] = array(
|
| 728 |
'#type' => 'submit',
|
| 729 |
'#value' => 'Reset',
|
| 730 |
);/**/
|
| 731 |
$form = system_settings_form($form);
|
| 732 |
//$form['#theme'] = 'wlw_blogapi_admin_settings_form';
|
| 733 |
//drupal_set_message('$form = <pre>'. print_r($form, TRUE) .'</pre>');
|
| 734 |
//drupal_rebuild_theme_registry();
|
| 735 |
//$hooks = theme_get_registry();
|
| 736 |
//drupal_set_message('$hooks = <pre>'. print_r($hooks, TRUE) .'</pre>');
|
| 737 |
|
| 738 |
return $form;
|
| 739 |
}
|
| 740 |
function theme_wlw_blogapi_admin_settings_form(&$form, &$form_state) {
|
| 741 |
$args = func_get_args();
|
| 742 |
drupal_set_message('$args = <pre>'. print_r($args, TRUE) .'</pre>');
|
| 743 |
}
|
| 744 |
/**
|
| 745 |
* implementation os hook_init()
|
| 746 |
*/
|
| 747 |
function wlw_blogapi_init() {
|
| 748 |
drupal_add_link(array(
|
| 749 |
'rel' => 'wlwmanifest',
|
| 750 |
'type' => 'application/wlwmanifest+xml',
|
| 751 |
'href' => url('blogapi/wlwmanifest.xml', array('absolute' => TRUE))
|
| 752 |
));
|
| 753 |
drupal_add_link(array(
|
| 754 |
'rel' => 'EditURI',
|
| 755 |
'type' => 'application/rsd+xml',
|
| 756 |
'title' => t('RSD'),
|
| 757 |
'href' => url('blogapi/rsd', array('absolute' => TRUE))
|
| 758 |
));
|
| 759 |
}
|
| 760 |
|
| 761 |
|
| 762 |
function wlw_blogapi_menu() {
|
| 763 |
$items = array();
|
| 764 |
|
| 765 |
$items['blogapi'] = array(
|
| 766 |
'title' => 'RSD',
|
| 767 |
'page callback' => 'wlw_blogapi_blogapi',
|
| 768 |
'access arguments' => array('access content'),
|
| 769 |
'type' => MENU_CALLBACK
|
| 770 |
);
|
| 771 |
$items['admin/settings/wlw_blogapi'] = array(
|
| 772 |
'title' => 'WLW Blog API',
|
| 773 |
'description' => 'Configure which content types blog clients can use, as well as WLW settings.',
|
| 774 |
'page callback' => 'drupal_get_form',
|
| 775 |
'page arguments' => array('wlw_blogapi_admin_settings_form'),
|
| 776 |
'access arguments' => array('administer site configuration'),
|
| 777 |
'type' => MENU_NORMAL_ITEM
|
| 778 |
);
|
| 779 |
$items['blogapi/wlwmanifest.xml'] = array(
|
| 780 |
'title' => 'WLW Manifest',
|
| 781 |
'description' => 'This provides the wlwmanifest.xml file for WLW configuration',
|
| 782 |
'page callback' => '_wlw_blogapi_wlwmanifest',
|
| 783 |
'type' => MENU_CALLBACK,
|
| 784 |
'access callback' => TRUE,
|
| 785 |
);
|
| 786 |
return $items;
|
| 787 |
}
|
| 788 |
|
| 789 |
function wlw_blogapi_blogapi() {
|
| 790 |
switch (arg(1)) {
|
| 791 |
case 'rsd':
|
| 792 |
wlw_blogapi_rsd();
|
| 793 |
break;
|
| 794 |
default:
|
| 795 |
drupal_not_found();
|
| 796 |
break;
|
| 797 |
}
|
| 798 |
}
|
| 799 |
|
| 800 |
function wlw_blogapi_rsd() {
|
| 801 |
global $base_url;
|
| 802 |
|
| 803 |
$xmlrpc = $base_url .'/'.'xmlrpc.php';
|
| 804 |
$base = url('', array('absolute' => TRUE));
|
| 805 |
$blogid = 1; # until we figure out how to handle multiple bloggers
|
| 806 |
|
| 807 |
drupal_set_header('Content-Type: application/rsd+xml; charset=utf-8');
|
| 808 |
print <<<__RSD__
|
| 809 |
<?xml version="1.0"?>
|
| 810 |
<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
|
| 811 |
<service>
|
| 812 |
<engineName>Drupal</engineName>
|
| 813 |
<engineLink>http://drupal.org/</engineLink>
|
| 814 |
<homePageLink>$base</homePageLink>
|
| 815 |
<apis>
|
| 816 |
<api name="MetaWeblog" preferred="false" apiLink="$xmlrpc" blogID="$blogid" />
|
| 817 |
<api name="Blogger" preferred="false" apiLink="$xmlrpc" blogID="$blogid" />
|
| 818 |
<api name="MovableType" preferred="true" apiLink="$xmlrpc" blogID="$blogid" />
|
| 819 |
</apis>
|
| 820 |
</service>
|
| 821 |
</rsd>
|
| 822 |
__RSD__;
|
| 823 |
}
|
| 824 |
|
| 825 |
/**
|
| 826 |
* Handles extra information sent by clients according to MovableType's spec.
|
| 827 |
*/
|
| 828 |
function _wlw_blogapi_mt_extra(&$node, $struct) {
|
| 829 |
//watchdog('wlw_blogapi', 'struct = <pre>@struct</pre>', array('@struct' => print_r($struct, true)), WATCHDOG_DEBUG);
|
| 830 |
|
| 831 |
if (is_array($node)) {
|
| 832 |
$was_array = TRUE;
|
| 833 |
$node = (object)$node;
|
| 834 |
}
|
| 835 |
|
| 836 |
// take the categories from the struct and add them to the first vocabulary
|
| 837 |
// that allows free tagging that is assigned to the node type
|
| 838 |
$vocabs = taxonomy_get_vocabularies($node->type);
|
| 839 |
$vocab_to_use_for_tags = 0;
|
| 840 |
foreach ($vocabs as $vocab) {
|
| 841 |
if ($vocab_to_use_for_tags) {
|
| 842 |
continue;
|
| 843 |
}
|
| 844 |
else if ($vocab->tags) {
|
| 845 |
$vocab_to_use_for_tags = $vocab->vid;
|
| 846 |
}
|
| 847 |
}
|
| 848 |
if ($vocab_to_use_for_tags) {
|
| 849 |
$tags = array();
|
| 850 |
foreach ($struct['categories'] as $tag) {
|
| 851 |
// if there is a heirarchy we will only submit the last branch
|
| 852 |
$tag = explode('/', $tag);
|
| 853 |
$tag = array_reverse($tag);
|
| 854 |
$tag = $tag[0];
|
| 855 |
$tags[$vocab_to_use_for_tags] .= $tag .', ';
|
| 856 |
}
|
| 857 |
}
|
| 858 |
$node->taxonomy = array('tags' => $tags);
|
| 859 |
|
| 860 |
|
| 861 |
// set the nodewords variable, if the nodewords (Meta Tags) module
|
| 862 |
// is installed this will take the keywords submitted and set those
|
| 863 |
// as the meta tags
|
| 864 |
if (isset($struct['mt_keywords'])) {
|
| 865 |
$node->nodewords = array(
|
| 866 |
'description' => '',
|
| 867 |
'keywords' => $struct['mt_keywords'],
|
| 868 |
);
|
| 869 |
}
|
| 870 |
// mt_allow_comments
|
| 871 |
if (array_key_exists('mt_allow_comments', $struct)) {
|
| 872 |
switch ($struct['mt_allow_comments']) {
|
| 873 |
case 0:
|
| 874 |
$node->comment = COMMENT_NODE_DISABLED;
|
| 875 |
break;
|
| 876 |
case 1:
|
| 877 |
$node->comment = COMMENT_NODE_READ_WRITE;
|
| 878 |
break;
|
| 879 |
case 2:
|
| 880 |
$node->comment = COMMENT_NODE_READ_ONLY;
|
| 881 |
break;
|
| 882 |
}
|
| 883 |
}
|
| 884 |
// add the new node to the menu
|
| 885 |
$menu = variable_get('wlw_blogapi_menu_'. $node->type, 'none');
|
| 886 |
if (($menu !== 'none') && (!isset($node->nid))) {
|
| 887 |
//watchdog('wlw_blogapi', 'wlw_blogapi_mt_extra node = <pre>@node</pre>', array('@node' => print_r($node, true)), WATCHDOG_DEBUG);
|
| 888 |
$node->menu = array(
|
| 889 |
'module' => 'menu',
|
| 890 |
'menu_name' => $menu,
|
| 891 |
'link_title' => $struct['title'],
|
| 892 |
);
|
| 893 |
}
|
| 894 |
// do the slug or url_alias
|
| 895 |
if ($struct['wp_slug']) {
|
| 896 |
$node->path = $struct['wp_slug'];
|
| 897 |
}
|
| 898 |
|
| 899 |
// merge the 3 body sections (description, mt_excerpt, mt_text_more) into one body
|
| 900 |
if ($struct['mt_excerpt']) {
|
| 901 |
$node->body = $struct['mt_excerpt'] .'<!--break-->'. $node->body;
|
| 902 |
}
|
| 903 |
if ($struct['mt_text_more']) {
|
| 904 |
$node->body = $node->body .'<!--break-->'. $struct['mt_text_more'];
|
| 905 |
}
|
| 906 |
|
| 907 |
// mt_convert_breaks
|
| 908 |
if ($struct['mt_convert_breaks']) {
|
| 909 |
$node->format = $struct['mt_convert_breaks'];
|
| 910 |
}
|
| 911 |
|
| 912 |
// dateCreated
|
| 913 |
if ($struct['dateCreated']) {
|
| 914 |
//$formatted_date = format_date(mktime($struct['dateCreated']->hour, $struct['dateCreated']->minute, $struct['dateCreated']->second, $struct['dateCreated']->month, $struct['dateCreated']->day, $struct['dateCreated']->year), 'custom', 'Y-m-d H:i:s O');
|
| 915 |
//So WLW claims to give the date in ISO8601 format, they don't quite,
|
| 916 |
// they give the time in UTC but don't declare it, also this function
|
| 917 |
// didn't even worry about the time zone except to format for it.
|
| 918 |
$formatted_date = format_date(strtotime($struct['dateCreated']->iso8601 .'+00:00'), 'custom', 'Y-m-d H:i:s O');
|
| 919 |
//watchdog('wlw_blogapi', 'dateCreated = <pre>$dateCreated</pre><br/>date = $date<br/>formatted_date = $formatted_date', array('$dateCreated' => print_r($struct['dateCreated'], true), '$date' => date('r', strtotime($struct['dateCreated']->iso8601 .'+00:00')),'$formatted_date' => $formatted_date ), WATCHDOG_DEBUG);
|
| 920 |
$node->date = $formatted_date;
|
| 921 |
}
|
| 922 |
// take care of special chars in title
|
| 923 |
//watchdog('wlw_blogapi', 'func: _wlw_blogapi_mt_extra, node = <pre>$node</pre>', array('$node' => print_r($node, true)));
|
| 924 |
$node->title = str_replace('&', '&', $node->title);
|
| 925 |
//watchdog('wlw_blogapi', 'func: _wlw_blogapi_mt_extra 2, node = <pre>$node</pre>', array('$node' => print_r($node, true)));
|
| 926 |
$title = $node->title;
|
| 927 |
//watchdog('wlw_blogapi', 'func: _wlw_blogapi_mt_extra 1, title = $title', array('$title' => print_r($title, true)));
|
| 928 |
$temp = array();
|
| 929 |
$title2 = '';
|
| 930 |
for ($i = 0; $i <= 20; $i++) {
|
| 931 |
$temp[] = $title2[$i];
|
| 932 |
}
|
| 933 |
if ($was_array) {
|
| 934 |
$node = (array)$node;
|
| 935 |
}
|
| 936 |
}
|
| 937 |
|
| 938 |
/**
|
| 939 |
* Some times with WYSIWYG editors you have the problem
|
| 940 |
* where they like to add extra code, usually without your
|
| 941 |
* knowledge, until you go to look at the final result and
|
| 942 |
* you see the result.
|
| 943 |
*
|
| 944 |
* _wlw_blogapi_filter_extra_code() Filter out some extra code that is
|
| 945 |
* usually unwanted. Code that usually adds undesired
|
| 946 |
* whitespace
|
| 947 |
*/
|
| 948 |
function _wlw_blogapi_filter_extra_code($text) {
|
| 949 |
$text = str_replace('<p> </p>', '', $text);
|
| 950 |
$text = str_replace('<p> </p>', '', $text);
|
| 951 |
$text = str_replace('<p></p>', '', $text);
|
| 952 |
//$text = str_Replace('é', '', $text);
|
| 953 |
//$text = str_Replace('é', '', $text);
|
| 954 |
//watchdog('wlw_blogapi', 'func: _wlw_blogapi_filter_extra_code, text = <pre>$text</pre>', array('$text' => print_r($text, true)));
|
| 955 |
return $text;
|
| 956 |
}
|
| 957 |
function wlw_blogapi_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
|
| 958 |
switch ($op) {
|
| 959 |
case 'insert':
|
| 960 |
case 'update':
|
| 961 |
case 'presave':
|
| 962 |
//$text = str_Replace('', 'é', $text);
|
| 963 |
//watchdog('wlw_blogapi', 'func: wlw_blogapi_nodeapi, node = <pre>'. print_r($node, true) .'</pre>');
|
| 964 |
break;
|
| 965 |
}
|
| 966 |
}
|
| 967 |
function _wlw_blogapi_get_post($node, $bodies = TRUE) {
|
| 968 |
$xmlrpcval = array(
|
| 969 |
'userid' => $node->name,
|
| 970 |
'dateCreated' => xmlrpc_date($node->created),
|
| 971 |
'title' => $node->title,
|
| 972 |
'postid' => $node->nid,
|
| 973 |
'link' => url('node/'. $node->nid, array('absolute', TRUE)),
|
| 974 |
'permaLink' => url('node/'. $node->nid, array('absolute', TRUE)),
|
| 975 |
);
|
| 976 |
if ($bodies) {
|
| 977 |
if ($node->comment == 1) {
|
| 978 |
$comment = 2;
|
| 979 |
}
|
| 980 |
else if ($node->comment == 2) {
|
| 981 |
$comment = 1;
|
| 982 |
}
|
| 983 |
$xmlrpcval['content'] = "<title>$node->title</title>$node->body";
|
| 984 |
$xmlrpcval['description'] = $node->body;
|
| 985 |
// Add MT specific fields
|
| 986 |
$xmlrpcval['mt_allow_comments'] = (int) $comment;
|
| 987 |
$xmlrpcval['mt_convert_breaks'] = $node->format;
|
| 988 |
}
|
| 989 |
|
| 990 |
return $xmlrpcval;
|
| 991 |
}
|
| 992 |
|
| 993 |
function _wlw_blogapi_blogid($id) {
|
| 994 |
if (is_numeric($id)) {
|
| 995 |
return 'blog';
|
| 996 |
}
|
| 997 |
else {
|
| 998 |
return $id;
|
| 999 |
}
|
| 1000 |
}
|
| 1001 |
|
| 1002 |
function _wlw_blogapi_get_node_types() {
|
| 1003 |
$available_types = array_keys(array_filter(variable_get('blogapi_node_types', array('blog' => 1))));
|
| 1004 |
$types = array();
|
| 1005 |
foreach (node_get_types() as $type => $name) {
|
| 1006 |
if (node_access('create', $type) && in_array($type, $available_types)) {
|
| 1007 |
$types[] = $type;
|
| 1008 |
}
|
| 1009 |
}
|
| 1010 |
|
| 1011 |
return $types;
|
| 1012 |
}
|
| 1013 |
|
| 1014 |
|
| 1015 |
function _wlw_blogapi_space_used($uid) {
|
| 1016 |
return db_result(db_query('SELECT SUM(filesize) FROM {blogapi_files} f WHERE f.uid = %d', $uid));
|
| 1017 |
}
|
| 1018 |
|
| 1019 |
function _wlw_blogapi_wlwmanifest() {
|
| 1020 |
|
| 1021 |
$slug = (module_exists('path') ? 'Yes' : 'No');
|
| 1022 |
$keywords = (module_exists('nodewords') ? 'Yes' : 'No');
|
| 1023 |
$excerpt = (variable_get('blogapi_excerpt', 0) ? 'Yes' : 'No');
|
| 1024 |
|
| 1025 |
$output = <<<__manifest__
|
| 1026 |
<?xml version="1.0" encoding="utf-8" ?>
|
| 1027 |
<manifest xmlns="http://schemas.microsoft.com/wlw/manifest/weblog">
|
| 1028 |
<options>
|
| 1029 |
<clientType>MovableType</clientType>
|
| 1030 |
<supportsKeywords>$keywords</supportsKeywords>
|
| 1031 |
<supportsTrackbacks>Yes</supportsTrackbacks>
|
| 1032 |
<supportsCategoriesInline>Yes</supportsCategoriesInline>
|
| 1033 |
<supportsMultipleCategories>Yes</supportsMultipleCategories>
|
| 1034 |
<supportsNewCategories>Yes</supportsNewCategories>
|
| 1035 |
<supportsNewCategoriesInline>Yes</supportsNewCategoriesInline>
|
| 1036 |
<supportsSlug>$slug</supportsSlug>
|
| 1037 |
<supportsAutoUpdate>Yes</supportsAutoUpdate>
|
| 1038 |
<requiresHtmlTitles>No</requiresHtmlTitles>
|
| 1039 |
<supportsExcerpt>$excerpt</supportsExcerpt>
|
| 1040 |
</options>
|
| 1041 |
</manifest>
|
| 1042 |
__manifest__;
|
| 1043 |
print $output;
|
| 1044 |
}
|