Textpattern | PHP Cross Reference | Content Management Systems |
Description: Images panel.
1 <?php 2 3 /* 4 * Textpattern Content Management System 5 * http://textpattern.com 6 * 7 * Copyright (C) 2005 Dean Allen 8 * Copyright (C) 2016 The Textpattern Development Team 9 * 10 * This file is part of Textpattern. 11 * 12 * Textpattern is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation, version 2. 15 * 16 * Textpattern is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with Textpattern. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 /** 26 * Images panel. 27 * 28 * @package Admin\Image 29 */ 30 31 use Textpattern\Validator\CategoryConstraint; 32 use Textpattern\Validator\Validator; 33 use Textpattern\Search\Filter; 34 35 if (!defined('txpinterface')) { 36 die('txpinterface is undefined.'); 37 } 38 39 global $extensions; 40 $extensions = get_safe_image_types(); 41 42 include txpath.'/lib/class.thumb.php'; 43 44 if ($event == 'image') { 45 require_privs('image'); 46 47 global $all_image_cats, $all_image_authors; 48 $all_image_cats = getTree('root', 'image'); 49 $all_image_authors = the_privileged('image.edit.own'); 50 51 $available_steps = array( 52 'image_list' => false, 53 'image_edit' => false, 54 'image_insert' => true, 55 'image_replace' => true, 56 'image_save' => true, 57 'thumbnail_insert' => true, 58 'image_change_pageby' => true, 59 'thumbnail_create' => true, 60 'thumbnail_delete' => true, 61 'image_multi_edit' => true, 62 ); 63 64 if ($step && bouncer($step, $available_steps)) { 65 $step(); 66 } else { 67 image_list(); 68 } 69 } 70 71 /** 72 * The main panel listing all images. 73 * 74 * @param string|array $message The activity message 75 */ 76 77 function image_list($message = '') 78 { 79 global $txpcfg, $extensions, $img_dir, $file_max_upload_size, $image_list_pageby, $txp_user, $event; 80 81 pagetop(gTxt('tab_image'), $message); 82 83 extract($txpcfg); 84 extract(gpsa(array( 85 'page', 86 'sort', 87 'dir', 88 'crit', 89 'search_method', 90 ))); 91 92 if ($sort === '') { 93 $sort = get_pref('image_sort_column', 'id'); 94 } else { 95 if (!in_array($sort, array('name', 'thumbnail', 'category', 'date', 'author'))) { 96 $sort = 'id'; 97 } 98 99 set_pref('image_sort_column', $sort, 'image', 2, '', 0, PREF_PRIVATE); 100 } 101 102 if ($dir === '') { 103 $dir = get_pref('image_sort_dir', 'desc'); 104 } else { 105 $dir = ($dir == 'asc') ? "asc" : "desc"; 106 set_pref('image_sort_dir', $dir, 'image', 2, '', 0, PREF_PRIVATE); 107 } 108 109 switch ($sort) { 110 case 'name': 111 $sort_sql = "txp_image.name $dir"; 112 break; 113 case 'thumbnail': 114 $sort_sql = "txp_image.thumbnail $dir, txp_image.id ASC"; 115 break; 116 case 'category': 117 $sort_sql = "txp_category.title $dir, txp_image.id ASC"; 118 break; 119 case 'date': 120 $sort_sql = "txp_image.date $dir, txp_image.id ASC"; 121 break; 122 case 'author': 123 $sort_sql = "txp_users.RealName $dir, txp_image.id ASC"; 124 break; 125 default: 126 $sort = 'id'; 127 $sort_sql = "txp_image.id $dir"; 128 break; 129 } 130 131 $switch_dir = ($dir == 'desc') ? 'asc' : 'desc'; 132 133 $search = new Filter($event, 134 array( 135 'id' => array( 136 'column' => 'txp_image.id', 137 'label' => gTxt('ID'), 138 'type' => 'integer', 139 ), 140 'name' => array( 141 'column' => 'txp_image.name', 142 'label' => gTxt('name'), 143 ), 144 'alt' => array( 145 'column' => 'txp_image.alt', 146 'label' => gTxt('alt_text'), 147 ), 148 'caption' => array( 149 'column' => 'txp_image.caption', 150 'label' => gTxt('caption'), 151 ), 152 'category' => array( 153 'column' => array('txp_image.category', 'txp_category.title'), 154 'label' => gTxt('image_category'), 155 ), 156 'ext' => array( 157 'column' => 'txp_image.ext', 158 'label' => gTxt('extension'), 159 ), 160 'author' => array( 161 'column' => array('txp_image.author', 'txp_users.RealName'), 162 'label' => gTxt('author'), 163 ), 164 'thumbnail' => array( 165 'column' => array('txp_image.thumbnail'), 166 'label' => gTxt('thumbnail'), 167 'type' => 'boolean', 168 ), 169 ) 170 ); 171 172 $alias_yes = '1, Yes'; 173 $alias_no = '0, No'; 174 $search->setAliases('thumbnail', array($alias_no, $alias_yes)); 175 176 list($criteria, $crit, $search_method) = $search->getFilter(array( 177 'id' => array('can_list' => true), 178 )); 179 180 $search_render_options = array( 181 'placeholder' => 'search_images', 182 ); 183 184 $sql_from = 185 safe_pfx_j('txp_image')." 186 LEFT JOIN ".safe_pfx_j('txp_category')." ON txp_category.name = txp_image.category AND txp_category.type = 'image' 187 LEFT JOIN ".safe_pfx_j('txp_users')." ON txp_users.name = txp_image.author"; 188 189 if ($criteria === 1) { 190 $total = getCount('txp_image', $criteria); 191 } else { 192 $total = getThing("SELECT COUNT(*) FROM $sql_from WHERE $criteria"); 193 } 194 195 echo n.'<div class="txp-layout">'. 196 n.tag( 197 hed(gTxt('tab_image'), 1, array('class' => 'txp-heading')), 198 'div', array('class' => 'txp-layout-4col-alt') 199 ); 200 201 $searchBlock = 202 n.tag( 203 $search->renderForm('image_list', $search_render_options), 204 'div', array( 205 'class' => 'txp-layout-4col-3span', 206 'id' => $event.'_control', 207 ) 208 ); 209 210 $createBlock = array(); 211 212 if (!is_dir(IMPATH) or !is_writeable(IMPATH)) { 213 $createBlock[] = 214 graf( 215 span(null, array('class' => 'ui-icon ui-icon-alert')).' '. 216 gTxt('img_dir_not_writeable', array('{imgdir}' => IMPATH)), 217 array('class' => 'alert-block warning') 218 ); 219 } elseif (has_privs('image.edit.own')) { 220 $createBlock[] = 221 n.tag( 222 n.upload_form('upload_image', 'upload_image', 'image_insert', 'image', '', $file_max_upload_size, '', '', ''), 223 'div', array('class' => 'txp-control-panel') 224 ); 225 } 226 227 $contentBlockStart = n.tag_start('div', array( 228 'class' => 'txp-layout-1col', 229 'id' => $event.'_container', 230 )); 231 232 $createBlock = implode(n, $createBlock); 233 234 if ($total < 1) { 235 if ($criteria != 1) { 236 echo $searchBlock. 237 $contentBlockStart. 238 $createBlock. 239 graf( 240 span(null, array('class' => 'ui-icon ui-icon-info')).' '. 241 gTxt('no_results_found'), 242 array('class' => 'alert-block information') 243 ); 244 } else { 245 echo $contentBlockStart. 246 $createBlock. 247 graf( 248 span(null, array('class' => 'ui-icon ui-icon-info')).' '. 249 gTxt('no_images_recorded'), 250 array('class' => 'alert-block information') 251 ); 252 } 253 254 echo n.tag_end('div'). // End of .txp-layout-1col. 255 n.'</div>'; // End of .txp-layout. 256 257 return; 258 } 259 260 $limit = max($image_list_pageby, 15); 261 262 list($page, $offset, $numPages) = pager($total, $limit, $page); 263 264 echo $searchBlock.$contentBlockStart.$createBlock; 265 266 $rs = safe_query( 267 "SELECT 268 txp_image.id, 269 txp_image.name, 270 txp_image.category, 271 txp_image.ext, 272 txp_image.w, 273 txp_image.h, 274 txp_image.alt, 275 txp_image.caption, 276 UNIX_TIMESTAMP(txp_image.date) AS uDate, 277 txp_image.author, 278 txp_image.thumbnail, 279 txp_image.thumb_w, 280 txp_image.thumb_h, 281 txp_users.RealName AS realname, 282 txp_category.Title AS category_title 283 FROM $sql_from WHERE $criteria ORDER BY $sort_sql LIMIT $offset, $limit" 284 ); 285 286 echo pluggable_ui('image_ui', 'extend_controls', '', $rs); 287 288 if ($rs && numRows($rs)) { 289 $show_authors = !has_single_author('txp_image'); 290 291 echo n.tag( 292 toggle_box('images_detail'), 'div', array('class' => 'txp-list-options')). 293 n.tag_start('form', array( 294 'class' => 'multi_edit_form', 295 'id' => 'images_form', 296 'name' => 'longform', 297 'method' => 'post', 298 'action' => 'index.php', 299 )). 300 n.tag_start('div', array('class' => 'txp-listtables')). 301 n.tag_start('table', array('class' => 'txp-list')). 302 n.tag_start('thead'). 303 tr( 304 hCell( 305 fInput('checkbox', 'select_all', 0, '', '', '', '', '', 'select_all'), 306 '', ' class="txp-list-col-multi-edit" scope="col" title="'.gTxt('toggle_all_selected').'"' 307 ). 308 column_head( 309 'ID', 'id', 'image', true, $switch_dir, $crit, $search_method, 310 (('id' == $sort) ? "$dir " : '').'txp-list-col-id' 311 ). 312 column_head( 313 'name', 'name', 'image', true, $switch_dir, $crit, $search_method, 314 (('name' == $sort) ? "$dir " : '').'txp-list-col-name' 315 ). 316 column_head( 317 'date', 'date', 'image', true, $switch_dir, $crit, $search_method, 318 (('date' == $sort) ? "$dir " : '').'txp-list-col-created date images_detail' 319 ). 320 column_head( 321 'thumbnail', 'thumbnail', 'image', true, $switch_dir, $crit, $search_method, 322 (('thumbnail' == $sort) ? "$dir " : '').'txp-list-col-thumbnail' 323 ). 324 hCell( 325 gTxt('tags'), '', ' class="txp-list-col-tag-build images_detail" scope="col"' 326 ). 327 column_head( 328 'image_category', 'category', 'image', true, $switch_dir, $crit, $search_method, 329 (('category' == $sort) ? "$dir " : '').'txp-list-col-category category' 330 ). 331 ( 332 $show_authors 333 ? column_head('author', 'author', 'image', true, $switch_dir, $crit, $search_method, 334 (('author' == $sort) ? "$dir " : '').'txp-list-col-author name') 335 : '' 336 ) 337 ). 338 n.tag_end('thead'). 339 n.tag_start('tbody'); 340 341 $validator = new Validator(); 342 343 while ($a = nextRow($rs)) { 344 extract($a); 345 346 $edit_url = array( 347 'event' => 'image', 348 'step' => 'image_edit', 349 'id' => $id, 350 'sort' => $sort, 351 'dir' => $dir, 352 'page' => $page, 353 'search_method' => $search_method, 354 'crit' => $crit, 355 ); 356 357 $name = empty($name) ? gTxt('unnamed') : txpspecialchars($name); 358 359 if ($thumbnail) { 360 if ($ext != '.swf') { 361 $thumbnail = '<img class="content-image" src="'.imagesrcurl($id, $ext, true)."?$uDate".'" alt="" '. 362 "title='$id$ext ($w × $h)'". 363 ($thumb_w ? " width='$thumb_w' height='$thumb_h'" : '').' />'; 364 $thumbexists = 1; 365 } else { 366 $thumbnail = ''; 367 $thumbexists = ''; 368 } 369 } else { 370 $thumbnail = gTxt('no'); 371 $thumbexists = ''; 372 } 373 374 if ($ext != '.swf') { 375 $tagName = 'image'; 376 $tag_url = array( 377 'id' => $id, 378 'ext' => $ext, 379 'w' => $w, 380 'h' => $h, 381 'alt' => urlencode($alt), 382 'caption' => urlencode($caption), 383 'step' => 'build', 384 ); 385 386 $tagbuilder = popTag($tagName, 'Textile', array('type' => 'textile') + $tag_url). 387 sp.span('|', array('role' => 'separator')). 388 sp.popTag($tagName, 'Textpattern', array('type' => 'textpattern') + $tag_url). 389 sp.span('|', array('role' => 'separator')). 390 sp.popTag($tagName, 'HTML', array('type' => 'html') + $tag_url); 391 } else { 392 $tagbuilder = sp; 393 } 394 395 $validator->setConstraints(array(new CategoryConstraint($category, array('type' => 'image')))); 396 $vc = $validator->validate() ? '' : ' error'; 397 398 if ($category) { 399 $category = span(txpspecialchars($category_title), array('title' => $category)); 400 } 401 402 $can_edit = has_privs('image.edit') || ($author === $txp_user && has_privs('image.edit.own')); 403 404 echo tr( 405 td( 406 $can_edit ? fInput('checkbox', 'selected[]', $id) : ' ', '', 'txp-list-col-multi-edit' 407 ). 408 hCell( 409 ($can_edit ? href($id, $edit_url, array('title' => gTxt('edit'))) : $id). 410 span( 411 sp.span('|', array('role' => 'separator')). 412 sp.href(gTxt('view'), imagesrcurl($id, $ext)), 413 array('class' => 'txp-option-link images_detail') 414 ), '', array( 415 'class' => 'txp-list-col-id', 416 'scope' => 'row', 417 ) 418 ). 419 td( 420 ($can_edit ? href($name, $edit_url, ' title="'.gTxt('edit').'"') : $name), '', 'txp-list-col-name' 421 ). 422 td( 423 gTime($uDate), '', 'txp-list-col-created date images_detail' 424 ). 425 td( 426 pluggable_ui('image_ui', 'thumbnail', ($can_edit ? href($thumbnail, $edit_url) : $thumbnail), $a), '', 'txp-list-col-thumbnail'.($thumbexists ? ' has-thumbnail' : '') 427 ). 428 td( 429 $tagbuilder, '', 'txp-list-col-tag-build images_detail' 430 ). 431 td( 432 $category, '', 'txp-list-col-category category'.$vc 433 ). 434 ( 435 $show_authors 436 ? td(span(txpspecialchars($realname), array('title' => $author)), '', 'txp-list-col-author name') 437 : '' 438 ) 439 ); 440 } 441 442 echo 443 n.tag_end('tbody'). 444 n.tag_end('table'). 445 n.tag_end('div'). // End of .txp-listtables. 446 image_multiedit_form($page, $sort, $dir, $crit, $search_method). 447 tInput(). 448 n.tag_end('form'). 449 n.tag_start('div', array( 450 'class' => 'txp-navigation', 451 'id' => $event.'_navigation', 452 )). 453 pageby_form('image', $image_list_pageby). 454 nav_form('image', $page, $numPages, $sort, $dir, $crit, $search_method, $total, $limit). 455 n.tag_end('div'); 456 } 457 458 echo n.tag_end('div'). // End of .txp-layout-1col. 459 n.tag( 460 null, 461 'div', array( 462 'class' => 'txp-tagbuilder-content', 463 'id' => 'tagbuild_links', 464 'aria-label' => gTxt('tagbuilder'), 465 'title' => gTxt('tagbuilder'), 466 )). 467 n.'</div>'; // End of .txp-layout. 468 } 469 470 // ------------------------------------------------------------- 471 472 function image_multiedit_form($page, $sort, $dir, $crit, $search_method) 473 { 474 global $all_image_cats, $all_image_authors; 475 476 $categories = $all_image_cats ? treeSelectInput('category', $all_image_cats, '') : ''; 477 $authors = $all_image_authors ? selectInput('author', $all_image_authors, '', true) : ''; 478 479 $methods = array( 480 'changecategory' => array('label' => gTxt('changecategory'), 'html' => $categories), 481 'changeauthor' => array('label' => gTxt('changeauthor'), 'html' => $authors), 482 'delete' => gTxt('delete'), 483 ); 484 485 if (!$categories) { 486 unset($methods['changecategory']); 487 } 488 489 if (has_single_author('txp_image') || !has_privs('image.edit')) { 490 unset($methods['changeauthor']); 491 } 492 493 if (!has_privs('image.delete.own') && !has_privs('image.delete')) { 494 unset($methods['delete']); 495 } 496 497 return multi_edit($methods, 'image', 'image_multi_edit', $page, $sort, $dir, $crit, $search_method); 498 } 499 500 // ------------------------------------------------------------- 501 502 function image_multi_edit() 503 { 504 global $txp_user, $all_image_cats, $all_image_authors; 505 506 // Empty entry to permit clearing the category. 507 $categories = array(''); 508 509 foreach ($all_image_cats as $row) { 510 $categories[] = $row['name']; 511 } 512 513 $selected = ps('selected'); 514 515 if (!$selected or !is_array($selected)) { 516 return image_list(); 517 } 518 519 $selected = array_map('assert_int', $selected); 520 $method = ps('edit_method'); 521 $changed = array(); 522 $key = ''; 523 524 switch ($method) { 525 case 'delete': 526 return image_delete($selected); 527 break; 528 case 'changecategory': 529 $val = ps('category'); 530 if (in_array($val, $categories)) { 531 $key = 'category'; 532 } 533 break; 534 case 'changeauthor': 535 $val = ps('author'); 536 if (has_privs('image.edit') && in_array($val, $all_image_authors)) { 537 $key = 'author'; 538 } 539 break; 540 default: 541 $key = ''; 542 $val = ''; 543 break; 544 } 545 546 if (!has_privs('image.edit')) { 547 if (has_privs('image.edit.own')) { 548 $selected = safe_column("id", 'txp_image', "id IN (".join(',', $selected).") AND author = '".doSlash($txp_user)."'"); 549 } else { 550 $selected = array(); 551 } 552 } 553 554 if ($selected and $key) { 555 foreach ($selected as $id) { 556 if (safe_update('txp_image', "$key = '".doSlash($val)."'", "id = $id")) { 557 $changed[] = $id; 558 } 559 } 560 } 561 562 if ($changed) { 563 update_lastmod('image_updated', $changed); 564 565 return image_list(gTxt('image_updated', array('{name}' => join(', ', $changed)))); 566 } 567 568 return image_list(); 569 } 570 571 /** 572 * Renders and outputs the image editor panel. 573 * 574 * @param string|array $message The activity message 575 * @param int $id The image ID 576 */ 577 578 function image_edit($message = '', $id = '') 579 { 580 global $prefs, $file_max_upload_size, $txp_user, $event, $all_image_cats; 581 582 if (!$id) { 583 $id = gps('id'); 584 } 585 586 $id = assert_int($id); 587 $rs = safe_row("*, UNIX_TIMESTAMP(date) AS uDate", 'txp_image', "id = $id"); 588 589 if ($rs) { 590 extract($rs); 591 592 if (!has_privs('image.edit') && !($author === $txp_user && has_privs('image.edit.own'))) { 593 image_list(gTxt('restricted_area')); 594 595 return; 596 } 597 598 pagetop(gTxt('edit_image'), $message); 599 600 extract(gpsa(array( 601 'page', 602 'sort', 603 'dir', 604 'crit', 605 'search_method' 606 ))); 607 608 if ($ext != '.swf') { 609 $aspect = ($h == $w) ? ' square' : (($h > $w) ? ' portrait' : ' landscape'); 610 $img_info = $id.$ext.' ('.$w.' × '.$h.')'; 611 $img = '<div class="fullsize-image"><img class="content-image" src="'.imagesrcurl($id, $ext)."?$uDate".'" alt="'.$img_info.'" title="'.$img_info.'" /></div>'; 612 } else { 613 $img = $aspect = ''; 614 } 615 616 if ($thumbnail and ($ext != '.swf')) { 617 $thumb_info = $id.'t'.$ext.' ('.$thumb_w.' × '.$thumb_h.')'; 618 $thumb = '<img class="content-image" src="'.imagesrcurl($id, $ext, true)."?$uDate".'" alt="'.$thumb_info.'" title="'.$thumb_info.'" />'; 619 } else { 620 $thumb = ''; 621 622 if ($thumb_w == 0) { 623 $thumb_w = get_pref('thumb_w', 0); 624 } 625 626 if ($thumb_h == 0) { 627 $thumb_h = get_pref('thumb_h', 0); 628 } 629 } 630 631 $imageBlock = array(); 632 $thumbBlock = array(); 633 634 $imageBlock[] = pluggable_ui( 635 'image_ui', 636 'image_edit', 637 upload_form('replace_image', 'replace_image_form', 'image_replace', 'image', $id, $file_max_upload_size, 'image-upload', ' image-replace'), 638 $rs 639 ); 640 641 $imageBlock[] = pluggable_ui( 642 'image_ui', 643 'fullsize_image', 644 $img, 645 $rs 646 ); 647 648 $thumbBlock[] = hed(gTxt('create_thumbnail').popHelp('create_thumbnail'), 3); 649 650 $thumbBlock[] = pluggable_ui( 651 'image_ui', 652 'thumbnail_edit', 653 upload_form('upload_thumbnail', 'upload_thumbnail', 'thumbnail_insert', 'image', $id, $file_max_upload_size, 'thumbnail-upload', ' thumbnail-upload'), 654 $rs 655 ); 656 657 $thumbBlock[] = (check_gd($ext)) 658 ? pluggable_ui( 659 'image_ui', 660 'thumbnail_create', 661 form( 662 graf( 663 n.'<label for="width">'.gTxt('thumb_width').'</label>'. 664 fInput('text', 'width', @$thumb_w, 'input-xsmall', '', '', INPUT_XSMALL, '', 'width'). 665 n.'<label for="height">'.gTxt('thumb_height').'</label>'. 666 fInput('text', 'height', @$thumb_h, 'input-xsmall', '', '', INPUT_XSMALL, '', 'height'). 667 n.'<label for="crop">'.gTxt('keep_square_pixels').'</label>'. 668 checkbox('crop', 1, @$prefs['thumb_crop'], '', 'crop'). 669 fInput('submit', '', gTxt('create')), ' class="edit-alter-thumbnail"'). 670 hInput('id', $id). 671 eInput('image'). 672 sInput('thumbnail_create'). 673 hInput('sort', $sort). 674 hInput('dir', $dir). 675 hInput('page', $page). 676 hInput('search_method', $search_method). 677 hInput('crit', $crit), '', '', 'post', '', '', 'thumbnail_alter_form'), 678 $rs 679 ) 680 : ''; 681 682 $thumbBlock[] = pluggable_ui( 683 'image_ui', 684 'thumbnail_image', 685 '<div class="thumbnail-image">'. 686 (($thumbnail) 687 ? $thumb.n.dLink('image', 'thumbnail_delete', 'id', $id, '', '', '', '', array($page, $sort, $dir, $crit, $search_method)) 688 : ''). 689 '</div>', 690 $rs 691 ); 692 693 echo n.'<div class="txp-layout">'. 694 n.tag( 695 hed(gTxt('edit_image'), 1, array('class' => 'txp-heading')), 696 'div', array('class' => 'txp-layout-1col') 697 ). 698 n.tag( 699 form( 700 wrapGroup( 701 'image-details', 702 inputLabel( 703 'id', 704 $id, 705 'id', '', array('class' => 'txp-form-field edit-image-id') 706 ). 707 inputLabel( 708 'image_name', 709 fInput('text', 'name', $name, '', '', '', INPUT_REGULAR, '', 'image_name'), 710 'image_name', '', array('class' => 'txp-form-field edit-image-name') 711 ). 712 inputLabel( 713 'image_category', 714 event_category_popup('image', $category, 'image_category'). 715 n.eLink('category', 'list', '', '', gTxt('edit'), '', '', '', 'txp-option-link'), 716 'image_category', '', array('class' => 'txp-form-field edit-image-category') 717 ). 718 inputLabel( 719 'image_alt_text', 720 fInput('text', 'alt', $alt, '', '', '', INPUT_REGULAR, '', 'image_alt_text'), 721 'alt_text', '', array('class' => 'txp-form-field edit-image-alt-text') 722 ). 723 inputLabel( 724 'image_caption', 725 '<textarea id="image_caption" name="caption" cols="'.INPUT_LARGE.'" rows="'.TEXTAREA_HEIGHT_SMALL.'">'.htmlspecialchars($caption, ENT_NOQUOTES).'</textarea>', 726 'caption', '', array('class' => 'txp-form-field txp-form-field-textarea edit-image-caption') 727 ). 728 pluggable_ui('image_ui', 'extend_detail_form', '', $rs). 729 hInput('id', $id). 730 eInput('image'). 731 sInput('image_save'). 732 hInput('sort', $sort). 733 hInput('dir', $dir). 734 hInput('page', $page). 735 hInput('search_method', $search_method). 736 hInput('crit', $crit), 737 'image_details' 738 ). 739 graf(fInput('submit', '', gTxt('save'), 'publish'), array('class' => 'txp-save')), 740 '', '', 'post', '', '', 'image_details_form'), 741 'div', array('class' => 'txp-layout-4col-alt') 742 ). 743 n.tag( 744 n.implode(n, $imageBlock). 745 n.'<hr />'. 746 n.tag(implode(n, $thumbBlock), 'section', array('class' => 'thumbnail-alter')), 747 'div', array('class' => 'txp-layout-4col-3span') 748 ). 749 n.'</div>'; // End of .txp-layout. 750 } 751 } 752 753 // ------------------------------------------------------------- 754 755 function image_insert() 756 { 757 global $txpcfg, $extensions, $txp_user; 758 759 if (!has_privs('image.edit.own')) { 760 image_list(gTxt('restricted_area')); 761 762 return; 763 } 764 765 extract($txpcfg); 766 767 $meta = gpsa(array('caption', 'alt', 'category')); 768 769 $img_result = image_data($_FILES['thefile'], $meta); 770 771 if (is_array($img_result)) { 772 list($message, $id) = $img_result; 773 774 return image_edit($message, $id); 775 } else { 776 return image_list(array($img_result, E_ERROR)); 777 } 778 } 779 780 // ------------------------------------------------------------- 781 782 function image_replace() 783 { 784 global $txpcfg, $extensions, $txp_user; 785 extract($txpcfg); 786 787 $id = assert_int(gps('id')); 788 $rs = safe_row("*", 'txp_image', "id = $id"); 789 790 if (!has_privs('image.edit') && !($rs['author'] === $txp_user && has_privs('image.edit.own'))) { 791 image_list(gTxt('restricted_area')); 792 793 return; 794 } 795 796 if ($rs) { 797 $meta = array('category' => $rs['category'], 'caption' => $rs['caption'], 'alt' => $rs['alt']); 798 } else { 799 $meta = ''; 800 } 801 802 $img_result = image_data($_FILES['thefile'], $meta, $id); 803 804 if (is_array($img_result)) { 805 list($message, $id) = $img_result; 806 807 return image_edit($message, $id); 808 } else { 809 return image_edit(array($img_result, E_ERROR), $id); 810 } 811 } 812 813 // ------------------------------------------------------------- 814 815 function thumbnail_insert() 816 { 817 global $txpcfg, $extensions, $txp_user, $img_dir, $path_to_site; 818 extract($txpcfg); 819 $id = assert_int(gps('id')); 820 $author = fetch('author', 'txp_image', 'id', $id); 821 822 if (!has_privs('image.edit') && !($author === $txp_user && has_privs('image.edit.own'))) { 823 image_list(gTxt('restricted_area')); 824 825 return; 826 } 827 828 $file = $_FILES['thefile']['tmp_name']; 829 $name = $_FILES['thefile']['name']; 830 $file = get_uploaded_file($file); 831 832 if (empty($file)) { 833 image_edit(array(upload_get_errormsg(UPLOAD_ERR_NO_FILE), E_ERROR), $id); 834 835 return; 836 } 837 838 list($w, $h, $extension) = getimagesize($file); 839 840 if (($file !== false) && @$extensions[$extension]) { 841 $ext = $extensions[$extension]; 842 $newpath = IMPATH.$id.'t'.$ext; 843 844 if (shift_uploaded_file($file, $newpath) == false) { 845 image_edit(array($newpath.sp.gTxt('upload_dir_perms'), E_ERROR), $id); 846 } else { 847 chmod($newpath, 0644); 848 safe_update('txp_image', "thumbnail = 1, thumb_w = $w, thumb_h = $h, date = NOW()", "id = $id"); 849 850 $message = gTxt('image_uploaded', array('{name}' => $name)); 851 update_lastmod('thumbnail_created', compact('id', 'w', 'h')); 852 853 image_edit($message, $id); 854 } 855 } else { 856 if ($file === false) { 857 image_edit(array(upload_get_errormsg($_FILES['thefile']['error']), E_ERROR), $id); 858 } else { 859 image_edit(array(gTxt('only_graphic_files_allowed'), E_ERROR), $id); 860 } 861 } 862 } 863 864 // ------------------------------------------------------------- 865 866 function image_save() 867 { 868 global $txp_user; 869 870 $varray = array_map('assert_string', gpsa(array('id', 'name', 'category', 'caption', 'alt'))); 871 extract(doSlash($varray)); 872 $id = $varray['id'] = assert_int($id); 873 $author = fetch('author', 'txp_image', 'id', $id); 874 875 if (!has_privs('image.edit') && !($author === $txp_user && has_privs('image.edit.own'))) { 876 image_list(gTxt('restricted_area')); 877 878 return; 879 } 880 881 $constraints = array( 882 'category' => new CategoryConstraint(gps('category'), array('type' => 'image')), 883 ); 884 callback_event_ref('image_ui', 'validate_save', 0, $varray, $constraints); 885 $validator = new Validator($constraints); 886 887 if ($validator->validate() && safe_update( 888 'txp_image', 889 "name = '$name', 890 category = '$category', 891 alt = '$alt', 892 caption = '$caption'", 893 "id = $id" 894 )) { 895 $message = gTxt('image_updated', array('{name}' => doStrip($name))); 896 update_lastmod('image_saved', compact('id', 'name', 'category', 'alt', 'caption')); 897 } else { 898 $message = array(gTxt('image_save_failed'), E_ERROR); 899 } 900 901 image_list($message); 902 } 903 904 // ------------------------------------------------------------- 905 906 function image_delete($ids = array()) 907 { 908 global $txp_user, $event; 909 910 $ids = $ids ? array_map('assert_int', $ids) : array(assert_int(ps('id'))); 911 $message = ''; 912 913 if (!has_privs('image.delete')) { 914 if (has_privs('image.delete.own')) { 915 $ids = safe_column("id", 'txp_image', "id IN (".join(',', $ids).") AND author = '".doSlash($txp_user)."'"); 916 } else { 917 $ids = array(); 918 } 919 } 920 921 if (!empty($ids)) { 922 $fail = array(); 923 $rs = safe_rows_start("id, ext", 'txp_image', "id IN (".join(',', $ids).")"); 924 925 if ($rs) { 926 while ($a = nextRow($rs)) { 927 extract($a); 928 929 // Notify plugins of pending deletion, pass image's $id. 930 callback_event('image_deleted', $event, false, $id); 931 932 $rsd = safe_delete('txp_image', "id = $id"); 933 $ul = false; 934 935 if (is_file(IMPATH.$id.$ext)) { 936 $ul = unlink(IMPATH.$id.$ext); 937 } 938 939 if (is_file(IMPATH.$id.'t'.$ext)) { 940 $ult = unlink(IMPATH.$id.'t'.$ext); 941 } 942 943 if (!$rsd or !$ul) { 944 $fail[] = $id; 945 } 946 } 947 948 if ($fail) { 949 $message = array(gTxt('image_delete_failed', array('{name}' => join(', ', $fail))), E_ERROR); 950 } else { 951 update_lastmod('image_deleted', compact('id')); 952 $message = gTxt('image_deleted', array('{name}' => join(', ', $ids))); 953 } 954 } 955 } 956 957 image_list($message); 958 } 959 960 // ------------------------------------------------------------- 961 962 function image_change_pageby() 963 { 964 event_change_pageby('image'); 965 image_list(); 966 } 967 968 // ------------------------------------------------------------- 969 970 function thumbnail_create() 971 { 972 global $prefs, $txp_user; 973 974 extract(doSlash(gpsa(array('id', 'width', 'height')))); 975 $id = assert_int($id); 976 $author = fetch('author', 'txp_image', 'id', $id); 977 978 if (!has_privs('image.edit') && !($author === $txp_user && has_privs('image.edit.own'))) { 979 image_list(gTxt('restricted_area')); 980 981 return; 982 } 983 984 $width = (int) $width; 985 $height = (int) $height; 986 987 if ($width == 0) { 988 $width = ''; 989 } 990 991 if ($height == 0) { 992 $height = ''; 993 } 994 995 $crop = gps('crop'); 996 997 $prefs['thumb_w'] = $width; 998 $prefs['thumb_h'] = $height; 999 $prefs['thumb_crop'] = $crop; 1000 1001 // Hidden prefs. 1002 set_pref('thumb_w', $width, 'image', 2); 1003 set_pref('thumb_h', $height, 'image', 2); 1004 set_pref('thumb_crop', $crop, 'image', 2); 1005 1006 if ($width === '' && $height === '') { 1007 image_edit(array(gTxt('invalid_width_or_height'), E_ERROR), $id); 1008 1009 return; 1010 } 1011 1012 $t = new txp_thumb($id); 1013 $t->crop = ($crop == '1'); 1014 $t->hint = '0'; 1015 $t->width = $width; 1016 $t->height = $height; 1017 1018 if ($t->write()) { 1019 $message = gTxt('thumbnail_saved', array('{id}' => $id)); 1020 update_lastmod('thumbnail_created', compact('id', 'width', 'height', 'crop')); 1021 1022 image_edit($message, $id); 1023 } else { 1024 $message = array(gTxt('thumbnail_not_saved', array('{id}' => $id)), E_ERROR); 1025 1026 image_edit($message, $id); 1027 } 1028 } 1029 1030 // ------------------------------------------------------------- 1031 1032 function thumbnail_delete() 1033 { 1034 global $txp_user; 1035 1036 $id = assert_int(gps('id')); 1037 $author = fetch('author', 'txp_image', 'id', $id); 1038 1039 if (!has_privs('image.edit') && !($author === $txp_user && has_privs('image.edit.own'))) { 1040 image_list(gTxt('restricted_area')); 1041 1042 return; 1043 } 1044 1045 $t = new txp_thumb($id); 1046 1047 if ($t->delete()) { 1048 callback_event('thumbnail_deleted', '', false, $id); 1049 update_lastmod('thumbnail_deleted', compact('id')); 1050 image_edit(gTxt('thumbnail_deleted'), $id); 1051 } else { 1052 image_edit(array(gTxt('thumbnail_delete_failed'), E_ERROR), $id); 1053 } 1054 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
title