-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathReassignFilesPlugin.php
293 lines (247 loc) · 9.08 KB
/
ReassignFilesPlugin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<?php
/**
* ConditionalElements plugin.
*
* @package Omeka\Plugins\ReassignFiles
*/
class ReassignFilesPlugin extends Omeka_Plugin_AbstractPlugin
{
// Define Hooks
protected $_hooks = array(
'initialize',
'install',
'uninstall',
'after_save_item',
'admin_items_form_files',
'define_acl',
'config_form',
'config',
);
//Define Filters
protected $_filters = array('admin_navigation_main');
protected $_options = array(
'reassign_files_delete_orphaned_items' => 1,
'reassign_files_local_reassign' => 0,
);
public function hookInitialize()
{
add_translation_source(dirname(__FILE__) . '/languages');
}
/**
* Install the plugin.
*/
public function hookInstall() {
SELF::_installOptions();
}
/**
* Uninstall the plugin.
*/
public function hookUninstall() {
SELF::_uninstallOptions();
}
/**
* reassignfiles admin navigation filter
*/
public function filterAdminNavigationMain($nav)
{
if(is_allowed('ReassignFiles_Index', 'index')) {
$nav[] = array('label' => __('Reassign Files'), 'uri' => url('reassign-files'));
}
return $nav;
}
/*
* Define ACL entry for reassignfiles controller.
*/
public function hookDefineAcl($args)
{
$acl = $args['acl'];
$indexResource = new Zend_Acl_Resource('ReassignFiles_Index');
$acl->add($indexResource);
$acl->allow(array('super', 'admin'), 'ReassignFiles_Index', 'index');
}
/**
* Display the reassignfiles list on the item form.
* This simply adds a heading to the output
*/
public function hookAdminItemsFormFiles()
{
$localReassign = (int)(boolean) get_option('reassign_files_local_reassign');
if ($localReassign) {
echo '<h3>' . __('Add Files from Other Items') . '</h3>';
$itemId = metadata('item', 'id');
$fileNames = SELF::reassignFiles_getFileNames($itemId); // from helpers/ReassignFilesFunctions.php
echo common('reassignfileslist', array( "fileNames" => $fileNames ), 'index');
}
}
public function hookAfterSaveItem($args)
{
if (!$args['post']) {
return;
}
$record = $args['record'];
$post = $args['post'];
#echo "<pre>"; print_r($_POST); die("</pre>");
// reassign the selected files from other items to the current item
if (isset($post['reassignFilesFiles']) and (isset($post['itemId']))) {
$itemID = ( $post['itemId'] ? $post['itemId'] : $args["record"]["id"] );
$errMsg = SELF::reassignFiles_reassignFiles($itemID, $post['reassignFilesFiles']);
# if ($errMsg) { $this->_helper->flashMessenger( $errMsg, 'error' ); }
// ... turns out, we don't actually have a $this->_helper object here :-(
}
}
/**
* Display the plugin configuration form.
*/
public static function hookConfigForm() {
$deleteOrphanedItems = (int)(boolean) get_option('reassign_files_delete_orphaned_items');
$localReassign = (int)(boolean) get_option('reassign_files_local_reassign');
require dirname(__FILE__) . '/config_form.php';
}
/**
* Handle the plugin configuration form.
*/
public static function hookConfig() {
$deleteOrphanedItems = (int)(boolean) $_POST['reassign_files_delete_orphaned_items'];
set_option('reassign_files_delete_orphaned_items', $deleteOrphanedItems);
$localReassign = (int)(boolean) $_POST['reassign_files_local_reassign'];
set_option('reassign_files_local_reassign', $localReassign);
$deleteOrphanedItemsNow = (int)(boolean) $_POST['reassign_files_delete_orphaned_items_now'];
if ($deleteOrphanedItemsNow) { SELF::reassignFiles_deleteOrphans(); }
}
private function _batchDeleteOrphanedItems() {
$db = get_db();
#check file? itemrelation installed? title? description?
$sql= "select id from `$db->Items` ";
$items = $db->fetchAll($sql);
#echo "<pre>"; print_r($items); die("</pre>");
}
/**
* Returns all fileNames as data source for the multi-select box
*/
public function reassignFiles_getFileNames($filterItemID = 0) {
$filterItemId = intval($filterItemID);
$filterItemInfix = ( $filterItemId > 0 ? "AND f.item_id <> $filterItemID" : "" );
$fileNames = array();
$db = get_db();
$select = "
SELECT f.original_filename AS original_filename, f.item_id AS itemId, f.id AS fileId
FROM {$db->File} f
WHERE 1 $filterItemInfix
";
$files = $db->fetchAll($select);
$itemIds = array();
foreach($files as $file) {
$itemIds[$file["itemId"]] = $file["itemId"];
}
$itemNames = array();
foreach($itemIds as $itemId) {
$item = get_record_by_id('Item', $itemId);
$itemNames[$itemId] = metadata($item, array('Dublin Core', 'Title'));
}
foreach ($files as $file) {
$fileNames[$file['fileId']] = $file['original_filename'].
' - '.$itemNames[$file['itemId']] .
' [#'.$file['itemId'].
'/'.$file['fileId'].']';
}
return $fileNames;
}
/**
* Do the actual work: Reassign the $files (specified by their file IDs towards one target item ID
*/
public function reassignFiles_reassignFiles($itemID, $files) {
$errMsg = false;
$itemID = intval($itemID); // typecast / filter item ID for strange characters
if ($itemID) {
$db = get_db();
// make sure that the target item actually exists in the database
$targetExists = $db->fetchOne("SELECT count(*) FROM `$db->Items` where id=$itemID");
if ($targetExists) {
$fileIDs = array();
foreach($files as $file) {
$fileID = intval($file); // typecast / filter file IDs for strange characters
if ($fileID) { $fileIDs[] = $fileID; }
}
if ($fileIDs) { // at least one?
$fileIDs = implode(",", $fileIDs);
$deleteOrphanedItems = (int)(boolean) get_option('reassign_files_delete_orphaned_items');
// 1st: If applicable, figure out which items might be orphaned after the reassign
$potentialOrphans = array();
if ($deleteOrphanedItems) {
$sql = "SELECT item_id from `$db->File` where id IN ($fileIDs)";
$potentialOrphans = $db->fetchAll($sql);
}
// 2nd: Actually reassign the files
$sql = "UPDATE `$db->File` set item_id = $itemID where id IN ($fileIDs)";
$db->query($sql); // let's do this
// 3rd: If applicable, take care of orphans, i.e. delete them
if ($deleteOrphanedItems) { SELF::reassignFiles_deleteOrphans($potentialOrphans); }
# $errMsg = $sql;
}
else { $errMsg = __('Please select one or more files to reassign to the selected item.'); }
}
else { $errMsg = __('Please select an existing item to reassign files to.'); }
}
else { $errMsg = __('Please select an item to reassign files to.'); }
return $errMsg;
}
/**
* If applicable, check if items who just had files assigned to other items are now "empty" and, if so, delete them
*/
function reassignFiles_deleteOrphans($potentialOrphans = false) {
$db = get_db();
$idInfix="WHERE true"; // Sanity: Check _all_ items
if ( is_array($potentialOrphans) ) { // Received an array of item IDs?
$justIds = array();
foreach($potentialOrphans as $potentialOrphan) { $justIds[] = $potentialOrphan["item_id"]; }
if ($justIds) {
$justIdString = implode(",", $justIds);
$idInfix = "WHERE it.id in ($justIdString)"; // limiting the items to be searched
}
else { $idInfix="WHERE false"; } // No IDs? Then don't search at all
}
// Huge left join query:
// - Find those items (in case they are still existent)
// - without any element texts
// - without any other files assigned to them
// - (if applicable) without item relations participation
// Is ItemRelations installed? In that case: Create infixes to check items' relations as well
$irJoin = $irWhere = "";
if (SELF::reassignFiles_withItemRelations()) {
$irJoin = "LEFT JOIN `$db->ItemRelationsRelations` ir
ON it.id = ir.subject_item_id OR it.id = ir.object_item_id";
$irWhere = "AND ir.subject_item_id IS NULL
AND ir.object_item_id IS NULL";
}
$sql = "SELECT it.id
FROM `$db->Items` it
LEFT JOIN {$db->ElementText} et
ON it.id = et.record_id AND et.element_id<>50
LEFT JOIN `$db->File` f
ON it.id = f.item_id
$irJoin
$idInfix
AND et.record_id IS NULL
AND f.item_id IS NULL
$irWhere
AND it.item_type_id IS NULL";
$orphans = $db->fetchAll($sql);
if ($orphans) {
foreach($orphans as $orphan) {
$orphanObject = $db->getTable('Item')->find($orphan["id"]);
$orphanObject->delete();
}
}
}
/**
* Checks if ItemRelations is installed, so it could be taken into account during orphaned items search
*/
function reassignFiles_withItemRelations() {
$db = get_db();
$sql = "select 1 from `$db->ItemRelationsRelations` limit 1";
$withItemRelations = false;
try { $withItemRelations = ($db->fetchOne($sql) === 1); }
catch (Exception $e) { $withItemRelations=false; }
return $withItemRelations;
}
}