| 1 |
<?php
|
| 2 |
// $Id: monument_image.module,v 1.14 2007/07/30 01:56:29 grunthus Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Monument image modules, manage extra data for monument survey images.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Implementation of hook_form_alter().
|
| 11 |
* (Parts from nodeapi_example.module)
|
| 12 |
*/
|
| 13 |
function monument_image_form_alter($form_id, &$form) {
|
| 14 |
if (!isset($form['type']) || $form['type']['#value']!='image') {
|
| 15 |
return;
|
| 16 |
}
|
| 17 |
|
| 18 |
//put any extra data in fieldset
|
| 19 |
$form['Monument data'] = array('#type' => 'fieldset', '#title' => t('Extra monument related data'), '#collapsible' => TRUE);
|
| 20 |
$monuments = _monument_ids();
|
| 21 |
if (!($default_mid = check_plain($form['#node']->monument_image_mid))) $default_mid=-8; //nasty hack
|
| 22 |
//above needed to ensure image import doesn't leave this field undefined (-9)
|
| 23 |
$form['Monument data']['monument_image_mid'] = array(
|
| 24 |
'#type' => 'select',
|
| 25 |
'#title' => t('Associated Monument ID'),
|
| 26 |
'#required' => TRUE,
|
| 27 |
'#default_value' => $default_mid,
|
| 28 |
'#options' => $monuments,
|
| 29 |
'#description' => t('ID of parent monument for this image')
|
| 30 |
);
|
| 31 |
$form['Monument data']['monument_image_face_bearing'] = array(
|
| 32 |
'#type' => 'textfield',
|
| 33 |
'#title' => t('Facing Bearing'),
|
| 34 |
'#required' => FALSE,
|
| 35 |
'#default_value' => check_plain($form['#node']->monument_image_face_bearing),
|
| 36 |
'#description' => t('Enter the face_bearing for the image'),
|
| 37 |
);
|
| 38 |
$form['Monument data']['monument_image_taken_date'] = array(
|
| 39 |
'#type' => 'textfield',
|
| 40 |
'#title' => t('Date image taken'),
|
| 41 |
'#required' => FALSE,
|
| 42 |
'#default_value' => check_plain($form['#node']->monument_image_taken_date),
|
| 43 |
'#description' => t('Date image taken dd/mm/yyyy')
|
| 44 |
);
|
| 45 |
$img_locations = _monument_image_img_locations();
|
| 46 |
// TODO: remove the required status from here and do checks in validate section of nodeapi
|
| 47 |
// TODO: this one does need to be filled in if an associated monument is given
|
| 48 |
$form['Monument data']['monument_image_img_location'] = array(
|
| 49 |
'#type' => 'select',
|
| 50 |
'#title' => t('Image Location'),
|
| 51 |
'#required' => FALSE,
|
| 52 |
'#default_value' => check_plain($form['#node']->monument_image_img_location),
|
| 53 |
'#options' => $img_locations,
|
| 54 |
'#description' => t('Location where image is taken from')
|
| 55 |
);
|
| 56 |
} //function monument_image_form_alter
|
| 57 |
|
| 58 |
/**
|
| 59 |
* Implementation of hook_nodeapi().
|
| 60 |
*
|
| 61 |
*/
|
| 62 |
function monument_image_nodeapi(&$node, $op, $teaser, $page) {
|
| 63 |
if ($node->type == 'image') {
|
| 64 |
switch ($op) {
|
| 65 |
// When an image editing form is submitted, we need to validate the input
|
| 66 |
// to make sure the bearing is between 0 and 360. We allow 999 degrees to
|
| 67 |
// code for 'unknown'.
|
| 68 |
case 'validate':
|
| 69 |
//Associated Monument ID validation
|
| 70 |
if ($node->monument_image_mid == "-9") {
|
| 71 |
//if a user add via image upload module, they will not get the chance
|
| 72 |
//to say whether or not the image is a monument image
|
| 73 |
//this results in lots of mid==0 entries in monument_image table.
|
| 74 |
//TODO this renders the -9 option redundant:
|
| 75 |
// -9 was supposed to indicate that monument image status was undetermined
|
| 76 |
// -8 was supposed to indicate that image was not a monument image
|
| 77 |
// >0 was supposed to indicate that image was a monmuent image
|
| 78 |
// TODO - dispose of -9 notion and assume -8 if not >0
|
| 79 |
$node->monument_image_mid = "-8";
|
| 80 |
//form_set_error( 'monument_image_mid',
|
| 81 |
// t('Please choose an associated monument, or if your image is not associated, then choose \'Not associated\''));
|
| 82 |
}
|
| 83 |
|
| 84 |
//All subsequent validation conditional on mid set not eq. -8 (i.e. image is a monument image)
|
| 85 |
if ($node->monument_image_mid != "-8") {
|
| 86 |
//face_bearing validation
|
| 87 |
if (isset($node->monument_image_face_bearing)
|
| 88 |
&& (($node->monument_image_face_bearing >359)
|
| 89 |
&& ($node->monument_image_face_bearing!=999))) {
|
| 90 |
form_set_error(
|
| 91 |
'monument_image_face_bearing',
|
| 92 |
t('The bearing cannot exceed 359 degrees')
|
| 93 |
);
|
| 94 |
}
|
| 95 |
if (isset($node->monument_image_face_bearing)
|
| 96 |
&& ($node->monument_image_face_bearing <0)) {
|
| 97 |
form_set_error(
|
| 98 |
'monument_image_face_bearing',
|
| 99 |
t('The bearing must be 0 degrees or more')
|
| 100 |
);
|
| 101 |
}
|
| 102 |
//img_location validation
|
| 103 |
if ($node->monument_image_img_location == 0) {
|
| 104 |
form_set_error(
|
| 105 |
'monument_image_img_location',
|
| 106 |
t('You need to specify an image location')
|
| 107 |
);
|
| 108 |
}
|
| 109 |
//there can be only one key_img, check that is so if this is a key_img
|
| 110 |
if ($node->monument_image_img_location == 5) {
|
| 111 |
$result = db_query(
|
| 112 |
'SELECT COUNT(*) as COUNT ' .
|
| 113 |
'FROM {monument_image} ' .
|
| 114 |
'WHERE mid = %d AND img_loc = 5', $node->monument_image_mid
|
| 115 |
);
|
| 116 |
$count = db_fetch_object($result);
|
| 117 |
$count = $count->COUNT;
|
| 118 |
if ($count) {
|
| 119 |
form_set_error(
|
| 120 |
'monument_image_img_location',
|
| 121 |
t('A key image already exists for the selected monument. There can be only one.')
|
| 122 |
);
|
| 123 |
}
|
| 124 |
}
|
| 125 |
|
| 126 |
// Date check syntax lifted from drupal website
|
| 127 |
// http://drupal.org/node/71959
|
| 128 |
if (isset($node->monument_image_taken_date)
|
| 129 |
&& (trim($node->monument_image_taken_date != ''))) {
|
| 130 |
// check the date format
|
| 131 |
if (!preg_match( '/^(\d\d)\/(\d\d)\/(\d\d\d\d)$/',
|
| 132 |
$node->monument_image_taken_date, $matches)) {
|
| 133 |
form_set_error(
|
| 134 |
'monument_image_taken_date',
|
| 135 |
t('Date image taken should be in the format dd/mm/yyyy')
|
| 136 |
);
|
| 137 |
} else {
|
| 138 |
//make sure the date provided is a valid date
|
| 139 |
if (!checkdate($matches[2], $matches[1], $matches[3])) {
|
| 140 |
form_set_error(
|
| 141 |
'monument_image_taken_date',
|
| 142 |
t('Please enter a valid date')
|
| 143 |
);
|
| 144 |
}
|
| 145 |
}
|
| 146 |
}
|
| 147 |
}
|
| 148 |
break;
|
| 149 |
|
| 150 |
// Load extra data
|
| 151 |
// Need to re-write the field names, and convert object->array hence
|
| 152 |
// reconstructing the array resulting from the query
|
| 153 |
// TODO - see if some of this can be simplified with sth. like SELECT face_bearing AS monument_image_face_bearing
|
| 154 |
case 'load':
|
| 155 |
$extrafields = db_fetch_object(db_query(
|
| 156 |
'SELECT mid, img_loc, taken_date, face_bearing ' .
|
| 157 |
'FROM {monument_image} WHERE nid = %d', $node->nid
|
| 158 |
));
|
| 159 |
|
| 160 |
//TODO: Now check and see if there are any results. If not then is not a monument image, no extra data
|
| 161 |
if ($extrafields) {
|
| 162 |
return array(
|
| 163 |
'monument_image_face_bearing' => $extrafields->face_bearing,
|
| 164 |
'monument_image_taken_date' => date('d/m/Y',$extrafields->taken_date),
|
| 165 |
'monument_image_img_location' => $extrafields->img_loc,
|
| 166 |
'monument_image_mid' => $extrafields->mid
|
| 167 |
);
|
| 168 |
} else {
|
| 169 |
return array('monument_image_mid' => -8);
|
| 170 |
}
|
| 171 |
break;
|
| 172 |
|
| 173 |
// Create record in monument_image table.
|
| 174 |
case 'insert':
|
| 175 |
//if a mid is set (greater than 0) then we save extra data
|
| 176 |
|
| 177 |
if ($node->monument_image_mid > 0) {
|
| 178 |
//date syntax from http://drupal.org/node/71961
|
| 179 |
preg_match(
|
| 180 |
'/^(\d\d)\/(\d\d)\/(\d\d\d\d)$/',
|
| 181 |
$node->monument_image_taken_date, $m
|
| 182 |
);
|
| 183 |
$ts = mktime(0, 0, 0, $m[2], $m[1], $m[3]);
|
| 184 |
db_query(
|
| 185 |
'INSERT INTO {monument_image} (nid, mid, taken_date, img_loc, face_bearing) ' .
|
| 186 |
'VALUES (%d, %d, %d, %d, %d)',
|
| 187 |
$node->nid,
|
| 188 |
$node->monument_image_mid, $ts,
|
| 189 |
$node->monument_image_img_location,
|
| 190 |
$node->monument_image_face_bearing
|
| 191 |
);
|
| 192 |
}
|
| 193 |
break;
|
| 194 |
|
| 195 |
case 'update':
|
| 196 |
//if a mid is set (not -8 or -9) then we save extra data
|
| 197 |
//if this image existed but was NOT previously associated, then we need to INSERT a monument image row
|
| 198 |
//if this image was already associated with a monument, we UPDATE the existing row
|
| 199 |
if ($node->monument_image_mid >= 0) {
|
| 200 |
//date syntax from http://drupal.org/node/71961
|
| 201 |
preg_match(
|
| 202 |
'/^(\d\d)\/(\d\d)\/(\d\d\d\d)$/',
|
| 203 |
$node->monument_image_taken_date, $m
|
| 204 |
);
|
| 205 |
$ts = mktime(0, 0, 0, $m[2], $m[1], $m[3]);
|
| 206 |
|
| 207 |
//is there a row in monument_image already?
|
| 208 |
$result = db_fetch_object(db_query(
|
| 209 |
'SELECT nid FROM {monument_image} ' .
|
| 210 |
'WHERE nid=%d LIMIT 1', $node->nid
|
| 211 |
));
|
| 212 |
if ($result) { //yes there is. update it
|
| 213 |
db_query(
|
| 214 |
'UPDATE {monument_image} ' .
|
| 215 |
'SET nid=%d, mid=%d, taken_date=%d, ' .
|
| 216 |
'img_loc=%d, face_bearing=%d ' .
|
| 217 |
'WHERE nid=%d',
|
| 218 |
$node->nid,
|
| 219 |
$node->monument_image_mid,
|
| 220 |
$ts,
|
| 221 |
$node->monument_image_img_location,
|
| 222 |
$node->monument_image_face_bearing,
|
| 223 |
$node->nid
|
| 224 |
);
|
| 225 |
} else { //No. This image is just becoming a monument_image
|
| 226 |
db_query(
|
| 227 |
'INSERT INTO {monument_image} (nid, mid, taken_date, img_loc, face_bearing) ' .
|
| 228 |
'VALUES (%d, %d, %d, %d, %d)',
|
| 229 |
$node->nid,
|
| 230 |
$node->monument_image_mid,
|
| 231 |
$ts,
|
| 232 |
$node->monument_image_img_location,
|
| 233 |
$node->monument_image_face_bearing
|
| 234 |
);
|
| 235 |
}
|
| 236 |
}
|
| 237 |
|
| 238 |
//if mid is now -8, then check whether any rows exist in monument_image
|
| 239 |
//if so they shall be deleted
|
| 240 |
if ($node->monument_image_mid == -8 ) {
|
| 241 |
$result = db_query(
|
| 242 |
'DELETE FROM {monument_image} ' .
|
| 243 |
'WHERE nid=%d LIMIT 1', $node->nid
|
| 244 |
);
|
| 245 |
$count = db_affected_rows();
|
| 246 |
drupal_set_message ('Deleted '.$count.' row(s) of related monument_image data.');
|
| 247 |
|
| 248 |
}
|
| 249 |
break;
|
| 250 |
|
| 251 |
case 'delete':
|
| 252 |
//if a mid is set (not -8 or -9) then we delete extra data
|
| 253 |
if ($node->monument_image_mid >= 0) {
|
| 254 |
db_query(
|
| 255 |
'DELETE FROM {monument_image} ' .
|
| 256 |
'WHERE nid=%d', $node->nid
|
| 257 |
);
|
| 258 |
$count = db_affected_rows();
|
| 259 |
drupal_set_message ('Deleted '.$count.' row(s) of related monument_image data.');
|
| 260 |
}
|
| 261 |
break;
|
| 262 |
|
| 263 |
case 'view':
|
| 264 |
//if a mid is set (not -8 or -9) then we save extra data
|
| 265 |
if ($node->monument_image_mid >= 0) {
|
| 266 |
//add face_bearing
|
| 267 |
$node->content['image_face_bearing'] = array(
|
| 268 |
'#value' => theme(
|
| 269 |
'monument_image_face_bearing',
|
| 270 |
$node->monument_image_face_bearing
|
| 271 |
)
|
| 272 |
);
|
| 273 |
|
| 274 |
//add associated monument ID
|
| 275 |
$node->content['image_mid'] = array(
|
| 276 |
'#value' => theme(
|
| 277 |
'monument_image_mid',
|
| 278 |
$node->monument_image_mid
|
| 279 |
)
|
| 280 |
);
|
| 281 |
|
| 282 |
//add taken_date
|
| 283 |
$node->content['image_taken_date'] = array(
|
| 284 |
'#value' => theme(
|
| 285 |
'monument_image_taken_date',
|
| 286 |
$node->monument_image_taken_date
|
| 287 |
)
|
| 288 |
);
|
| 289 |
|
| 290 |
//add img_loc
|
| 291 |
$node->content['image_img_location'] = array(
|
| 292 |
'#value' => theme(
|
| 293 |
'monument_image_img_location',
|
| 294 |
$node->monument_image_img_location
|
| 295 |
)
|
| 296 |
);
|
| 297 |
}
|
| 298 |
break;
|
| 299 |
}
|
| 300 |
}
|
| 301 |
|
| 302 |
if ($node->type=='monument') {
|
| 303 |
switch ($op) {
|
| 304 |
case 'delete':
|
| 305 |
//A monument is being deleted.
|
| 306 |
//Delete the extra data from the monument_image table
|
| 307 |
db_query(
|
| 308 |
"DELETE FROM {monument_image} " .
|
| 309 |
"WHERE mid='%s'", $node->monumentID
|
| 310 |
);
|
| 311 |
$count = db_affected_rows();
|
| 312 |
drupal_set_message ('Deleted '.$count.' row(s) of related monument_image data. The images themselves remain in the database');
|
| 313 |
break;
|
| 314 |
}
|
| 315 |
}
|
| 316 |
} //function image_nodeapi()
|
| 317 |
|
| 318 |
|
| 319 |
/**
|
| 320 |
* Custom theme functions.
|
| 321 |
*
|
| 322 |
* By using these functions to format our additional data, themes can override
|
| 323 |
* this presentation if they wish; for example, they could provide a graphic for
|
| 324 |
* the location instead of text. We also wrap the default presentation in CSS
|
| 325 |
* classes
|
| 326 |
*/
|
| 327 |
function theme_monument_image_face_bearing($bearing) {
|
| 328 |
|
| 329 |
$output = '<div class="monument_image_face_bearing">';
|
| 330 |
$output .= t('BEARING: %bearing', array('%bearing' => $bearing));
|
| 331 |
$output .= '</div>';
|
| 332 |
return $output;
|
| 333 |
}
|
| 334 |
|
| 335 |
function theme_monument_image_mid($mid) {
|
| 336 |
$monuments = _monument_ids();
|
| 337 |
$output = '<div class="monument_image_mid">';
|
| 338 |
$monument = $monuments[$mid];
|
| 339 |
$nid = _mid2nid($mid);
|
| 340 |
$link = l('%monument', "node/$nid", NULL, NULL, NULL, FALSE, FALSE);
|
| 341 |
// $output .= t('Associated Monument: ' .
|
| 342 |
// '<a href=\'/node/@nid\'>%monument</a>',
|
| 343 |
// array('@nid' => $nid, '%monument' => $monument));
|
| 344 |
$output .= t('Associated Monument: '.$link, array('$nid' => $nid, '%monument' => $monument));
|
| 345 |
$output .= '</div>';
|
| 346 |
return $output;
|
| 347 |
}
|
| 348 |
|
| 349 |
function theme_monument_image_taken_date($taken) {
|
| 350 |
$output = '<div class="monument_image_taken_date">';
|
| 351 |
$output .= t('Taken date: %taken', array('%taken' => $taken));
|
| 352 |
$output .= '</div>';
|
| 353 |
return $output;
|
| 354 |
}
|
| 355 |
|
| 356 |
function theme_monument_image_img_location($loc) {
|
| 357 |
$output = '<div class="monument_image_img_location">';
|
| 358 |
$output .= t('Location: %loc', array('%loc' => $loc));
|
| 359 |
$output .= '</div>';
|
| 360 |
return $output;
|
| 361 |
}
|
| 362 |
|
| 363 |
/**
|
| 364 |
* Implementation of hook_help().
|
| 365 |
*/
|
| 366 |
function monument_image_help($section) {
|
| 367 |
switch ($section) {
|
| 368 |
case 'admin/help/monument_image':
|
| 369 |
return t(
|
| 370 |
'This module adds extra data for monument survey images. ' .
|
| 371 |
'Please see the help for the Monument module.'
|
| 372 |
);
|
| 373 |
break;
|
| 374 |
}
|
| 375 |
}
|
| 376 |
/**
|
| 377 |
* Implementation of hook_perm().
|
| 378 |
*/
|
| 379 |
function monument_image_perm() {
|
| 380 |
return array('create monument_image', 'edit monument_image', 'access monument_image', 'edit own monument_image');
|
| 381 |
}
|
| 382 |
|
| 383 |
/**
|
| 384 |
* Implementation of hook_access().
|
| 385 |
*/
|
| 386 |
function monument_image_access($op, $node) {
|
| 387 |
global $user;
|
| 388 |
|
| 389 |
if ($op == 'create') {
|
| 390 |
return user_access('add monument_image');
|
| 391 |
}
|
| 392 |
|
| 393 |
if ($op == 'update' || $op == 'delete') {
|
| 394 |
if (user_access('edit own monument_image') && ($user->uid == $node->uid)) {
|
| 395 |
return TRUE;
|
| 396 |
}
|
| 397 |
}
|
| 398 |
|
| 399 |
if ($op == 'view') {
|
| 400 |
return user_access('access monument_image');
|
| 401 |
}
|
| 402 |
}
|
| 403 |
|
| 404 |
/**
|
| 405 |
* Implementation of hook_delete().
|
| 406 |
*/
|
| 407 |
function monument_image_delete(&$node) {
|
| 408 |
db_query(db_rewrite_sql(
|
| 409 |
'DELETE FROM {monument_image} ' .
|
| 410 |
'WHERE nid=%d', $node->nid
|
| 411 |
));
|
| 412 |
}
|
| 413 |
|
| 414 |
|
| 415 |
/**
|
| 416 |
* Implementation of hook_prepare().
|
| 417 |
*/
|
| 418 |
function monument_image_prepare(&$node) {
|
| 419 |
$node->monument_image_taken_date = date('d/m/Y', $node->monument_image_taken_date);
|
| 420 |
}
|
| 421 |
|
| 422 |
/**
|
| 423 |
* Implementation of hook_node_info().
|
| 424 |
*/
|
| 425 |
function monument_image_node_info() {
|
| 426 |
return array('monument_image' => array( 'name' => t('monument_image'),
|
| 427 |
'module' => ('monument_image'),
|
| 428 |
'description' => t("Extended image data for images of monuments")
|
| 429 |
)
|
| 430 |
);
|
| 431 |
}
|
| 432 |
|
| 433 |
/**
|
| 434 |
* Return an array of possible image locations
|
| 435 |
* @return array of image locations
|
| 436 |
*/
|
| 437 |
function _monument_image_img_locations() {
|
| 438 |
return array (0 => t('Not Set'),
|
| 439 |
t('ring1'),
|
| 440 |
t('ring2'),
|
| 441 |
t('ring3'),
|
| 442 |
t('ad_hoc'),
|
| 443 |
t('key_img'),
|
| 444 |
t('art_img'));
|
| 445 |
}
|
| 446 |
|
| 447 |
/**
|
| 448 |
* Return an array of possible monument IDs from monument table
|
| 449 |
* @return array of image locations
|
| 450 |
*/
|
| 451 |
function _monument_ids(){
|
| 452 |
$b['-9'] = t('Please select one');
|
| 453 |
$b['-8'] = t('Not associated with a monument');
|
| 454 |
$result = db_query('SELECT {monument}.monumentID, title ' .
|
| 455 |
'FROM {node} INNER JOIN {monument} ON {node}.{nid}={monument}.{nid}');
|
| 456 |
while ($monument = db_fetch_object($result)) {
|
| 457 |
$b[$monument->monumentID] = $monument->monumentID . ": " . $monument->title;
|
| 458 |
}
|
| 459 |
return $b;
|
| 460 |
}
|
| 461 |
/**
|
| 462 |
* Convert a monument id mid to a node id nid from monument table
|
| 463 |
*/
|
| 464 |
function _mid2nid($mid){
|
| 465 |
$result = db_query('SELECT nid FROM {monument} WHERE monumentID=%d', $mid);
|
| 466 |
$monument = db_fetch_object($result);
|
| 467 |
return $monument->nid;
|
| 468 |
}
|
| 469 |
|
| 470 |
/**
|
| 471 |
* Convert a monument node id (nid) to a monument ID (mid) from monument table
|
| 472 |
*/
|
| 473 |
function _nid2mid($nid) {
|
| 474 |
$result = db_query(
|
| 475 |
'SELECT monumentID FROM {monument} ' .
|
| 476 |
'WHERE nid=%d LIMIT 1', $nid
|
| 477 |
);
|
| 478 |
$row = db_fetch_object($result);
|
| 479 |
return $row->monumentID;
|
| 480 |
}
|