├── .gitignore
├── README.md
├── _build
├── build.config.php
├── build.model.php
├── build.transport.php
├── data
│ ├── permissions
│ │ └── fileattach.policy.php
│ ├── transport.chunks.php
│ ├── transport.events.php
│ ├── transport.menu.php
│ ├── transport.plugins.php
│ ├── transport.policies.php
│ ├── transport.policytemplates.php
│ ├── transport.settings.php
│ └── transport.snippets.php
├── includes
│ └── functions.php
├── properties
│ ├── properties.fileattach.php
│ └── properties.filelink.php
├── resolvers
│ ├── resolve.chunks.php
│ ├── resolve.policy.php
│ ├── resolve.setup.php
│ └── resolve.tables.php
└── setup.options.php
├── assets
└── components
│ └── fileattach
│ ├── connector.php
│ └── js
│ └── mgr
│ ├── fileattach.js
│ ├── filestab.js
│ └── widgets
│ ├── home.panel.js
│ └── items.grid.js
└── core
└── components
└── fileattach
├── controllers
└── list.class.php
├── docs
├── changelog.txt
├── license.txt
└── readme.txt
├── elements
├── chunks
│ └── chunk.item.tpl
├── plugins
│ └── plugin.filestab.php
├── snippets
│ ├── snippet.fileattach.php
│ └── snippet.filelink.php
└── templates
│ └── home.tpl
├── lexicon
├── en
│ ├── default.inc.php
│ ├── permissions.inc.php
│ ├── properties.inc.php
│ ├── setting.inc.php
│ └── source.inc.php
└── ru
│ ├── default.inc.php
│ ├── permissions.inc.php
│ ├── properties.inc.php
│ ├── setting.inc.php
│ └── source.inc.php
├── model
├── fileattach
│ ├── fileattach.class.php
│ ├── fileattachmediasource.class.php
│ ├── fileitem.class.php
│ ├── metadata.mysql.php
│ ├── metadata.sqlsrv.php
│ ├── mysql
│ │ ├── fileattachmediasource.class.php
│ │ ├── fileattachmediasource.map.inc.php
│ │ ├── fileitem.class.php
│ │ └── fileitem.map.inc.php
│ └── sqlsrv
│ │ ├── fileattachmediasource.class.php
│ │ ├── fileattachmediasource.map.inc.php
│ │ ├── fileitem.class.php
│ │ └── fileitem.map.inc.php
└── schema
│ ├── fileattach.mysql.schema.xml
│ └── fileattach.sqlsrv.schema.xml
└── processors
├── mgr
├── access.class.php
├── create.class.php
├── get.class.php
├── getlist.class.php
├── hash.class.php
├── rank.class.php
├── remove.class.php
├── reset.class.php
├── searchres.class.php
├── update.class.php
└── upload.class.php
└── web
├── download.class.php
├── getlist.class.php
└── remove.class.php
/.gitignore:
--------------------------------------------------------------------------------
1 | config.core.php
2 | .idea
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## FileAttach
2 |
3 | FileAttach is a tool to create file collections.
4 | Package provides UI for MODx Manager to upload files to Resources,
5 | manage file list, view download statistics, snippet for front-end listing.
6 | Allows to count downloads, keep files privately (without direct url),
7 | calculate SHA1 hash for uploaded files. Works with MediaSource.
8 | Provides MediaSource to view tree with Resources and files attached to them.
9 |
10 | ## How to Export
11 |
12 | First, clone this repository somewhere on your development machine:
13 |
14 | `git clone http://github.com/13hakta/FileAttach.git ./`
15 |
16 | Then, create the target directory where you want to create the file.
17 |
18 | Then, navigate to the directory FileAttach is now in, and do this:
19 |
20 | `git archive HEAD | (cd /path/where/I/want/my/new/repo/ && tar -xvf -)`
21 |
22 | (Windows users can just do git archive HEAD and extract the tar file to wherever
23 | they want.)
24 |
25 | Then you can git init or whatever in that directory, and your files will be located
26 | there!
27 |
28 | ## Configuration
29 |
30 | Now, you'll want to change references to FileAttach in the files in your
31 | new copied-from-FileAttach repo to whatever name of your new Extra will be. Once
32 | you've done that, you can create some System Settings:
33 |
34 | - 'mynamespace.core_path' - Point to /path/to/my/extra/core/components/extra/
35 | - 'mynamespace.assets_url' - /path/to/my/extra/assets/components/extra/
36 |
37 | Then clear the cache. This will tell the Extra to look for the files located
38 | in these directories, allowing you to develop outside of the MODx webroot!
39 |
40 | ## Information
41 |
42 | Note that if you git archive from this repository, you may not need all of its
43 | functionality. This Extra contains files and the setup to do the following:
44 |
45 | - Integrates a custom table of "FileItem"
46 | - A snippet listing Items sorted by name and templated with a chunk
47 | - A snippet showing link to get inline content
48 | - A custom manager page to manage FileItem on
49 |
50 | If you do not require all of this functionality, simply remove it and change the
51 | appropriate code.
52 |
53 | Also, you'll want to change all the references of 'FileAttach' to whatever the
54 | name of your component is.
55 |
56 | ## Copyright Information
57 |
58 | FileAttach is distributed as GPL (as MODx Revolution is), but the copyright owner
59 | (Vitaly Chekryzhev) grants all users of FileAttach the ability to modify, distribute
60 | and use FileAttach in MODx development as they see fit, as long as attribution
61 | is given somewhere in the distributed source of all derivative works.
--------------------------------------------------------------------------------
/_build/build.config.php:
--------------------------------------------------------------------------------
1 | $root,
11 | 'build' => $root . '_build/',
12 | 'source_core' => $root . 'core/components/' . PKG_NAME_LOWER,
13 | 'model' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/',
14 | 'schema' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/schema/',
15 | 'xml' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/schema/' . PKG_NAME_LOWER . '.mysql.schema.xml',
16 | 'xml2' => $root . 'core/components/' . PKG_NAME_LOWER . '/model/schema/' . PKG_NAME_LOWER . '.sqlsrv.schema.xml',
17 | );
18 | unset($root);
19 |
20 | require MODX_CORE_PATH . 'model/modx/modx.class.php';
21 | require $sources['build'] . '/includes/functions.php';
22 |
23 | $modx = new modX();
24 | $modx->initialize('mgr');
25 | $modx->getService('error', 'error.modError');
26 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
27 | $modx->setLogTarget('ECHO');
28 | $modx->loadClass('transport.modPackageBuilder', '', false, true);
29 | if (!XPDO_CLI_MODE) {
30 | echo '
';
31 | }
32 |
33 | /** @var xPDOManager $manager */
34 | $manager = $modx->getManager();
35 | /** @var xPDOGenerator $generator */
36 | $generator = $manager->getGenerator();
37 |
38 | // Remove old model
39 | rrmdir($sources['model'] . PKG_NAME_LOWER . '/mysql');
40 | rrmdir($sources['model'] . PKG_NAME_LOWER . '/sqlsrv');
41 |
42 | // Generate a new one
43 | $generator->parseSchema($sources['xml'], $sources['model']);
44 | $generator->parseSchema($sources['xml2'], $sources['model']);
45 |
46 | $modx->log(modX::LOG_LEVEL_INFO, 'Model generated.');
47 | if (!XPDO_CLI_MODE) {
48 | echo '
';
49 | }
--------------------------------------------------------------------------------
/_build/build.transport.php:
--------------------------------------------------------------------------------
1 | $root,
21 | 'build' => $root . '_build/',
22 | 'data' => $root . '_build/data/',
23 | 'resolvers' => $root . '_build/resolvers/',
24 | 'chunks' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/chunks/',
25 | 'snippets' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/',
26 | 'plugins' => $root . 'core/components/' . PKG_NAME_LOWER . '/elements/plugins/',
27 | 'lexicon' => $root . 'core/components/' . PKG_NAME_LOWER . '/lexicon/',
28 | 'docs' => $root . 'core/components/' . PKG_NAME_LOWER . '/docs/',
29 | 'source_assets' => $root . 'assets/components/' . PKG_NAME_LOWER,
30 | 'source_core' => $root . 'core/components/' . PKG_NAME_LOWER,
31 | );
32 | unset($root);
33 |
34 | require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
35 | require_once $sources['build'] . '/includes/functions.php';
36 |
37 | $modx = new modX();
38 | $modx->initialize('mgr');
39 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
40 | $modx->setLogTarget('ECHO');
41 | $modx->getService('error', 'error.modError');
42 | $modx->loadClass('transport.modPackageBuilder', '', false, true);
43 | if (!XPDO_CLI_MODE) {
44 | echo '';
45 | }
46 |
47 | $builder = new modPackageBuilder($modx);
48 | $builder->createPackage(PKG_NAME_LOWER, PKG_VERSION, PKG_RELEASE);
49 | $builder->registerNamespace(PKG_NAME_LOWER, false, true, PKG_NAMESPACE_PATH, PKG_ASSETS_PATH);
50 |
51 | $modx->log(modX::LOG_LEVEL_INFO, 'Created Transport Package and Namespace.');
52 |
53 | /* load system settings */
54 | if (defined('BUILD_SETTING_UPDATE')) {
55 | $settings = include $sources['data'] . 'transport.settings.php';
56 | if (!is_array($settings)) {
57 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in settings.');
58 | }
59 | else {
60 | $attributes = array(
61 | xPDOTransport::UNIQUE_KEY => 'key',
62 | xPDOTransport::PRESERVE_KEYS => true,
63 | xPDOTransport::UPDATE_OBJECT => BUILD_SETTING_UPDATE,
64 | );
65 | foreach ($settings as $setting) {
66 | $vehicle = $builder->createVehicle($setting, $attributes);
67 | $builder->putVehicle($vehicle);
68 | }
69 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($settings) . ' System Settings.');
70 | }
71 | unset($settings, $setting, $attributes);
72 | }
73 |
74 | /* load plugins events */
75 | if (defined('BUILD_EVENT_UPDATE')) {
76 | $events = include $sources['data'] . 'transport.events.php';
77 | if (!is_array($events)) {
78 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in events.');
79 | }
80 | else {
81 | $attributes = array(
82 | xPDOTransport::PRESERVE_KEYS => true,
83 | xPDOTransport::UPDATE_OBJECT => BUILD_EVENT_UPDATE,
84 | );
85 | foreach ($events as $event) {
86 | $vehicle = $builder->createVehicle($event, $attributes);
87 | $builder->putVehicle($vehicle);
88 | }
89 | $modx->log(xPDO::LOG_LEVEL_INFO, 'Packaged in ' . count($events) . ' Plugins events.');
90 | }
91 | unset ($events, $event, $attributes);
92 | }
93 |
94 | /* package in default access policy */
95 | if (defined('BUILD_POLICY_UPDATE')) {
96 | $attributes = array(
97 | xPDOTransport::PRESERVE_KEYS => false,
98 | xPDOTransport::UNIQUE_KEY => array('name'),
99 | xPDOTransport::UPDATE_OBJECT => BUILD_POLICY_UPDATE,
100 | );
101 | $policies = include $sources['data'] . 'transport.policies.php';
102 | if (!is_array($policies)) {
103 | $modx->log(modX::LOG_LEVEL_FATAL, 'Adding policies failed.');
104 | }
105 | foreach ($policies as $policy) {
106 | $vehicle = $builder->createVehicle($policy, $attributes);
107 | $builder->putVehicle($vehicle);
108 | }
109 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($policies) . ' Access Policies.');
110 | flush();
111 | unset($policies, $policy, $attributes);
112 | }
113 |
114 | /* package in default access policy templates */
115 | if (defined('BUILD_POLICY_TEMPLATE_UPDATE')) {
116 | $templates = include dirname(__FILE__) . '/data/transport.policytemplates.php';
117 | $attributes = array(
118 | xPDOTransport::PRESERVE_KEYS => false,
119 | xPDOTransport::UNIQUE_KEY => array('name'),
120 | xPDOTransport::UPDATE_OBJECT => BUILD_POLICY_TEMPLATE_UPDATE,
121 | xPDOTransport::RELATED_OBJECTS => true,
122 | xPDOTransport::RELATED_OBJECT_ATTRIBUTES => array(
123 | 'Permissions' => array(
124 | xPDOTransport::PRESERVE_KEYS => false,
125 | xPDOTransport::UPDATE_OBJECT => BUILD_PERMISSION_UPDATE,
126 | xPDOTransport::UNIQUE_KEY => array('template', 'name'),
127 | ),
128 | )
129 | );
130 | if (is_array($templates)) {
131 | foreach ($templates as $template) {
132 | $vehicle = $builder->createVehicle($template, $attributes);
133 | $builder->putVehicle($vehicle);
134 | }
135 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($templates) . ' Access Policy Templates.');
136 | flush();
137 | }
138 | else {
139 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in Access Policy Templates.');
140 | }
141 | unset ($templates, $template, $attributes);
142 | }
143 |
144 | /* load menus */
145 | if (defined('BUILD_MENU_UPDATE')) {
146 | $menus = include $sources['data'] . 'transport.menu.php';
147 |
148 | $attributes = array(
149 | xPDOTransport::PRESERVE_KEYS => true,
150 | xPDOTransport::UPDATE_OBJECT => BUILD_MENU_UPDATE,
151 | xPDOTransport::UNIQUE_KEY => 'text',
152 | xPDOTransport::RELATED_OBJECTS => true
153 | );
154 |
155 | if (is_array($menus)) {
156 | foreach ($menus as $menu) {
157 | $vehicle = $builder->createVehicle($menu, $attributes);
158 | $builder->putVehicle($vehicle);
159 | /* @var modMenu $menu */
160 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in menu "' . $menu->get('text') . '".');
161 | }
162 | }
163 | else {
164 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in menu.');
165 | }
166 | unset($vehicle, $menus, $menu, $attributes);
167 | }
168 |
169 |
170 | /* create category */
171 | $modx->log(xPDO::LOG_LEVEL_INFO, 'Created category.');
172 | /* @var modCategory $category */
173 | $category = $modx->newObject('modCategory');
174 | $category->set('category', PKG_NAME);
175 | /* create category vehicle */
176 | $attr = array(
177 | xPDOTransport::UNIQUE_KEY => 'category',
178 | xPDOTransport::PRESERVE_KEYS => false,
179 | xPDOTransport::UPDATE_OBJECT => true,
180 | xPDOTransport::RELATED_OBJECTS => true,
181 | );
182 |
183 | /* add snippets */
184 | if (defined('BUILD_SNIPPET_UPDATE')) {
185 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Snippets'] = array(
186 | xPDOTransport::PRESERVE_KEYS => false,
187 | xPDOTransport::UPDATE_OBJECT => BUILD_SNIPPET_UPDATE,
188 | xPDOTransport::UNIQUE_KEY => 'name',
189 | );
190 | $snippets = include $sources['data'] . 'transport.snippets.php';
191 | if (!is_array($snippets)) {
192 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in snippets.');
193 | }
194 | else {
195 | $category->addMany($snippets);
196 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($snippets) . ' snippets.');
197 | }
198 | }
199 |
200 | /* add chunks */
201 | if (defined('BUILD_CHUNK_UPDATE')) {
202 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Chunks'] = array(
203 | xPDOTransport::PRESERVE_KEYS => false,
204 | xPDOTransport::UPDATE_OBJECT => BUILD_CHUNK_UPDATE,
205 | xPDOTransport::UNIQUE_KEY => 'name',
206 | );
207 | $chunks = include $sources['data'] . 'transport.chunks.php';
208 | if (!is_array($chunks)) {
209 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in chunks.');
210 | }
211 | else {
212 | $category->addMany($chunks);
213 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($chunks) . ' chunks.');
214 | }
215 | }
216 |
217 | /* add plugins */
218 | if (defined('BUILD_PLUGIN_UPDATE')) {
219 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['Plugins'] = array(
220 | xPDOTransport::PRESERVE_KEYS => false,
221 | xPDOTransport::UPDATE_OBJECT => BUILD_PLUGIN_UPDATE,
222 | xPDOTransport::UNIQUE_KEY => 'name',
223 | );
224 | $attr[xPDOTransport::RELATED_OBJECT_ATTRIBUTES]['PluginEvents'] = array(
225 | xPDOTransport::PRESERVE_KEYS => true,
226 | xPDOTransport::UPDATE_OBJECT => BUILD_EVENT_UPDATE,
227 | xPDOTransport::UNIQUE_KEY => array('pluginid', 'event'),
228 | );
229 | $plugins = include $sources['data'] . 'transport.plugins.php';
230 | if (!is_array($plugins)) {
231 | $modx->log(modX::LOG_LEVEL_ERROR, 'Could not package in plugins.');
232 | }
233 | else {
234 | $category->addMany($plugins);
235 | $modx->log(modX::LOG_LEVEL_INFO, 'Packaged in ' . count($plugins) . ' plugins.');
236 | }
237 | }
238 |
239 | $vehicle = $builder->createVehicle($category, $attr);
240 |
241 | /* now pack in resolvers */
242 | $vehicle->resolve('file', array(
243 | 'source' => $sources['source_assets'],
244 | 'target' => "return MODX_ASSETS_PATH . 'components/';",
245 | ));
246 | $vehicle->resolve('file', array(
247 | 'source' => $sources['source_core'],
248 | 'target' => "return MODX_CORE_PATH . 'components/';",
249 | ));
250 |
251 | foreach ($BUILD_RESOLVERS as $resolver) {
252 | if ($vehicle->resolve('php', array('source' => $sources['resolvers'] . 'resolve.' . $resolver . '.php'))) {
253 | $modx->log(modX::LOG_LEVEL_INFO, 'Added resolver "' . $resolver . '" to category.');
254 | }
255 | else {
256 | $modx->log(modX::LOG_LEVEL_INFO, 'Could not add resolver "' . $resolver . '" to category.');
257 | }
258 | }
259 |
260 | flush();
261 | $builder->putVehicle($vehicle);
262 |
263 | /* now pack in the license file, readme and setup options */
264 | $builder->setPackageAttributes(array(
265 | 'changelog' => file_get_contents($sources['docs'] . 'changelog.txt'),
266 | 'license' => file_get_contents($sources['docs'] . 'license.txt'),
267 | 'readme' => file_get_contents($sources['docs'] . 'readme.txt'),
268 | 'setup-options' => array(
269 | 'source' => $sources['build'] . 'setup.options.php',
270 | ),
271 | ));
272 | $modx->log(modX::LOG_LEVEL_INFO, 'Added package attributes and setup options.');
273 |
274 | /* zip up package */
275 | $modx->log(modX::LOG_LEVEL_INFO, 'Packing up transport package zip...');
276 | $builder->pack();
277 |
278 | $mtime = microtime();
279 | $mtime = explode(" ", $mtime);
280 | $mtime = $mtime[1] + $mtime[0];
281 | $tend = $mtime;
282 | $totalTime = ($tend - $tstart);
283 | $totalTime = sprintf("%2.4f s", $totalTime);
284 |
285 | $signature = $builder->getSignature();
286 | if (defined('PKG_AUTO_INSTALL') && PKG_AUTO_INSTALL) {
287 | $sig = explode('-', $signature);
288 | $versionSignature = explode('.', $sig[1]);
289 |
290 | /* @var modTransportPackage $package */
291 | if (!$package = $modx->getObject('transport.modTransportPackage', array('signature' => $signature))) {
292 | $package = $modx->newObject('transport.modTransportPackage');
293 | $package->set('signature', $signature);
294 | $package->fromArray(array(
295 | 'created' => date('Y-m-d h:i:s'),
296 | 'updated' => null,
297 | 'state' => 1,
298 | 'workspace' => 1,
299 | 'provider' => 0,
300 | 'source' => $signature . '.transport.zip',
301 | 'package_name' => $sig[0],
302 | 'version_major' => $versionSignature[0],
303 | 'version_minor' => !empty($versionSignature[1]) ? $versionSignature[1] : 0,
304 | 'version_patch' => !empty($versionSignature[2]) ? $versionSignature[2] : 0,
305 | ));
306 | if (!empty($sig[2])) {
307 | $r = preg_split('/([0-9]+)/', $sig[2], -1, PREG_SPLIT_DELIM_CAPTURE);
308 | if (is_array($r) && !empty($r)) {
309 | $package->set('release', $r[0]);
310 | $package->set('release_index', (isset($r[1]) ? $r[1] : '0'));
311 | }
312 | else {
313 | $package->set('release', $sig[2]);
314 | }
315 | }
316 | $package->save();
317 | }
318 |
319 | if ($package->install()) {
320 | $modx->runProcessor('system/clearcache');
321 | }
322 | }
323 | if (!empty($_GET['download'])) {
324 | echo '';
325 | }
326 |
327 | $modx->log(modX::LOG_LEVEL_INFO, "\n
Execution time: {$totalTime}\n");
328 | if (!XPDO_CLI_MODE) {
329 | echo '
';
330 | }
331 |
--------------------------------------------------------------------------------
/_build/data/permissions/fileattach.policy.php:
--------------------------------------------------------------------------------
1 | newObject('modAccessPermission',array(
11 | 'name' => 'fileattach.totallist',
12 | 'description' => 'perm.fileattach_all',
13 | 'value' => true,
14 | ));
15 |
16 | $permissions[] = $modx->newObject('modAccessPermission',array(
17 | 'name' => 'fileattach.doclist',
18 | 'description' => 'perm.fileattach_doc',
19 | 'value' => true,
20 | ));
21 |
22 | $permissions[] = $modx->newObject('modAccessPermission',array(
23 | 'name' => 'fileattach.download',
24 | 'description' => 'perm.fileattach_download',
25 | 'value' => true,
26 | ));
27 |
28 | $permissions[] = $modx->newObject('modAccessPermission',array(
29 | 'name' => 'fileattach.list',
30 | 'description' => 'perm.fileattach_list',
31 | 'value' => true,
32 | ));
33 |
34 | $permissions[] = $modx->newObject('modAccessPermission',array(
35 | 'name' => 'fileattach.remove',
36 | 'description' => 'perm.fileattach_remove',
37 | 'value' => true,
38 | ));
39 |
40 | return $permissions;
--------------------------------------------------------------------------------
/_build/data/transport.chunks.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'file' => 'item',
8 | 'description' => '',
9 | ),
10 | );
11 |
12 | // Save chunks for setup options
13 | $BUILD_CHUNKS = array();
14 |
15 | foreach ($tmp as $k => $v) {
16 | /* @avr modChunk $chunk */
17 | $chunk = $modx->newObject('modChunk');
18 | $chunk->fromArray(array(
19 | 'id' => 0,
20 | 'name' => $k,
21 | 'description' => @$v['description'],
22 | 'snippet' => file_get_contents($sources['source_core'] . '/elements/chunks/chunk.' . $v['file'] . '.tpl'),
23 | 'static' => BUILD_CHUNK_STATIC,
24 | 'source' => 1,
25 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/chunks/chunk.' . $v['file'] . '.tpl',
26 | ), '', true, true);
27 |
28 | $chunks[] = $chunk;
29 |
30 | $BUILD_CHUNKS[$k] = file_get_contents($sources['source_core'] . '/elements/chunks/chunk.' . $v['file'] . '.tpl');
31 | }
32 |
33 | unset($tmp);
34 | return $chunks;
--------------------------------------------------------------------------------
/_build/data/transport.events.php:
--------------------------------------------------------------------------------
1 | $v) {
12 | /** @var modEvent $event */
13 | $event = $modx->newObject('modEvent');
14 | $event->fromArray(array(
15 | 'name' => $v,
16 | 'service' => 6,
17 | 'groupname' => PKG_NAME,
18 | ), '', true, true);
19 | $events[] = $event;
20 | }
21 |
22 | return $events;
--------------------------------------------------------------------------------
/_build/data/transport.menu.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'description' => 'fileattach.menu_desc',
8 | 'permissions' => 'fileattach.totallist',
9 | 'action' => 'list'
10 | ),
11 | );
12 |
13 | $i = 0;
14 | foreach ($tmp as $k => $v) {
15 | /* @var modMenu $menu */
16 | $menu = $modx->newObject('modMenu');
17 | $menu->fromArray(array_merge(
18 | array(
19 | 'namespace' => PKG_NAME_LOWER,
20 | 'text' => $k,
21 | 'parent' => 'components',
22 | 'menuindex' => $i,
23 | 'params' => '',
24 | 'handler' => '',
25 | ), $v
26 | ), '', true, true);
27 |
28 | $menus[] = $menu;
29 | $i++;
30 | }
31 |
32 | unset($action, $menu, $i);
33 | return $menus;
--------------------------------------------------------------------------------
/_build/data/transport.plugins.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'file' => 'filestab',
8 | 'description' => '',
9 | 'events' => array(
10 | 'OnDocFormPrerender' => array(),
11 | 'OnEmptyTrash' => array()
12 | )
13 | )
14 | );
15 |
16 | foreach ($tmp as $k => $v) {
17 | /* @avr modplugin $plugin */
18 | $plugin = $modx->newObject('modPlugin');
19 | $plugin->fromArray(array(
20 | 'name' => $k,
21 | 'category' => 0,
22 | 'description' => @$v['description'],
23 | 'plugincode' => getSnippetContent($sources['source_core'] . '/elements/plugins/plugin.' . $v['file'] . '.php'),
24 | 'static' => BUILD_PLUGIN_STATIC,
25 | 'source' => 1,
26 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/plugins/plugin.' . $v['file'] . '.php'
27 | ), '', true, true);
28 |
29 | $events = array();
30 | if (!empty($v['events'])) {
31 | foreach ($v['events'] as $k2 => $v2) {
32 | /* @var modPluginEvent $event */
33 | $event = $modx->newObject('modPluginEvent');
34 | $event->fromArray(array_merge(
35 | array(
36 | 'event' => $k2,
37 | 'priority' => 0,
38 | 'propertyset' => 0,
39 | ), $v2
40 | ), '', true, true);
41 | $events[] = $event;
42 | }
43 | unset($v['events']);
44 | }
45 |
46 | if (!empty($events))
47 | $plugin->addMany($events);
48 |
49 | $plugins[] = $plugin;
50 | }
51 |
52 | unset($tmp, $properties);
53 | return $plugins;
--------------------------------------------------------------------------------
/_build/data/transport.policies.php:
--------------------------------------------------------------------------------
1 | array(
14 | 'description' => 'A policy for editing attached files to resources.',
15 | 'data' => '{"fileattach.totallist":true,"fileattach.doclist":true,"fileattach.download":true,"fileattach.list":true,"fileattach.remove":true}'),
16 | 'File Attach Download' => array(
17 | 'description' => 'A policy for downloading attached files to resources.',
18 | 'data' => '{"fileattach.download":true}'),
19 | 'File Attach Frontend' => array(
20 | 'description' => 'A policy for frontend uploading files to resources.',
21 | 'data' => '{"fileattach.download":true,"fileattach.list":true,"fileattach.remove":true}')
22 | );
23 |
24 | foreach ($tmp as $k => $v) {
25 | /* @avr modplugin $plugin */
26 | $policy = $modx->newObject('modAccessPolicy');
27 |
28 | $policy->fromArray(array(
29 | 'name' => $k,
30 | 'parent' => 0,
31 | 'class' => '',
32 | 'lexicon' => PKG_NAME_LOWER . ':permissions',
33 | 'data' => @$v['data'],
34 | 'description' => @$v['description']
35 | ), '', true, true);
36 |
37 | $policies[] = $policy;
38 | }
39 |
40 | unset($tmp, $template);
41 | return $policies;
--------------------------------------------------------------------------------
/_build/data/transport.policytemplates.php:
--------------------------------------------------------------------------------
1 | newObject('modAccessPolicyTemplate');
12 | $templates['1']->fromArray(array(
13 | 'id' => 1,
14 | 'name' => 'FileAttachTemplate',
15 | 'description' => 'A policy template for attached files containers.',
16 | 'lexicon' => 'fileattach:permissions',
17 | 'template_group' => 1,
18 | ));
19 |
20 | $permissions = include dirname(__FILE__).'/permissions/fileattach.policy.php';
21 |
22 | if (is_array($permissions)) {
23 | $templates['1']->addMany($permissions);
24 | } else {
25 | $modx->log(modX::LOG_LEVEL_ERROR,'Could not load FileAttach Policy Template.');
26 | }
27 |
28 | return $templates;
--------------------------------------------------------------------------------
/_build/data/transport.settings.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'key' => 'fileattach.mediasource',
8 | 'name' => 'setting_fileattach.mediasource',
9 | 'description' => 'setting_fileattach.mediasource_desc',
10 | 'xtype' => 'modx-combo-source',
11 | 'lexicon' => 'fileattach:setting',
12 | 'area' => 'file',
13 | 'value' => 1
14 | ),
15 | 'files_path' => array(
16 | 'key' => 'fileattach.files_path',
17 | 'name' => 'setting_fileattach.files_path',
18 | 'description' => 'setting_fileattach.files_path_desc',
19 | 'xtype' => 'textfield',
20 | 'lexicon' => 'fileattach:setting',
21 | 'area' => 'file',
22 | 'value' => '/'
23 | ),
24 | 'templates' => array(
25 | 'key' => 'fileattach.templates',
26 | 'name' => 'setting_fileattach.templates',
27 | 'description' => 'setting_fileattach.templates_desc',
28 | 'xtype' => 'textfield',
29 | 'lexicon' => 'fileattach:setting',
30 | 'value' => ''
31 | ),
32 | 'user_folders' => array(
33 | 'key' => 'fileattach.user_folders',
34 | 'name' => 'setting_fileattach.user_folders',
35 | 'description' => 'setting_fileattach.user_folders_desc',
36 | 'xtype' => 'combo-boolean',
37 | 'lexicon' => 'fileattach:setting',
38 | 'area' => 'file',
39 | 'value' => false
40 | ),
41 | 'calchash' => array(
42 | 'key' => 'fileattach.calchash',
43 | 'name' => 'setting_fileattach.calchash',
44 | 'description' => 'setting_fileattach.calchash_desc',
45 | 'xtype' => 'combo-boolean',
46 | 'lexicon' => 'fileattach:setting',
47 | 'value' => false
48 | ),
49 | 'put_docid' => array(
50 | 'key' => 'fileattach.put_docid',
51 | 'name' => 'setting_fileattach.put_docid',
52 | 'description' => 'setting_fileattach.put_docid_desc',
53 | 'xtype' => 'combo-boolean',
54 | 'lexicon' => 'fileattach:setting',
55 | 'area' => 'file',
56 | 'value' => false
57 | ),
58 | 'private' => array(
59 | 'key' => 'fileattach.private',
60 | 'name' => 'setting_fileattach.private',
61 | 'description' => 'setting_fileattach.private_desc',
62 | 'xtype' => 'combo-boolean',
63 | 'lexicon' => 'fileattach:setting',
64 | 'area' => 'file',
65 | 'value' => false
66 | ),
67 | 'download' => array(
68 | 'key' => 'fileattach.download',
69 | 'name' => 'setting_fileattach.download',
70 | 'description' => 'setting_fileattach.download_desc',
71 | 'xtype' => 'combo-boolean',
72 | 'lexicon' => 'fileattach:setting',
73 | 'value' => true
74 | ),
75 | 'translit' => array(
76 | 'key' => 'fileattach.translit',
77 | 'name' => 'setting_fileattach.translit',
78 | 'description' => 'setting_fileattach.translit_desc',
79 | 'xtype' => 'combo-boolean',
80 | 'lexicon' => 'fileattach:setting',
81 | 'value' => false
82 | ),
83 | );
84 |
85 | foreach ($tmp as $k => $v) {
86 | /* @var modSystemSetting $setting */
87 | $setting = $modx->newObject('modSystemSetting');
88 | $setting->fromArray(array_merge(
89 | array(
90 | 'key' => 'fileattach.' . $k,
91 | 'namespace' => PKG_NAME_LOWER,
92 | ), $v
93 | ), '', true, true);
94 |
95 | $settings[] = $setting;
96 | }
97 |
98 | unset($tmp);
99 | return $settings;
100 |
--------------------------------------------------------------------------------
/_build/data/transport.snippets.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'file' => 'fileattach',
8 | 'description' => '',
9 | ),
10 | 'FileLink' => array(
11 | 'file' => 'filelink',
12 | 'description' => '',
13 | ),
14 | );
15 |
16 | foreach ($tmp as $k => $v) {
17 | /* @avr modSnippet $snippet */
18 | $snippet = $modx->newObject('modSnippet');
19 | $snippet->fromArray(array(
20 | 'id' => 0,
21 | 'name' => $k,
22 | 'description' => @$v['description'],
23 | 'snippet' => getSnippetContent($sources['source_core'] . '/elements/snippets/snippet.' . $v['file'] . '.php'),
24 | 'static' => BUILD_SNIPPET_STATIC,
25 | 'source' => 1,
26 | 'static_file' => 'core/components/' . PKG_NAME_LOWER . '/elements/snippets/snippet.' . $v['file'] . '.php',
27 | ), '', true, true);
28 |
29 | $properties = include $sources['build'] . 'properties/properties.' . $v['file'] . '.php';
30 | $snippet->setProperties($properties);
31 |
32 | $snippets[] = $snippet;
33 | }
34 |
35 | unset($tmp, $properties);
36 | return $snippets;
--------------------------------------------------------------------------------
/_build/includes/functions.php:
--------------------------------------------------------------------------------
1 | '));
13 | }
14 |
15 |
16 | /**
17 | * Recursive directory remove
18 | *
19 | * @param $dir
20 | */
21 | function rrmdir($dir) {
22 | if (is_dir($dir)) {
23 | $objects = scandir($dir);
24 |
25 | foreach ($objects as $object) {
26 | if ($object != '.' && $object != '..') {
27 | if (filetype($dir . '/' . $object) == 'dir') {
28 | rrmdir($dir . '/' . $object);
29 | } else {
30 | unlink($dir . '/' . $object);
31 | }
32 | }
33 | }
34 |
35 | reset($objects);
36 | rmdir($dir);
37 | }
38 | }
--------------------------------------------------------------------------------
/_build/properties/properties.fileattach.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'type' => 'textfield',
8 | 'value' => 'FileAttachTpl',
9 | ),
10 | 'sortBy' => array(
11 | 'type' => 'textfield',
12 | 'value' => 'name',
13 | ),
14 | 'sortDir' => array(
15 | 'type' => 'list',
16 | 'options' => array(
17 | array('text' => 'ASC', 'value' => 'ASC'),
18 | array('text' => 'DESC', 'value' => 'DESC'),
19 | ),
20 | 'value' => 'ASC'
21 | ),
22 | 'inline' => array(
23 | 'type' => 'combo-boolean',
24 | 'value' => false,
25 | ),
26 | 'limit' => array(
27 | 'type' => 'numberfield',
28 | 'value' => 0,
29 | ),
30 | 'offset' => array(
31 | 'type' => 'numberfield',
32 | 'value' => 0,
33 | ),
34 | 'totalVar' => array(
35 | 'type' => 'textfield',
36 | 'value' => 'total',
37 | ),
38 | 'outputSeparator' => array(
39 | 'type' => 'textfield',
40 | 'value' => "\n",
41 | ),
42 | 'toPlaceholder' => array(
43 | 'type' => 'combo-boolean',
44 | 'value' => false,
45 | ),
46 | 'resource' => array(
47 | 'type' => 'numberfield',
48 | 'value' => 0,
49 | ),
50 | 'makeUrl' => array(
51 | 'type' => 'combo-boolean',
52 | 'value' => true,
53 | ),
54 | 'privateUrl' => array(
55 | 'type' => 'combo-boolean',
56 | 'value' => false,
57 | ),
58 | 'showHASH' => array(
59 | 'type' => 'combo-boolean',
60 | 'value' => false,
61 | ),
62 | 'showSize' => array(
63 | 'type' => 'combo-boolean',
64 | 'value' => false,
65 | ),
66 | 'showExt' => array(
67 | 'type' => 'combo-boolean',
68 | 'value' => false,
69 | ),
70 | 'groups' => array(
71 | 'type' => 'textfield',
72 | 'value' => '',
73 | ),
74 | );
75 |
76 | foreach ($tmp as $k => $v) {
77 | $properties[] = array_merge(
78 | array(
79 | 'name' => $k,
80 | 'desc' => PKG_NAME_LOWER . '.prop_' . $k,
81 | 'lexicon' => PKG_NAME_LOWER . ':properties',
82 | ), $v
83 | );
84 | }
85 |
86 | return $properties;
--------------------------------------------------------------------------------
/_build/properties/properties.filelink.php:
--------------------------------------------------------------------------------
1 | array(
7 | 'type' => 'numberfield',
8 | 'value' => 0,
9 | ),
10 | 'groups' => array(
11 | 'type' => 'textfield',
12 | 'value' => '',
13 | ),
14 | );
15 |
16 | foreach ($tmp as $k => $v) {
17 | $properties[] = array_merge(
18 | array(
19 | 'name' => $k,
20 | 'desc' => PKG_NAME_LOWER . '.prop_' . $k,
21 | 'lexicon' => PKG_NAME_LOWER . ':properties',
22 | ), $v
23 | );
24 | }
25 |
26 | return $properties;
--------------------------------------------------------------------------------
/_build/resolvers/resolve.chunks.php:
--------------------------------------------------------------------------------
1 | xpdo) {
4 | /** @var modX $modx */
5 | $modx =& $object->xpdo;
6 |
7 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
8 | case xPDOTransport::ACTION_INSTALL:
9 | break;
10 |
11 | case xPDOTransport::ACTION_UPGRADE:
12 | if (!empty($options['chunks']) && !empty($options['update_chunks'])) {
13 | foreach ($options['update_chunks'] as $v) {
14 | if (!empty($options['chunks'][$v]) && $chunk = $modx->getObject('modChunk', array('name' => $v))) {
15 | $chunk->set('snippet', $options['chunks'][$v]);
16 | $chunk->save();
17 | $modx->log(modX::LOG_LEVEL_INFO, 'Updated chunk "' . $v . '"');
18 | }
19 | }
20 | }
21 | break;
22 |
23 | case xPDOTransport::ACTION_UNINSTALL:
24 | break;
25 | }
26 | }
27 |
28 | return true;
--------------------------------------------------------------------------------
/_build/resolvers/resolve.policy.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, a simple commenting component for MODx Revolution.
8 | *
9 | * FileAttach is free software; you can redistribute it and/or modify it under the
10 | * terms of the GNU General Public License as published by the Free Software
11 | * Foundation; either version 2 of the License, or (at your option) any later
12 | * version.
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package fileattach
23 | */
24 | /**
25 | * Auto-assign the FileAttachPolicy to the Administrator User Group
26 | *
27 | * @package fileattach
28 | * @subpackage build
29 | */
30 | if ($object->xpdo) {
31 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
32 | case xPDOTransport::ACTION_INSTALL:
33 | case xPDOTransport::ACTION_UPGRADE:
34 | $modx =& $object->xpdo;
35 | $modelPath = $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/') . 'model/';
36 | $modx->addPackage('fileattach', $modelPath);
37 |
38 | $modx->setLogLevel(modX::LOG_LEVEL_ERROR);
39 |
40 | /* assign policy to template */
41 | $template = $transport->xpdo->getObject('modAccessPolicyTemplate', array('name' => 'FileAttachTemplate'));
42 | if (!$template)
43 | $modx->log(xPDO::LOG_LEVEL_ERROR,'[FileAttach] Could not find FileAttacTemplate Access Policy Template!');
44 |
45 | $policyList = array('File Attach', 'File Attach Download', 'File Attach Frontend');
46 |
47 | foreach ($policyList as $policyName) {
48 | $policy = $transport->xpdo->getObject('modAccessPolicy', array('name' => $policyName));
49 |
50 | if ($policy) {
51 | $policy->set('template', $template->get('id'));
52 | $policy->save();
53 | } else
54 | $modx->log(xPDO::LOG_LEVEL_ERROR,'[FileAttach] Could not find ' . $policyName . ' Access Policy!');
55 | }
56 |
57 | /* assign policy to admin group */
58 | $policy = $modx->getObject('modAccessPolicy', array('name' => 'File Attach'));
59 |
60 | $adminGroup = $modx->getObject('modUserGroup', array('name' => 'Administrator'));
61 | if ($policy && $adminGroup) {
62 | $access = $modx->getObject('modAccessContext', array(
63 | 'target' => 'mgr',
64 | 'principal_class' => 'modUserGroup',
65 | 'principal' => $adminGroup->get('id'),
66 | 'authority' => 9999,
67 | 'policy' => $policy->get('id'),
68 | ));
69 | if (!$access) {
70 | $access = $modx->newObject('modAccessContext');
71 | $access->fromArray(array(
72 | 'target' => 'mgr',
73 | 'principal_class' => 'modUserGroup',
74 | 'principal' => $adminGroup->get('id'),
75 | 'authority' => 9999,
76 | 'policy' => $policy->get('id'),
77 | ));
78 | $access->save();
79 | }
80 | }
81 |
82 | /* assign policy to anonymous group */
83 | if (isset($options['allow_anonymous'])) {
84 | $policy = $modx->getObject('modAccessPolicy', array('name' => 'File Attach Download'));
85 |
86 | $access = $modx->getObject('modAccessContext', array(
87 | 'target' => 'web',
88 | 'principal_class' => 'modUserGroup',
89 | 'principal' => 0,
90 | 'authority' => 9999,
91 | 'policy' => $policy->get('id'),
92 | ));
93 | if (!$access) {
94 | $access = $modx->newObject('modAccessContext');
95 | $access->fromArray(array(
96 | 'target' => 'web',
97 | 'principal_class' => 'modUserGroup',
98 | 'principal' => 0,
99 | 'authority' => 9999,
100 | 'policy' => $policy->get('id'),
101 | ));
102 | $access->save();
103 | }
104 | }
105 |
106 | $modx->setLogLevel(modX::LOG_LEVEL_INFO);
107 | break;
108 | }
109 | }
110 |
111 | return true;
--------------------------------------------------------------------------------
/_build/resolvers/resolve.setup.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation; either version 2 of the License, or (at your option) any later
13 | * version.
14 | *
15 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
16 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU General Public License along with
20 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
21 | * Suite 330, Boston, MA 02111-1307 USA
22 | *
23 | * @package fileattach
24 | */
25 |
26 | $success = false;
27 |
28 | if ($object->xpdo) {
29 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
30 | case xPDOTransport::ACTION_UPGRADE:
31 | if (!isset($options['install_pack'])) {
32 | $modx =& $object->xpdo;
33 | if ($modx instanceof modX)
34 | $modx->removeExtensionPackage('fileattach');
35 | }
36 |
37 | case xPDOTransport::ACTION_INSTALL:
38 | if (isset($options['install_pack'])) {
39 | /** @var modX $modx */
40 | $modx =& $object->xpdo;
41 | $modelPath = $modx->getOption('fileattach.core_path');
42 | if (empty($modelPath))
43 | $modelPath = '[[++core_path]]components/fileattach/';
44 |
45 | $modelPath = rtrim($modelPath, '/') . '/model/';
46 | if ($modx instanceof modX)
47 | $modx->addExtensionPackage('fileattach', $modelPath);
48 | }
49 |
50 | $success = true;
51 | break;
52 | case xPDOTransport::ACTION_UNINSTALL:
53 | $modx =& $object->xpdo;
54 | if ($modx instanceof modX)
55 | $modx->removeExtensionPackage('fileattach');
56 |
57 | $success = true;
58 | break;
59 | }
60 | }
61 |
62 | return $success;
--------------------------------------------------------------------------------
/_build/resolvers/resolve.tables.php:
--------------------------------------------------------------------------------
1 | xpdo) {
4 | /** @var modX $modx */
5 | $modx =& $object->xpdo;
6 |
7 | $modelPath = $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/') . 'model/';
8 | $modx->addPackage('fileattach', $modelPath);
9 | $manager = $modx->getManager();
10 |
11 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
12 | case xPDOTransport::ACTION_INSTALL:
13 | // Create tables
14 | $objects = array(
15 | 'FileItem', 'FileAttachMediaSource'
16 | );
17 | foreach ($objects as $tmp) {
18 | $manager->createObjectContainer($tmp);
19 | }
20 | break;
21 |
22 | case xPDOTransport::ACTION_UPGRADE:
23 | // Upgrade DB scheme if there were older packages installed
24 | // Find latest installed version
25 |
26 | $c = $modx->newQuery('modTransportPackage');
27 | $c->select(array('version_major', 'version_minor', 'version_patch'));
28 | $c->where(array(
29 | 'package_name' => 'FileAttach',
30 | 'installed:IS NOT' => NULL
31 | ));
32 | $c->sortby('version_major', 'DESC');
33 | $c->sortby('version_minor', 'DESC');
34 | $c->sortby('version_patch', 'DESC');
35 |
36 | $package = $modx->getObject('modTransportPackage', $c);
37 | if ($package) {
38 | $oldLogLevel = $modx->getLogLevel();
39 | $modx->setLogLevel(0);
40 |
41 | $version =
42 | $package->get('version_major') * 1000 +
43 | $package->get('version_minor') * 100 +
44 | $package->get('version_patch');
45 |
46 | // Update tables
47 | if ($version < 1002)
48 | $manager->addField('FileItem', 'rank', array('after' => 'uid'));
49 |
50 | if ($version < 1007) {
51 | $manager->addField('FileItem', 'fid', array('after' => 'id'));
52 | $manager->addIndex('FileItem', 'fid');
53 | }
54 |
55 | if ($version < 1011) {
56 | $manager->addField('FileItem', 'tag', array('after' => 'hash'));
57 | $manager->alterField('FileItem', 'hash');
58 | }
59 |
60 | $modx->setLogLevel($oldLogLevel);
61 | }
62 |
63 | // Find old records with empty file ID
64 | $needID = $modx->getCollection('FileItem', array('fid' => ''));
65 | foreach ($needID as $item) {
66 | $item->set('fid', $item->generateName());
67 | $item->save();
68 | }
69 |
70 | break;
71 |
72 | case xPDOTransport::ACTION_UNINSTALL:
73 | break;
74 | }
75 | }
76 |
77 | return true;
--------------------------------------------------------------------------------
/_build/setup.options.php:
--------------------------------------------------------------------------------
1 | getOption('extension_packages');
7 | if ($value) {
8 | $exts = $modx->fromJSON($value);
9 | foreach ($exts as $idx => $extPack) {
10 | foreach ($extPack as $key => $opt) {
11 | if ($key == 'fileattach') {
12 | $installed = true;
13 | break;
14 | }
15 | }
16 | }
17 | }
18 |
19 | // Check if anonymous policy is installed
20 | $access = NULL;
21 |
22 | $policy = $modx->getObject('modAccessPolicy', array('name' => 'File Attach Download'));
23 | if ($policy) {
24 | $access = $modx->getObject('modAccessContext', array(
25 | 'target' => 'web',
26 | 'principal_class' => 'modUserGroup',
27 | 'principal' => 0,
28 | 'authority' => 9999,
29 | 'policy' => $policy->get('id')
30 | ));
31 | }
32 |
33 | switch ($options[xPDOTransport::PACKAGE_ACTION]) {
34 | case xPDOTransport::ACTION_INSTALL:
35 | case xPDOTransport::ACTION_UPGRADE:
36 | if ($modx->getOption('manager_language') == 'ru') {
37 | $output = '
38 | Позволяет использовать файловый медиа источник
';
39 |
40 | $output .= ($access)?
41 | 'Анонимным пользователям разрешено скачивание' :
42 | '';
43 | } else {
44 | $output = '
45 | This will allow to use media file source
';
46 |
47 | $output .= ($access)?
48 | 'Anonymous users downloading allowed' :
49 | '';
50 | }
51 |
52 | case xPDOTransport::ACTION_UNINSTALL:
53 | break;
54 | }
55 |
56 | return $output;
57 |
--------------------------------------------------------------------------------
/assets/components/fileattach/connector.php:
--------------------------------------------------------------------------------
1 | getService('fileattach', 'FileAttach', $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/') . 'model/fileattach/');
11 | $modx->lexicon->load('fileattach:default');
12 |
13 | $key = $modx->context->get('key');
14 | if ($modx->user->hasSessionContext($key))
15 | $_SERVER['HTTP_MODAUTH'] = $_SESSION["modx.$key.user.token"];
16 | else {
17 | define('MODX_REQP', false);
18 | $_SERVER['HTTP_MODAUTH'] = 0;
19 | }
20 |
21 | // handle request
22 | $corePath = $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/');
23 | $path = $modx->getOption('processorsPath', $FileAttach->config, $corePath . 'processors/');
24 | $modx->request->handleRequest(array(
25 | 'processors_path' => $path,
26 | 'location' => '',
27 | ));
--------------------------------------------------------------------------------
/assets/components/fileattach/js/mgr/fileattach.js:
--------------------------------------------------------------------------------
1 | var FileAttach = function (config) {
2 | config = config || {};
3 | FileAttach.superclass.constructor.call(this, config);
4 | };
5 | Ext.extend(FileAttach, Ext.Component, {
6 | page: {}, window: {}, grid: {}, panel: {}, config: {}, utils: {}
7 | });
8 | Ext.reg('fileattach', FileAttach);
9 |
10 | FileAttach = new FileAttach();
--------------------------------------------------------------------------------
/assets/components/fileattach/js/mgr/filestab.js:
--------------------------------------------------------------------------------
1 | Ext.onReady(function () {
2 | var mainPanel = Ext.getCmp("modx-panel-resource");
3 | if (!mainPanel) return;
4 |
5 | if (mainPanel.config.record.id > 0) {
6 | FileAttach.config.docid = mainPanel.config.record.id;
7 |
8 | MODx.addTab("modx-resource-tabs", {
9 | title: _("files"),
10 | id: "files-tab",
11 | width: "95%",
12 | items: [{
13 | xtype: "fileattach-grid-items",
14 | width: "95%"
15 | }]
16 | });
17 | }
18 | });
19 |
--------------------------------------------------------------------------------
/assets/components/fileattach/js/mgr/widgets/home.panel.js:
--------------------------------------------------------------------------------
1 | FileAttach.page.Home = function (config) {
2 | config = config || {};
3 | Ext.applyIf(config, {
4 | components: [{
5 | xtype: 'fileattach-panel-home', renderTo: 'fileattach-panel-home-div'
6 | }]
7 | });
8 | FileAttach.page.Home.superclass.constructor.call(this, config);
9 | };
10 | Ext.extend(FileAttach.page.Home, MODx.Component);
11 | Ext.reg('fileattach-page-home', FileAttach.page.Home);
12 |
13 | FileAttach.panel.Home = function (config) {
14 | config = config || {};
15 | Ext.apply(config, {
16 | baseCls: 'modx-formpanel',
17 | layout: 'anchor',
18 | hideMode: 'offsets',
19 | style: {padding: '20px 15px'},
20 | items: [{
21 | html: '' + _('fileattach') + '
',
22 | cls: 'modx-page-header',
23 | border: false,
24 | }, {
25 | layout: 'anchor',
26 | items: [{
27 | html: _('fileattach.intro_msg'),
28 | cls: 'panel-desc',
29 | }, {
30 | xtype: 'fileattach-grid-items',
31 | cls: 'main-wrapper',
32 | }]
33 | }]
34 | });
35 | FileAttach.panel.Home.superclass.constructor.call(this, config);
36 | };
37 | Ext.extend(FileAttach.panel.Home, MODx.Panel);
38 | Ext.reg('fileattach-panel-home', FileAttach.panel.Home);
39 |
--------------------------------------------------------------------------------
/assets/components/fileattach/js/mgr/widgets/items.grid.js:
--------------------------------------------------------------------------------
1 | // Helper boolean render
2 | FileAttach.utils.renderBoolean = function (value, props, row) {
3 | return value
4 | ? String.format('{0}', _('yes'))
5 | : String.format('{0}', _('no'));
6 | }
7 |
8 | // Helper title render
9 | FileAttach.utils.renderName = function (value, props, row) {
10 | return value +
11 | ((row.data['description'])? '
' +
12 | row.data['description'] + '' : '');
13 | }
14 |
15 | FileAttach.window.UpdateItem = function (config) {
16 | config = config || {};
17 | if (!config.id) {
18 | config.id = 'fileattach-item-window-update';
19 | }
20 | Ext.applyIf(config, {
21 | title: _('update'),
22 | width: 550,
23 | autoHeight: true,
24 | url: FileAttach.config.connectorUrl,
25 | action: 'mgr/update',
26 | fields: this.getFields(config),
27 | keys: [{
28 | key: Ext.EventObject.ENTER, shift: true, fn: function () {
29 | this.submit()
30 | }, scope: this}]
31 | });
32 |
33 | FileAttach.window.UpdateItem.superclass.constructor.call(this, config);
34 | }
35 |
36 | Ext.extend(FileAttach.window.UpdateItem, MODx.Window, {
37 | calcHash: function (btn, e, row) {
38 | btn.hide();
39 | MODx.Ajax.request({
40 | url: this.config.url,
41 | params: {
42 | action: 'mgr/hash',
43 | id: this.config.record.object.id
44 | },
45 | listeners: {
46 | success: {
47 | fn: function (r) {
48 | Ext.getCmp(this.config.id + '-hash').setValue(r.object.hash);
49 | Ext.getCmp(this.config.id + '-hash').show();
50 | }, scope: this},
51 | fail: { fn: function () { btn.show(); }, scope: this }
52 | }
53 | });
54 | },
55 |
56 | getFields: function (config) {
57 | var fields = [{
58 | xtype: 'hidden',
59 | name: 'id',
60 | id: config.id + '-id',
61 | }, {
62 | xtype: 'textfield',
63 | fieldLabel: _('name'),
64 | name: 'name',
65 | id: config.id + '-name',
66 | anchor: '100%',
67 | allowBlank: false
68 | }, {
69 | xtype: 'textfield',
70 | fieldLabel: _('description'),
71 | name: 'description',
72 | id: config.id + '-description',
73 | anchor: '100%',
74 | }, {
75 | xtype: 'textfield',
76 | fieldLabel: _('fileattach.tag'),
77 | id: config.id + '-tag',
78 | name: 'tag',
79 | anchor: '100%'
80 | }, {
81 | xtype: 'statictextfield',
82 | fieldLabel: _('fileattach.hash'),
83 | id: config.id + '-hash',
84 | name: 'hash',
85 | hidden: (config.record.object.hash == ''),
86 | anchor: '100%'
87 | }, {
88 | xtype: 'statictextfield',
89 | fieldLabel: _('fileattach.fid'),
90 | name: 'fid',
91 | id: config.id + '-fid',
92 | anchor: '100%',
93 | }];
94 |
95 | if (config.record.object.hash == '')
96 | fields.push([{
97 | xtype: 'button',
98 | text: _('fileattach.calculate'),
99 | style: 'margin-top: 15px;',
100 | handler: this.calcHash,
101 | scope: this
102 | }]);
103 |
104 | fields.push([{
105 | xtype: 'xcheckbox',
106 | id: config.id + '-private',
107 | boxLabel: _('private'),
108 | hideLabel: true,
109 | name: 'private'
110 | }]);
111 |
112 | if (FileAttach.config.docid > 0)
113 | fields.push({xtype: 'hidden', name: 'docid', id: config.id + '-docid'});
114 | else {
115 | fields.unshift({
116 | xtype: 'modx-combo',
117 | id: config.id + '-docid',
118 | fieldLabel: _('resource'),
119 | name: 'docid',
120 | hiddenName: 'docid',
121 | url: FileAttach.config.connectorUrl,
122 | baseParams: {
123 | action: 'mgr/searchres'
124 | },
125 | fields: ['id','pagetitle','description'],
126 | displayField: 'pagetitle',
127 | anchor: '100%',
128 | pageSize: 10,
129 | editable: true,
130 | typeAhead: true,
131 | allowBlank: false,
132 | forceSelection: true,
133 | tpl: new Ext.XTemplate('{pagetitle}',
134 | '
{description}', '
')
135 | });
136 | }
137 |
138 | return fields;
139 | }
140 | });
141 | Ext.reg('fileattach-item-window-update', FileAttach.window.UpdateItem);
142 |
143 | FileAttach.grid.Items = function (config) {
144 | config = config || {};
145 | if (!config.id) {
146 | config.id = 'fileattach-grid-items';
147 | }
148 | this.sm = new Ext.grid.CheckboxSelectionModel();
149 | Ext.applyIf(config, {
150 | url: FileAttach.config.connectorUrl,
151 | fields: this.getFields(config),
152 | columns: this.getColumns(config),
153 | ddText: _('fileattach.ddtext'),
154 | tbar: this.getTopBar(config),
155 | sm: this.sm,
156 | baseParams: {
157 | action: 'mgr/getlist',
158 | docid: FileAttach.config.docid
159 | },
160 | listeners: {
161 | rowDblClick: function (grid, rowIndex, e) {
162 | var row = grid.store.getAt(rowIndex);
163 | this.updateItem(grid, e, row);
164 | },
165 | sortchange: this.saveSort
166 | },
167 | viewConfig: {
168 | forceFit: true,
169 | enableRowBody: true,
170 | autoFill: true,
171 | showPreview: true,
172 | scrollOffset: 0
173 | },
174 | paging: true,
175 | remoteSort: true,
176 | autoHeight: true,
177 | });
178 |
179 | // Enable D&D only in resource editor
180 | if (FileAttach.config.docid)
181 | Ext.applyIf(config, {
182 | plugins: [new Ext.ux.dd.GridDragDropRowOrder({
183 | copy: false,
184 | scrollable: true,
185 | targetCfg: {},
186 | listeners: {
187 | 'afterrowmove': {fn:this.onAfterRowMove, scope:this}
188 | }
189 | })]
190 | });
191 |
192 | // Restore sort state
193 | var sortInfo = [];
194 | if (sortInfo = this.restoreSort()) {
195 | // Workaround for absence of sortInfo support
196 | config.baseParams.sort = sortInfo[0];
197 | config.baseParams.dir = sortInfo[1];
198 |
199 | config.sortBy = sortInfo[0];
200 | config.sortDir = sortInfo[1];
201 | }
202 |
203 | FileAttach.grid.Items.superclass.constructor.call(this, config);
204 |
205 | // Set sort arrow
206 | if (sortInfo.length > 0)
207 | this.store.setDefaultSort(sortInfo[0], sortInfo[1]);
208 |
209 | this.restoreColumn();
210 | this.colModel.on('hiddenchange', this.saveColumn, this);
211 |
212 | // Clear selection on grid refresh
213 | this.store.on('load', function () {
214 | if (this._getSelectedIds().length) {
215 | this.getSelectionModel().clearSelections();
216 | }
217 | }, this);
218 | }
219 | Ext.extend(FileAttach.grid.Items, MODx.grid.Grid, {
220 | windows: {},
221 |
222 | // Item context menu
223 | getMenu: function (grid, rowIndex) {
224 | var menu = [
225 | {handler: grid['downloadItem'], text: _('file_download')},
226 | {handler: grid['updateItem'], text: _('update')},
227 | {handler: grid['resetItem'], text: _('reset')},
228 | '-',
229 | {handler: grid['removeItem'], text: _('remove')}
230 | ];
231 |
232 | this.addContextMenuItem(menu);
233 | },
234 |
235 | // Restore sort info to session storage
236 | restoreSort: function () {
237 | if (typeof(Storage) !== "undefined") {
238 | var sortInfo = sessionStorage.getItem('fa_sort' + ((FileAttach.config.docid > 0)? '_' + FileAttach.config.docid : ''));
239 | return (sortInfo)? sortInfo.split('|', 2) : false;
240 | }
241 |
242 | return false;
243 | },
244 |
245 | // Save sort info to session storage
246 | saveSort: function (grid, sortInfo) {
247 | if (typeof(Storage) !== "undefined") {
248 | sessionStorage.setItem('fa_sort' + ((FileAttach.config.docid > 0)? '_' + FileAttach.config.docid : ''),
249 | sortInfo.field + "|" + sortInfo.direction);
250 | }
251 | },
252 |
253 | // Restore column info from session storage
254 | restoreColumn: function () {
255 | if (typeof(Storage) !== "undefined") {
256 | var colInfo = sessionStorage.getItem('fa_col' + ((FileAttach.config.docid > 0)? '_' + FileAttach.config.docid : ''));
257 | if (colInfo != null) {
258 | var cols = colInfo.split(',');
259 | for (var i = 0; i < cols.length; i++)
260 | this.colModel.setHidden(i + 1, cols[i] == '0');
261 | }
262 | }
263 | },
264 |
265 | // Save column visibility to session storage
266 | saveColumn: function(colModel, colIndex, hidden) {
267 | if (typeof(Storage) !== "undefined") {
268 | var count = colModel.getColumnCount(false);
269 | var cols = [];
270 | for (var i = 1; i < count; i++) cols.push(colModel.isHidden(i)? 0 : 1);
271 |
272 | sessionStorage.setItem('fa_col' + ((FileAttach.config.docid > 0)? '_' + FileAttach.config.docid : ''),
273 | cols.join(','));
274 | }
275 | },
276 |
277 | // Edit item
278 | updateItem: function (btn, e, row) {
279 | if (typeof(row) != 'undefined') {
280 | this.menu.record = row.data;
281 | }
282 | else if (!this.menu.record) {
283 | return false;
284 | }
285 | var id = this.menu.record.id;
286 |
287 | MODx.Ajax.request({
288 | url: this.config.url,
289 | params: {
290 | action: 'mgr/get',
291 | docid: FileAttach.config.docid,
292 | id: id
293 | },
294 | listeners: {
295 | success: {
296 | fn: function (r) {
297 | var w = MODx.load({
298 | xtype: 'fileattach-item-window-update',
299 | id: Ext.id(),
300 | record: r,
301 | listeners: {
302 | success: { fn: function () { this.refresh(); }, scope: this }
303 | }
304 | });
305 | w.reset();
306 | w.setValues(r.object);
307 | w.show(e.target);
308 | }, scope: this
309 | }
310 | }
311 | });
312 | },
313 |
314 | // Edit item access
315 | accessItem: function (act, btn, e) {
316 | var ids = this._getSelectedIds();
317 | if (!ids.length) {
318 | return false;
319 | }
320 |
321 | MODx.Ajax.request({
322 | url: this.config.url,
323 | params: {
324 | action: 'mgr/access',
325 | private: (act.name == 'close')? 1:0,
326 | ids: Ext.util.JSON.encode(ids),
327 | },
328 | listeners: {
329 | success: { fn: function (r) { this.refresh(); }, scope: this },
330 | failure: {fn: function (r) {}, scope: this}
331 | }
332 | });
333 |
334 | return true;
335 | },
336 |
337 | // Reset download count
338 | resetItem: function (act, btn, e) {
339 | var ids = this._getSelectedIds();
340 | if (!ids.length) {
341 | return false;
342 | }
343 | MODx.msg.confirm({
344 | title: ids.length > 1
345 | ? _('reset')
346 | : _('reset'),
347 | text: ids.length > 1
348 | ? _('fileattach.resets_confirm')
349 | : _('fileattach.reset_confirm'),
350 | url: this.config.url,
351 | params: {
352 | action: 'mgr/reset',
353 | ids: Ext.util.JSON.encode(ids),
354 | },
355 | listeners: {
356 | success: {
357 | fn: function (r) {
358 | this.refresh();
359 | }, scope: this
360 | }
361 | }
362 | });
363 | return true;
364 | },
365 |
366 | // Remove item
367 | removeItem: function (act, btn, e) {
368 | var ids = this._getSelectedIds();
369 | if (!ids.length) {
370 | return false;
371 | }
372 | MODx.msg.confirm({
373 | title: ids.length > 1
374 | ? _('remove')
375 | : _('remove'),
376 | text: ids.length > 1
377 | ? _('confirm_remove')
378 | : _('confirm_remove'),
379 | url: this.config.url,
380 | params: {
381 | action: 'mgr/remove',
382 | ids: Ext.util.JSON.encode(ids)
383 | },
384 | listeners: {
385 | success: {
386 | fn: function (r) {
387 | this.refresh();
388 | }, scope: this
389 | }
390 | }
391 | });
392 | return true;
393 | },
394 |
395 | // Download file
396 | downloadItem: function (act, btn, e) {
397 | var item = this._getSelected();
398 |
399 | var filePath = MODx.config['fileattach.files_path'] + item['path'] + item['internal_name'];
400 |
401 | MODx.Ajax.request({
402 | url: MODx.config.connector_url,
403 | params: {
404 | action: 'browser/file/download',
405 | file: filePath,
406 | wctx: MODx.ctx || '',
407 | source: MODx.config['fileattach.mediasource']
408 | },
409 | listeners: {
410 | 'success': { fn: function(r) {
411 | if (!Ext.isEmpty(r.object.url)) {
412 | location.href = MODx.config.connector_url +
413 | '?action=browser/file/download&download=1&file=' +
414 | filePath + '&HTTP_MODAUTH=' + MODx.siteId +
415 | '&source=' + MODx.config['fileattach.mediasource'] + '&wctx=' + MODx.ctx;
416 | }
417 | }, scope:this }
418 | }
419 | });
420 |
421 | return true;
422 | },
423 |
424 | // Show uploader dialog
425 | uploadFiles: function(btn,e) {
426 | if (!this.uploader) {
427 | aVer = MODx.config.version.split('.');
428 | uploaddialog = ((aVer[0] == 2) && aVer[1] >= 3)? MODx.util.MultiUploadDialog.Dialog : Ext.ux.UploadDialog.Dialog;
429 |
430 | this.uploader = new uploaddialog({
431 | title: _('upload'),
432 | url: this.config.url,
433 | base_params: {
434 | action: 'mgr/upload',
435 | docid: FileAttach.config.docid
436 | },
437 | cls: 'ext-ux-uploaddialog-dialog modx-upload-window'
438 | });
439 | this.uploader.on('hide', this.refresh,this);
440 | this.uploader.on('close', this.refresh,this);
441 | }
442 |
443 | // Automatically open picker
444 | this.uploader.show(btn);
445 | this.uploader.buttons[0].input_file.dom.click();
446 | },
447 |
448 | // Define visible fields
449 | getFields: function (config) {
450 | return ['id', 'name', 'description', 'docid', 'download', 'private', 'pagetitle', 'username', 'rank', 'tag'];
451 | },
452 |
453 | // Define columns
454 | getColumns: function (config) {
455 | var columns = [this.sm, {
456 | header: _('fileattach.rank'),
457 | dataIndex: 'rank',
458 | hidden: true,
459 | sortable: FileAttach.config.docid > 0,
460 | width: 50
461 | }, {
462 | header: _('id'),
463 | dataIndex: 'id',
464 | sortable: true,
465 | width: 50
466 | }, {
467 | header: _('name'),
468 | dataIndex: 'name',
469 | sortable: true,
470 | width: 200,
471 | renderer: FileAttach.utils.renderName
472 | }, {
473 | header: _('fileattach.downloads'),
474 | dataIndex: 'download',
475 | width: 50,
476 | sortable: true,
477 | }, {
478 | header: _('private'),
479 | dataIndex: 'private',
480 | width: 50,
481 | sortable: true,
482 | renderer: FileAttach.utils.renderBoolean
483 | }, {
484 | header: _('tag'),
485 | dataIndex: 'tag',
486 | width: 50,
487 | hidden: true,
488 | sortable: true
489 | }];
490 |
491 | if (!FileAttach.config.docid)
492 | columns.push({
493 | header: _('resource'),
494 | dataIndex: 'pagetitle',
495 | sortable: true
496 | }, {
497 | header: _('user'),
498 | dataIndex: 'username',
499 | sortable: true
500 | });
501 |
502 | return columns;
503 | },
504 |
505 | // Form top bar
506 | getTopBar: function (config) {
507 | var fields = [];
508 |
509 | if (FileAttach.config.docid)
510 | fields.push({
511 | xtype: 'button',
512 | cls: 'primary-button',
513 | text: _('upload'),
514 | handler: this.uploadFiles,
515 | scope: this
516 | });
517 |
518 | fields.push({
519 | xtype: 'splitbutton',
520 | text: _('remove'),
521 | menu: [{
522 | name: 'open',
523 | text: _('fileattach.open'),
524 | handler: this.accessItem,
525 | scope: this
526 | }, {
527 | name: 'close',
528 | text: _('fileattach.private'),
529 | handler: this.accessItem,
530 | scope: this
531 | }, '-', {
532 | text: _('fileattach.reset'),
533 | handler: this.resetItem,
534 | scope: this
535 | }, {
536 | text: _('remove'),
537 | handler: this.removeItem,
538 | scope: this
539 | }],
540 | text: _('bulk_actions')
541 | }, '->', {
542 | xtype: 'textfield',
543 | name: 'uid',
544 | width: 200,
545 | id: config.id + '-search-uid-field',
546 | emptyText: _('user'),
547 | listeners: {
548 | render: {
549 | fn: function (tf) {
550 | tf.getEl().addKeyListener(Ext.EventObject.ENTER,
551 | function () { this._doSearch(tf); }, this);
552 | }, scope: this
553 | }
554 | }
555 | }, {
556 | xtype: 'textfield',
557 | name: 'query',
558 | width: 200,
559 | id: config.id + '-search-field',
560 | emptyText: _('search'),
561 | listeners: {
562 | render: {
563 | fn: function (tf) {
564 | tf.getEl().addKeyListener(Ext.EventObject.ENTER,
565 | function () { this._doSearch(tf); }, this);
566 | }, scope: this
567 | }
568 | }
569 | }, {
570 | xtype: 'button',
571 | id: config.id + '-search-clear',
572 | text: '',
573 | listeners: {
574 | click: {fn: this._clearSearch, scope: this}
575 | }
576 | });
577 |
578 | return fields;
579 | },
580 |
581 | // Header button handler
582 | onClick: function (e) {
583 | var elem = e.getTarget();
584 | if (elem.nodeName == 'BUTTON') {
585 | var row = this.getSelectionModel().getSelected();
586 | if (typeof(row) != 'undefined') {
587 | var action = elem.getAttribute('action');
588 | if (action == 'showMenu') {
589 | var ri = this.getStore().find('id', row.id);
590 | return this._showMenu(this, ri, e);
591 | }
592 | else if (typeof this[action] === 'function') {
593 | this.menu.record = row.data;
594 | return this[action](this, e);
595 | }
596 | }
597 | }
598 | return this.processEvent('click', e);
599 | },
600 |
601 | // Get first selected record
602 | _getSelected: function () {
603 | var selected = this.getSelectionModel().getSelections();
604 |
605 | for (var i in selected) {
606 | if (!selected.hasOwnProperty(i)) continue;
607 | return selected[i].json;
608 | }
609 |
610 | return null;
611 | },
612 |
613 | // Get list of selected ID
614 | _getSelectedIds: function () {
615 | var ids = [];
616 | var selected = this.getSelectionModel().getSelections();
617 |
618 | for (var i in selected) {
619 | if (!selected.hasOwnProperty(i)) continue;
620 | ids.push(selected[i]['id']);
621 | }
622 |
623 | return ids;
624 | },
625 |
626 | // Perform store update with search query
627 | _doSearch: function (tf, nv, ov) {
628 | if (tf.name == 'query')
629 | this.getStore().baseParams.query = tf.getValue();
630 |
631 | if (tf.name == 'uid')
632 | this.getStore().baseParams.uid = tf.getValue();
633 | this.getBottomToolbar().changePage(1);
634 | this.refresh();
635 | },
636 |
637 | // Reset search query
638 | _clearSearch: function (btn, e) {
639 | this.getStore().baseParams.query = '';
640 | this.getStore().baseParams.uid = '';
641 | Ext.getCmp(this.config.id + '-search-uid-field').setValue('');
642 | Ext.getCmp(this.config.id + '-search-field').setValue('');
643 | this.getBottomToolbar().changePage(1);
644 | this.refresh();
645 | },
646 |
647 | // Handle changing item order with dragging
648 | onAfterRowMove: function(dt,sri,ri,sels) {
649 | var s = this.getStore();
650 | var sourceRec = s.getAt(sri);
651 | var belowRec = s.getAt(ri);
652 | var total = s.getTotalCount();
653 | var upd = {};
654 |
655 | sourceRec.set('rank', sri);
656 | sourceRec.commit();
657 | upd[sourceRec.get('id')] = sri;
658 |
659 | var brec;
660 | for (var x = (ri - 1); x < total; x++) {
661 | brec = s.getAt(x);
662 | if (brec) {
663 | brec.set('rank', x);
664 | brec.commit();
665 | upd[brec.get('id')] = x;
666 | }
667 | }
668 |
669 | MODx.Ajax.request({
670 | url: this.config.url,
671 | params: {
672 | action: 'mgr/rank',
673 | rank: Ext.util.JSON.encode(upd),
674 | }
675 | });
676 |
677 | return true;
678 | }
679 | });
680 | Ext.reg('fileattach-grid-items', FileAttach.grid.Items);
--------------------------------------------------------------------------------
/core/components/fileattach/controllers/list.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Class FileattachManageManagerController
27 | */
28 | class FileattachListManagerController extends modExtraManagerController {
29 | /** @var FileAttach $FileAttach */
30 | public $FileAttach;
31 |
32 |
33 | /**
34 | * @return void
35 | */
36 | public function initialize() {
37 | $corePath = $this->modx->getOption('fileattach.core_path', null, $this->modx->getOption('core_path') . 'components/fileattach/');
38 | require_once $corePath . 'model/fileattach/fileattach.class.php';
39 |
40 | $this->FileAttach = new FileAttach($this->modx);
41 | $this->addJavascript($this->FileAttach->config['jsUrl'] . 'mgr/fileattach.js');
42 | $this->addHtml('');
45 |
46 | parent::initialize();
47 | }
48 |
49 |
50 | /**
51 | * @return void
52 | */
53 | public function loadCustomCssJs() {
54 | $this->addJavascript($this->FileAttach->config['jsUrl'] . 'mgr/widgets/items.grid.js');
55 | $this->addJavascript($this->FileAttach->config['jsUrl'] . 'mgr/widgets/home.panel.js');
56 | $this->addHtml('');
61 | }
62 |
63 |
64 | /**
65 | * @return null|string
66 | */
67 | public function getPageTitle() {
68 | return $this->modx->lexicon('fileattach');
69 | }
70 |
71 |
72 | /**
73 | * @return array
74 | */
75 | public function getLanguageTopics() {
76 | return array('fileattach:default');
77 | }
78 |
79 |
80 | /**
81 | * @return string
82 | */
83 | public function getTemplateFile() {
84 | return $this->FileAttach->config['templatesPath'] . 'home.tpl';
85 | }
86 |
87 |
88 | /**
89 | * @return bool
90 | */
91 | public function checkPermissions() { return true; }
92 | }
93 |
--------------------------------------------------------------------------------
/core/components/fileattach/docs/changelog.txt:
--------------------------------------------------------------------------------
1 | Changelog for FileAttach.
2 |
3 | 1.0.11pl
4 | ==============
5 | - Fix/update media source
6 | - Add tag support
7 | - Add extension filter
8 |
9 | 1.0.10pl4
10 | ==============
11 | - Add internal file translit support
12 | - Configuration keys put to file category
13 |
14 | 1.0.10pl3
15 | ==============
16 | - Make menu router-based, enhances compatibility with 2.3+
17 |
18 | 1.0.10pl2
19 | ==============
20 | - Add file download in manager
21 |
22 | 1.0.10pl1
23 | ==============
24 | - Add support for pagination with new options: totalVar, offset
25 |
26 | 1.0.10
27 | ==============
28 | - Add system event 'faOnRemove'
29 | - Reformat table view
30 | - Remove unneeded JS objects
31 | - Fix typos, update doc URLs
32 |
33 | 1.0.9
34 | ==============
35 | - Compatibility with MODx >=2.5.2
36 | - Fix MediaSource error with MySQL 5.7 ONLY_FULL_GROUP_BY SQL Mode
37 | - Add download range support, download continuation
38 |
39 | 1.0.8 pl1
40 | ==============
41 | - Remember column sort state in session
42 | - Remember column visibility in session
43 | - Make rank column sortable in resource editor
44 | - Fix button captions / localization
45 | - Reformat code
46 |
47 | 1.0.8
48 | ==============
49 | - Fix margins in panels
50 | - Optimize plugin
51 | - Code cleanup and reformat
52 |
53 | 1.0.7 pl1
54 | ==============
55 | - Add file cleanup on resource removal
56 | - Optimize download processor performance
57 |
58 | 1.0.7
59 | ==============
60 | - Now files are available by unique string file ID
61 | - Add ability to restrict link list access with groups
62 | - Automatically open picker after upload button is clicked
63 |
64 | 1.0.6
65 | ==============
66 | - Add frontend processors
67 | - Add new policy for frontend uploader
68 | - Following system upload file type list
69 | - Don't double save on update
70 |
71 | 1.0.5 pl1
72 | ==============
73 | - Add ability to use extension placeholder
74 |
75 | 1.0.5
76 | ==============
77 | - Add ability to allow anonymous download
78 | - Fix snippet arguments typo
79 |
80 | 1.0.4
81 | ==============
82 | - DB scheme enhance
83 | - Add SQLSrv support
84 |
85 | 1.0.3
86 | ==============
87 | - Add compatibility with MODx v2.2
88 | - Snippet fix config loading
89 | - Enhance media source:
90 | - Extension distinction
91 | - Display thumbnails
92 |
93 | 1.0.2
94 | ==============
95 | - Add download option
96 | - Add rank field in model
97 | - Add ability to manually rearrange order
98 |
99 | 1.0.1
100 | ==============
101 | - Add ability to hash file if it didn't at upload
102 | - Add showSize option to snippet
103 | - Rewritten download processor
104 | - Updated FileItem model
105 | - Add filter for templates in document lister
106 | - UI editor rearrange
107 |
108 | 1.0.0
109 | ==============
110 | - Initial release
111 |
--------------------------------------------------------------------------------
/core/components/fileattach/docs/license.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, June 2007
3 |
4 | Read full version at:
5 | http://www.gnu.org/licenses/gpl-3.0.en.html
6 |
--------------------------------------------------------------------------------
/core/components/fileattach/docs/readme.txt:
--------------------------------------------------------------------------------
1 | --------------------
2 | FileAttach
3 | --------------------
4 | Author: Vitaly Chekryzhev <13hakta@gmail.com>
5 | --------------------
6 |
7 | File attach/upload tool for MODx Revolution.
8 |
9 | Feel free to suggest ideas/improvements/bugs on GitHub:
10 | http://github.com/13hakta/FileAttach/issues
11 |
12 | Official docs:
13 | http://13hakta.ru/blog/fileattach-en.html (English)
14 | http://13hakta.ru/blog/fileattach.html (Russian)
15 |
--------------------------------------------------------------------------------
/core/components/fileattach/elements/chunks/chunk.item.tpl:
--------------------------------------------------------------------------------
1 | [[+description:notempty=`[[+description]]
`]]
2 | [[+name]] [[+download]]
3 | [[+size:notempty=`
Size: [[+size]] bytes`]]
4 | [[+ext:notempty=`
Type:
`]]
5 | [[+timestamp:notempty=`
Date: [[+timestamp:date=`%d.%m.%Y %H:%M`]]`]]
6 | [[+hash:notempty=`
SHA1: [[+hash]]`]]
7 |
--------------------------------------------------------------------------------
/core/components/fileattach/elements/plugins/plugin.filestab.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | switch ($modx->event->name) {
26 | // Add a custom tab to the MODX create/edit resource pages
27 | case 'OnDocFormPrerender':
28 |
29 | // Check access
30 | if (!$modx->hasPermission('fileattach.doclist')) return;
31 |
32 | // Skip form building when resource template is not in permitted list
33 | $templates = $modx->getOption('fileattach.templates');
34 |
35 | if ($templates != '') {
36 | $templatelist = explode(',', $templates);
37 | $template = is_object($resource)? $resource->get('template') : 0;
38 | if (!in_array($template, $templatelist)) return;
39 | }
40 |
41 | $modx->controller->addLexiconTopic('fileattach:default');
42 |
43 | $corePath = $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/');
44 | require_once $corePath . 'model/fileattach/fileattach.class.php';
45 |
46 | $modx->FileAttach = new FileAttach($modx);
47 | $modx->controller->addJavascript($modx->FileAttach->config['jsUrl'] . 'mgr/fileattach.js');
48 | $modx->controller->addJavascript($modx->FileAttach->config['jsUrl'] . 'mgr/widgets/items.grid.js');
49 | $modx->controller->addLastJavascript($modx->FileAttach->config['jsUrl'] . 'mgr/filestab.js');
50 | $modx->controller->addHtml('');
51 |
52 | break;
53 |
54 | // Remove attached files to resources
55 | case 'OnEmptyTrash':
56 | // Load service
57 | if (!$FileAttach = $modx->getService('fileattach', 'FileAttach',
58 | $modx->getOption('fileattach.core_path',
59 | null,
60 | $modx->getOption('core_path') . 'components/fileattach/') . 'model/fileattach/')) {
61 | $modx->log(xPDO::LOG_LEVEL_ERROR, 'Could not load FileAttach class OnEmptyTrash!');
62 | return;
63 | }
64 |
65 | foreach ($ids as &$id) {
66 | $c = $modx->newQuery('FileItem');
67 | $c->where(array('docid' => $id));
68 |
69 | $iter = $modx->getIterator('FileItem', $c);
70 | foreach ($iter as $item) $item->remove();
71 | }
72 |
73 | break;
74 | }
--------------------------------------------------------------------------------
/core/components/fileattach/elements/snippets/snippet.fileattach.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /** @var array $scriptProperties */
26 | /** @var FileAttach $FileAttach */
27 | if (!$FileAttach = $modx->getService('fileattach', 'FileAttach', $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/') . 'model/fileattach/', $scriptProperties)) {
28 | return 'Could not load FileAttach class!';
29 | }
30 |
31 | // Get script options
32 | $tpl = $modx->getOption('tpl', $scriptProperties, 'FileItemTpl');
33 | $sortby = $modx->getOption('sortBy', $scriptProperties, 'name');
34 | $sortdir = $modx->getOption('sortDir', $scriptProperties, 'ASC');
35 | $inline = $modx->getOption('inline', $scriptProperties, false);
36 | $limit = $modx->getOption('limit', $scriptProperties, 0);
37 | $outputSeparator = $modx->getOption('outputSeparator', $scriptProperties, "\n");
38 | $toPlaceholder = $modx->getOption('toPlaceholder', $scriptProperties, false);
39 | $resource = $modx->getOption('resource', $scriptProperties, 0);
40 | $makeUrl = $modx->getOption('makeUrl', $scriptProperties, true);
41 | $privateUrl = $modx->getOption('privateUrl', $scriptProperties, false);
42 | $showHASH = $modx->getOption('showHASH', $scriptProperties, false);
43 | $showSize = $modx->getOption('showSize', $scriptProperties, false);
44 | $showExt = $modx->getOption('showExt', $scriptProperties, false);
45 | $showTime = $modx->getOption('showTime', $scriptProperties, false);
46 | $ext = $modx->getOption('ext', $scriptProperties, '');
47 | $tag = $modx->getOption('tag', $scriptProperties, '');
48 | $groups = $modx->getOption('groups', $scriptProperties, '');
49 |
50 | $offset = $modx->getOption('offset', $scriptProperties, 0);
51 | $totalVar = $modx->getOption('totalVar', $scriptProperties, 'total');
52 |
53 | // Check access
54 | if ($groups != '') {
55 | // Forbid access for non-authorized visitor
56 | if (empty($modx->user)) return;
57 |
58 | $accessGroups = explode(',', $groups);
59 |
60 | // Argument set erroneously
61 | if (empty($accessGroups)) return;
62 |
63 | $accessGroups = array_map('trim', $accessGroups);
64 |
65 | if (!$modx->user->isMember($accessGroups)) return;
66 | }
67 |
68 | if ($makeUrl) {
69 | if (!$privateUrl || $showSize) {
70 | // Get base URLs
71 | $mediaSource = $modx->getOption('fileattach.mediasource', null, 1);
72 |
73 | $ms = $modx->getObject('sources.modMediaSource', array('id' => $mediaSource));
74 | $ms->initialize();
75 |
76 | $files_path = $modx->getOption('fileattach.files_path');
77 | $public_url = $ms->getBaseUrl() . $files_path;
78 | $docs_path = $ms->getBasePath() . $files_path;
79 | }
80 |
81 | $private_url = $modx->getOption('fileattach.assets_url', null, $modx->getOption('assets_url')) . 'components/fileattach/';
82 | $private_url .= 'connector.php?action=web/download&ctx=' . $modx->context->key;
83 |
84 | if ($inline)
85 | $private_url .= '&inline=1';
86 |
87 | $private_url .= '&fid=';
88 | }
89 |
90 | // Build query
91 | $c = $modx->newQuery('FileItem');
92 |
93 | if ($showHASH)
94 | $c->select($modx->getSelectColumns('FileItem', 'FileItem'));
95 | else
96 | $c->select($modx->getSelectColumns('FileItem', 'FileItem', '', array('hash'), true));
97 |
98 | $c->where(array('docid' => ($resource > 0)? $resource : $modx->resource->get('id')));
99 |
100 | if ($tag != '')
101 | $c->where(array('tag' => $tag));
102 |
103 | if (!empty($limit)) {
104 | $total = $modx->getCount('FileItem', $c);
105 | $modx->setPlaceholder($totalVar, $total);
106 | }
107 |
108 | if (!empty($limit)) $c->limit($limit, $offset);
109 | $c->sortby($sortby, $sortdir);
110 |
111 | $items = $modx->getIterator('FileItem', $c);
112 |
113 | // Iterate through items
114 | $list = array();
115 | /** @var FileItem $item */
116 | foreach ($items as $item) {
117 | $item->source = $ms;
118 | $item->files_path = $files_path;
119 |
120 | $itemArr = $item->toArray();
121 |
122 | if ($makeUrl) {
123 | if ($itemArr['private'] || $privateUrl)
124 | $itemArr['url'] = $private_url . $itemArr['fid'];
125 | else
126 | $itemArr['url'] = $public_url . $itemArr['path'] . $itemArr['name'];
127 | }
128 |
129 | if ($showSize)
130 | $itemArr['size'] = $item->getSize();
131 |
132 | if ($showTime)
133 | $itemArr['timestamp'] = filectime($item->getFullPath());
134 |
135 | if ($showExt) {
136 | $itemArr['ext'] = strtolower(
137 | pathinfo($itemArr['name'], PATHINFO_EXTENSION));
138 |
139 | if (($ext != '') && ($ext != $itemArr['ext'])) continue;
140 | }
141 |
142 | $list[] = $modx->getChunk($tpl, $itemArr);
143 | }
144 |
145 | // Output
146 | $output = implode($outputSeparator, $list);
147 | if (!empty($toPlaceholder)) {
148 | // If using a placeholder, output nothing and set output to specified placeholder
149 | $modx->setPlaceholder($toPlaceholder, $output);
150 |
151 | return '';
152 | }
153 |
154 | return $output;
155 |
--------------------------------------------------------------------------------
/core/components/fileattach/elements/snippets/snippet.filelink.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /** @var array $scriptProperties */
26 | /** @var FileAttach $FileAttach */
27 | if (!$FileAttach = $modx->getService('fileattach', 'FileAttach', $modx->getOption('fileattach.core_path', null, $modx->getOption('core_path') . 'components/fileattach/') . 'model/fileattach/', $scriptProperties)) {
28 | return 'Could not load FileAttach class!';
29 | }
30 |
31 | // Get script options
32 | $fid = $modx->getOption('fid', $scriptProperties, 0);
33 | $groups = $modx->getOption('groups', $scriptProperties, '');
34 |
35 | // Check access
36 | if ($groups != '') {
37 | // Forbid access for non-authorized visitor
38 | if (empty($modx->user)) return;
39 |
40 | $accessGroups = explode(',', $groups);
41 |
42 | // Argument set erroneously
43 | if (empty($accessGroups)) return;
44 |
45 | $accessGroups = array_map('trim', $accessGroups);
46 |
47 | if (!$modx->user->isMember($accessGroups)) return;
48 | }
49 |
50 | // Build query
51 | $item = $modx->getObject('FileItem', array('id' => $fid, 'docid' => $modx->resource->get('id')));
52 |
53 | $itemArr = $item->toArray();
54 |
55 | if ($itemArr['private']) {
56 | $private_url = $modx->getOption('fileattach.assets_url', null, $modx->getOption('assets_url')) .
57 | 'components/fileattach/connector.php?action=web/download&ctx=' .
58 | $modx->context->key . '&inline=1&fid=';
59 |
60 | $itemArr['url'] = $private_url . $itemArr['fid'];
61 | } else
62 | $itemArr['url'] = $public_url . $itemArr['path'] . $itemArr['name'];
63 |
64 | return $itemArr['url'];
65 |
--------------------------------------------------------------------------------
/core/components/fileattach/elements/templates/home.tpl:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/core/components/fileattach/lexicon/en/default.inc.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * The base class for FileAttach.
27 | */
28 | class FileAttach {
29 | /* @var modX $modx */
30 | public $modx;
31 |
32 | /**
33 | * @param modX $modx
34 | * @param array $config
35 | */
36 | function __construct(modX &$modx, array $config = array()) {
37 | $this->modx =& $modx;
38 |
39 | $corePath = $this->modx->getOption('fileattach.core_path', $config, $this->modx->getOption('core_path') . 'components/fileattach/');
40 | $assetsUrl = $this->modx->getOption('fileattach.assets_url', $config, $this->modx->getOption('assets_url') . 'components/fileattach/');
41 | $connectorUrl = $assetsUrl . 'connector.php';
42 |
43 | $this->config = array_merge(array(
44 | 'assetsUrl' => $assetsUrl,
45 | 'jsUrl' => $assetsUrl . 'js/',
46 | 'connectorUrl' => $connectorUrl,
47 |
48 | 'corePath' => $corePath,
49 | 'modelPath' => $corePath . 'model/',
50 | 'chunksPath' => $corePath . 'elements/chunks/',
51 | 'templatesPath' => $corePath . 'elements/templates/',
52 | 'chunkSuffix' => '.chunk.tpl',
53 | 'snippetsPath' => $corePath . 'elements/snippets/',
54 | 'processorsPath' => $corePath . 'processors/'
55 | ), $config);
56 |
57 | $this->modx->addPackage('fileattach', $this->config['modelPath']);
58 | $this->modx->lexicon->load('fileattach:default');
59 | }
60 | }
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/fileattachmediasource.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | class FileAttachMediaSource extends modMediaSource implements modMediaSourceInterface {
26 | /** @var FileAttach $fileattach */
27 | public $fileattach;
28 |
29 | /** @var string $files_path */
30 | private $files_path;
31 |
32 | /** @var int $parentSourceID */
33 | private $parentSourceID;
34 |
35 |
36 | /**
37 | * Initialize the source, preparing it for usage.
38 | *
39 | * @return boolean
40 | */
41 | public function initialize() {
42 | $this->fileattach = $this->xpdo->getService('fileattach', 'FileAttach', $this->xpdo->getOption('fileattach.core_path', null, $this->xpdo->getOption('core_path') . 'components/fileattach/') . 'model/fileattach/');
43 | if (!($this->fileattach instanceof FileAttach))
44 | return false;
45 |
46 | $this->parentSourceID = $this->xpdo->getOption('fileattach.mediasource', null, 1);
47 | $this->files_path = $this->xpdo->getOption('fileattach.files_path');
48 |
49 | $this->xpdo->lexicon->load('fileattach:default', 'fileattach:source');
50 |
51 | return true;
52 | }
53 |
54 |
55 | /**
56 | * Return an array of containers at this current level in the container structure. Used for the tree
57 | * navigation on the files tree.
58 | *
59 | * @param string $path
60 | * @return array
61 | */
62 | public function getContainerList($path) {
63 | $properties = $this->getPropertyList();
64 | $list = array();
65 |
66 | if ($path == '/') {
67 | $c = $this->xpdo->newQuery('modResource');
68 |
69 | $c->select('modResource.id,modResource.pagetitle');
70 | $c->rightJoin('FileItem', 'FileItem', 'modResource.id=FileItem.docid');
71 | $c->sortby('modResource.pagetitle', 'ASC');
72 | $c->groupby('modResource.id');
73 |
74 | $resources = $this->xpdo->getCollection('modResource', $c);
75 | /** @var modResource $resource */
76 | foreach ($resources as $resource) {
77 | $list[] = array(
78 | 'id' => $resource->get('id'),
79 | 'text' => $resource->get('pagetitle') . ' (' . $resource->get('id') . ')',
80 | 'iconCls' => 'icon icon-folder',
81 | 'leaf' => false
82 | );
83 | }
84 |
85 | return $list;
86 | } else {
87 | $id = (int)$path;
88 |
89 | /* get items */
90 | $c = $this->xpdo->newQuery('FileItem');
91 | $c->sortby('name', 'ASC');
92 | $c->where(array('docid' => $id));
93 |
94 | $items = $this->xpdo->getCollection('FileItem', $c);
95 |
96 | $t_description = $this->xpdo->lexicon('description');
97 | $t_download = $this->xpdo->lexicon('fileattach.downloads');
98 | $t_size = $this->xpdo->lexicon('fileattach.size');
99 | $t_hash = $this->xpdo->lexicon('fileattach.hash');
100 |
101 | /** @var FileItem $item */
102 | foreach ($items as $item) {
103 | $ext = strtolower(pathinfo($item->get('internal_name'), PATHINFO_EXTENSION));
104 |
105 | $tip = $t_description . ': ' . $item->get('description') . '
' .
106 | $t_download . ': ' . $item->get('download') . '
' .
107 | $t_size . ': ' . $item->getSize() . '
' .
108 | $t_hash . ': ' . $item->get('hash');
109 |
110 | $list[] = array(
111 | 'id' => $item->get('id'),
112 | 'text' => $item->get('name'),
113 | 'iconCls' => 'icon icon-file icon-' . $ext . (($item->get('private'))? ' icon-access' : ''),
114 | 'qtip' => $tip,
115 | 'leaf' => true
116 | );
117 | }
118 |
119 | return $list;
120 | }
121 | }
122 |
123 |
124 | /**
125 | * Return a detailed list of objects in a specific path. Used for thumbnails in the Browser.
126 | *
127 | * @param string $path
128 | * @return array
129 | */
130 | public function getObjectsInContainer($path) {
131 | // Initialize config
132 | $properties = $this->getPropertyList();
133 | $list = array();
134 |
135 | $modAuth = $this->xpdo->user->getUserToken($this->xpdo->context->get('key'));
136 |
137 | $thumbnailType = $this->getOption('thumbnailType', $properties, 'png');
138 | $thumbnailQuality = $this->getOption('thumbnailQuality', $properties, 90);
139 | $thumbWidth = $this->xpdo->context->getOption('filemanager_thumb_width', 100);
140 | $thumbHeight = $this->xpdo->context->getOption('filemanager_thumb_height', 80);
141 | $imageWidth = $this->ctx->getOption('filemanager_image_width', 800);
142 | $imageHeight = $this->ctx->getOption('filemanager_image_height', 600);
143 |
144 | $thumb_default = $this->xpdo->context->getOption('manager_url', MODX_MANAGER_URL) . 'templates/default/images/restyle/nopreview.jpg';
145 | $thumbUrl = $this->xpdo->context->getOption('connectors_url', MODX_CONNECTORS_URL) . 'system/phpthumb.php?';
146 |
147 | $imagesExts = $this->getOption('imageExtensions', $properties, 'jpg,jpeg,png,gif');
148 | $imagesExts = explode(',', $imagesExts);
149 |
150 | if ($path != '/') {
151 | $thumb = $this->ctx->getOption('manager_url', MODX_MANAGER_URL).'templates/default/images/restyle/nopreview.jpg';
152 |
153 | $id = (int)$path;
154 |
155 | /* get items */
156 | $c = $this->xpdo->newQuery('FileItem');
157 | $c->sortby('name', 'ASC');
158 | $c->where(array('docid' => $id));
159 |
160 | $items = $this->xpdo->getCollection('FileItem', $c);
161 |
162 | /** @var FileItem $item */
163 | foreach ($items as $item) {
164 | $ext = strtolower(pathinfo($item->get('internal_name'), PATHINFO_EXTENSION));
165 |
166 | $listItem = array(
167 | 'id' => $item->get('id'),
168 | 'name' => $item->get('name'),
169 | 'ext' => $ext,
170 | 'type' => 'file',
171 | 'size' => $item->getSize(),
172 | 'thumb' => $thumb,
173 | 'leaf' => true,
174 | 'perms' => '',
175 | 'thumb_width' => $thumbWidth,
176 | 'thumb_height' => $thumbHeight,
177 | 'disabled' => false
178 | );
179 |
180 | if (in_array($ext, $imagesExts)) {
181 | /* get thumbnail */
182 | $preview = 1;
183 |
184 | /* generate thumb/image URLs */
185 | $thumbQuery = http_build_query(array(
186 | 'src' => $item->getPath(),
187 | 'w' => $thumbWidth,
188 | 'h' => $thumbHeight,
189 | 'f' => $thumbnailType,
190 | 'q' => $thumbnailQuality,
191 | 'far' => 'C',
192 | 'HTTP_MODAUTH' => $modAuth,
193 | 'wctx' => $this->xpdo->context->get('key'),
194 | 'source' => $this->parentSourceID
195 | ));
196 |
197 | $imageQuery = http_build_query(array(
198 | 'src' => $item->getPath(),
199 | 'w' => $imageWidth,
200 | 'h' => $imageHeight,
201 | 'f' => $thumbnailType,
202 | 'q' => $thumbnailQuality,
203 | 'far' => 'C',
204 | 'HTTP_MODAUTH' => $modAuth,
205 | 'wctx' => $this->xpdo->context->get('key'),
206 | 'source' => $this->parentSourceID
207 | ));
208 |
209 | $thumb = $thumbUrl . urldecode($thumbQuery);
210 |
211 | $listItem['image'] = $thumbUrl . urldecode($imageQuery);
212 | } else {
213 | $preview = 0;
214 | $thumb = $thumb_default;
215 | $listItem['image'] = $thumb;
216 | }
217 |
218 | $listItem['thumb'] = $thumb;
219 | $listItem['preview'] = $preview;
220 |
221 | $list[] = $listItem;
222 | }
223 | }
224 |
225 | return $list;
226 | }
227 |
228 |
229 | /**
230 | * Get the default properties for the filesystem media source type.
231 | *
232 | * @return array
233 | */
234 | public function getDefaultProperties() {
235 | return array(
236 | 'imageExtensions' => array(
237 | 'name' => 'imageExtensions',
238 | 'desc' => 'prop_file.imageExtensions_desc',
239 | 'type' => 'textfield',
240 | 'value' => 'jpg,jpeg,png,gif',
241 | 'lexicon' => 'core:source',
242 | ),
243 | 'thumbnailType' => array(
244 | 'name' => 'thumbnailType',
245 | 'desc' => 'prop_file.thumbnailType_desc',
246 | 'type' => 'list',
247 | 'options' => array(
248 | array('name' => 'PNG','value' => 'png'),
249 | array('name' => 'JPG','value' => 'jpg'),
250 | array('name' => 'GIF','value' => 'gif'),
251 | ),
252 | 'value' => 'png',
253 | 'lexicon' => 'core:source',
254 | ),
255 | 'thumbnailQuality' => array(
256 | 'name' => 'thumbnailQuality',
257 | 'desc' => 'prop_file.thumbnailQuality_desc',
258 | 'type' => 'textfield',
259 | 'options' => '',
260 | 'value' => 90,
261 | 'lexicon' => 'core:source',
262 | )
263 | );
264 | }
265 |
266 |
267 | /**
268 | * Prepare the source path for phpThumb
269 | *
270 | * @param string $src
271 | * @return string
272 | */
273 | public function prepareSrcForThumb($value) {
274 | return $this->getObjectUrl($value);
275 | }
276 |
277 |
278 | /**
279 | * Get the name of this source type
280 | * @return string
281 | */
282 | public function getTypeName() {
283 | $this->xpdo->lexicon->load('fileattach:source');
284 | return $this->xpdo->lexicon('fileattach.source_name');
285 | }
286 |
287 |
288 | /**
289 | * Get the description of this source type
290 | * @return string
291 | */
292 | public function getTypeDescription() {
293 | $this->xpdo->lexicon->load('fileattach:source');
294 | return $this->xpdo->lexicon('fileattach.source_desc');
295 | }
296 | }
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/fileitem.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | class FileItem extends xPDOSimpleObject {
26 | public $source = false;
27 | public $files_path = '';
28 |
29 |
30 | /**
31 | * Creates a FileItem instance
32 | *
33 | * {@inheritdoc}
34 | */
35 | function __construct(& $xpdo) {
36 | parent :: __construct($xpdo);
37 |
38 | $this->files_path = $this->xpdo->getOption('fileattach.files_path');
39 | }
40 |
41 |
42 | /**
43 | * Get the source, preparing it for usage.
44 | *
45 | * @return source
46 | */
47 | private function getMediaSource() {
48 | if ($this->source)
49 | return $this->source;
50 |
51 | //get modMediaSource
52 | $mediaSource = $this->xpdo->getOption('fileattach.mediasource', null, 1);
53 |
54 | $def = $this->xpdo->getObject('sources.modMediaSource', array('id' => $mediaSource));
55 | $def->initialize();
56 | $this->source = $def;
57 |
58 | return $this->source;
59 | }
60 |
61 |
62 | /**
63 | * Get object URL
64 | *
65 | * @return string
66 | */
67 | function getUrl() {
68 | $ms = $this->getMediaSource();
69 | return $ms->getBaseUrl() . $this->getPath();
70 | }
71 |
72 |
73 | /**
74 | * Get relative file path
75 | *
76 | * @return string
77 | */
78 | function getPath() {
79 | return $this->files_path . $this->get('path') . $this->get('internal_name');
80 | }
81 |
82 |
83 | /**
84 | * Get full file path in fs
85 | *
86 | * @return string
87 | */
88 | function getFullPath() {
89 | $ms = $this->getMediaSource();
90 | return $ms->getBasePath() . $this->getPath();
91 | }
92 |
93 |
94 | /**
95 | * Get file size
96 | *
97 | * @return int
98 | */
99 | function getSize() {
100 | $ms = $this->getMediaSource();
101 | $f = $ms->fileHandler->make($this->getFullPath(), array(), 'modFile');
102 | return $f->getSize();
103 | }
104 |
105 |
106 | /**
107 | * Rename file
108 | *
109 | * @param string $newname
110 | * @return boolean
111 | */
112 | function rename($newname) {
113 | $local_path = $this->files_path . $this->get('path');
114 |
115 | $ms = $this->getMediaSource();
116 |
117 | if ($ms->renameObject($local_path . $this->get('internal_name'), $newname)) {
118 | $this->set('name', $newname);
119 | $this->set('internal_name', $newname);
120 | } else
121 | return false;
122 |
123 | return true;
124 | }
125 |
126 |
127 | /**
128 | * Set privacy mode
129 | *
130 | * @param boolean $state
131 | * @return boolean
132 | */
133 | function setPrivate($state) {
134 | if ($this->get('private') == $state)
135 | return true;
136 |
137 | $ms = $this->getMediaSource();
138 |
139 | $local_path = $this->files_path . $this->get('path');
140 | $path = $ms->getBasePath() . $local_path;
141 |
142 | $ext = pathinfo($this->get('name'), PATHINFO_EXTENSION);
143 | $ext = strtolower($ext);
144 |
145 | // Generate name and check for existence
146 | if ($state)
147 | $filename = $this->generateName() . ".$ext";
148 | else
149 | $filename = $this->get('name');
150 |
151 | $fullpath = '';
152 |
153 | // Check intersection with existing
154 | while(1) {
155 | $f = $ms->fileHandler->make($path . '/' . $filename, array(), 'modFile');
156 | if (!$f->exists()) break;
157 |
158 | // Generate new name again
159 | if ($state)
160 | $filename = $this->generateName() . ".$ext";
161 | else
162 | $filename = $this->generateName(4) . '_' . $filename;
163 | }
164 |
165 | if ($ms->renameObject(
166 | $local_path . $this->get('internal_name'),
167 | $filename)) {
168 | $this->set('internal_name', $filename);
169 | $this->set('private', $state);
170 | $this->save();
171 |
172 | return true;
173 | } else
174 | $this->xpdo->log(xPDO::LOG_LEVEL_ERROR,'[FileAttach] An error occurred while trying to rename the attachment file at: ' . $filename);
175 |
176 | return false;
177 | }
178 |
179 |
180 | /**
181 | * Remove file
182 | */
183 | function removeFile() {
184 | $filename = $this->getPath();
185 |
186 | if (!empty($filename)) {
187 | $ms = $this->getMediaSource();
188 | if (!@$ms->removeObject($filename))
189 | $this->xpdo->log(xPDO::LOG_LEVEL_ERROR,'[FileAttach] An error occurred while trying to remove the attachment file at: ' . $filename);
190 | }
191 | }
192 |
193 |
194 | /**
195 | * Remove file and object
196 | *
197 | * @param array $ancestors
198 | */
199 | function remove(array $ancestors= array ()) {
200 | $this->removeFile();
201 |
202 | $this->xpdo->invokeEvent('faOnRemove', array(
203 | 'id' => $this->get('id'),
204 | 'object' => &$this)
205 | );
206 |
207 | return parent::remove($ancestors);
208 | }
209 |
210 |
211 | /* Generate Filename
212 | *
213 | * @param integer $length Length of generated sequence
214 | * @return string
215 | */
216 | static function generateName($length = 32) {
217 | $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_';
218 | $charactersLength = strlen($characters);
219 |
220 | $newname = '';
221 |
222 | for ($i = 0; $i < $length; $i++)
223 | $newname .= $characters[rand(0, $charactersLength - 1)];
224 |
225 | return $newname;
226 | }
227 |
228 |
229 | /* Sanitize Filename
230 | *
231 | * @param string $str Input file name
232 | * @return string
233 | */
234 | static function sanitizeName($str) {
235 | $bad = array(
236 | '../', '', '<', '>',
237 | "'", '"', '&', '$', '#',
238 | '{', '}', '[', ']', '=',
239 | ';', '?', '%20', '%22',
240 | '%3c', // <
241 | '%253c', // <
242 | '%3e', // >
243 | '%0e', // >
244 | '%28', // (
245 | '%29', // )
246 | '%2528', // (
247 | '%26', // &
248 | '%24', // $
249 | '%3f', // ?
250 | '%3b', // ;
251 | '%3d', // =
252 | '/', './', '\\'
253 | );
254 |
255 | return stripslashes(str_replace($bad, '', $str));
256 | }
257 | }
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/metadata.mysql.php:
--------------------------------------------------------------------------------
1 |
5 | array (
6 | 0 => 'FileItem',
7 | ),
8 | 'modMediaSource' =>
9 | array (
10 | 0 => 'FileAttachMediaSource',
11 | ),
12 | );
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/metadata.sqlsrv.php:
--------------------------------------------------------------------------------
1 |
5 | array (
6 | 0 => 'FileItem',
7 | ),
8 | 'modMediaSource' =>
9 | array (
10 | 0 => 'FileAttachMediaSource',
11 | ),
12 | );
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/mysql/fileattachmediasource.class.php:
--------------------------------------------------------------------------------
1 | 'fileattach',
4 | 'version' => '1.1',
5 | 'extends' => 'modMediaSource',
6 | 'tableMeta' =>
7 | array (
8 | 'engine' => 'MyISAM',
9 | ),
10 | 'fields' =>
11 | array (
12 | ),
13 | 'fieldMeta' =>
14 | array (
15 | ),
16 | );
17 |
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/mysql/fileitem.class.php:
--------------------------------------------------------------------------------
1 | 'fileattach',
4 | 'version' => '1.1',
5 | 'table' => 'files',
6 | 'extends' => 'xPDOSimpleObject',
7 | 'tableMeta' =>
8 | array (
9 | 'engine' => 'MyISAM',
10 | ),
11 | 'fields' =>
12 | array (
13 | 'fid' => '',
14 | 'name' => '',
15 | 'internal_name' => '',
16 | 'path' => '',
17 | 'description' => '',
18 | 'hash' => NULL,
19 | 'tag' => '',
20 | 'private' => 0,
21 | 'download' => 0,
22 | 'docid' => 0,
23 | 'uid' => 0,
24 | 'rank' => 0,
25 | ),
26 | 'fieldMeta' =>
27 | array (
28 | 'fid' =>
29 | array (
30 | 'dbtype' => 'varchar',
31 | 'precision' => '40',
32 | 'phptype' => 'string',
33 | 'null' => false,
34 | 'default' => '',
35 | ),
36 | 'name' =>
37 | array (
38 | 'dbtype' => 'varchar',
39 | 'precision' => '255',
40 | 'phptype' => 'string',
41 | 'null' => false,
42 | 'default' => '',
43 | ),
44 | 'internal_name' =>
45 | array (
46 | 'dbtype' => 'varchar',
47 | 'precision' => '255',
48 | 'phptype' => 'string',
49 | 'null' => false,
50 | 'default' => '',
51 | ),
52 | 'path' =>
53 | array (
54 | 'dbtype' => 'varchar',
55 | 'precision' => '100',
56 | 'phptype' => 'string',
57 | 'null' => false,
58 | 'default' => '',
59 | ),
60 | 'description' =>
61 | array (
62 | 'dbtype' => 'varchar',
63 | 'precision' => '255',
64 | 'phptype' => 'string',
65 | 'null' => false,
66 | 'default' => '',
67 | ),
68 | 'hash' =>
69 | array (
70 | 'dbtype' => 'varchar',
71 | 'precision' => '50',
72 | 'phptype' => 'string',
73 | 'null' => true,
74 | ),
75 | 'tag' =>
76 | array (
77 | 'dbtype' => 'varchar',
78 | 'precision' => '50',
79 | 'phptype' => 'string',
80 | 'null' => false,
81 | 'default' => '',
82 | ),
83 | 'private' =>
84 | array (
85 | 'dbtype' => 'tinyint',
86 | 'precision' => '1',
87 | 'phptype' => 'boolean',
88 | 'attributes' => 'unsigned',
89 | 'null' => false,
90 | 'default' => 0,
91 | ),
92 | 'download' =>
93 | array (
94 | 'dbtype' => 'int',
95 | 'precision' => '10',
96 | 'phptype' => 'integer',
97 | 'attributes' => 'unsigned',
98 | 'null' => false,
99 | 'default' => 0,
100 | ),
101 | 'docid' =>
102 | array (
103 | 'dbtype' => 'int',
104 | 'precision' => '10',
105 | 'phptype' => 'integer',
106 | 'null' => false,
107 | 'default' => 0,
108 | ),
109 | 'uid' =>
110 | array (
111 | 'dbtype' => 'int',
112 | 'precision' => '10',
113 | 'phptype' => 'integer',
114 | 'null' => false,
115 | 'default' => 0,
116 | ),
117 | 'rank' =>
118 | array (
119 | 'dbtype' => 'int',
120 | 'precision' => '10',
121 | 'phptype' => 'integer',
122 | 'attributes' => 'unsigned',
123 | 'null' => false,
124 | 'default' => 0,
125 | ),
126 | ),
127 | 'indexes' =>
128 | array (
129 | 'fid' =>
130 | array (
131 | 'alias' => 'fid',
132 | 'primary' => false,
133 | 'unique' => false,
134 | 'type' => 'BTREE',
135 | 'columns' =>
136 | array (
137 | 'fid' =>
138 | array (
139 | 'length' => '',
140 | 'collation' => 'A',
141 | 'null' => false,
142 | ),
143 | ),
144 | ),
145 | 'name' =>
146 | array (
147 | 'alias' => 'name',
148 | 'primary' => false,
149 | 'unique' => false,
150 | 'type' => 'BTREE',
151 | 'columns' =>
152 | array (
153 | 'name' =>
154 | array (
155 | 'length' => '',
156 | 'collation' => 'A',
157 | 'null' => false,
158 | ),
159 | ),
160 | ),
161 | 'docid' =>
162 | array (
163 | 'alias' => 'docid',
164 | 'primary' => false,
165 | 'unique' => false,
166 | 'type' => 'BTREE',
167 | 'columns' =>
168 | array (
169 | 'docid' =>
170 | array (
171 | 'length' => '',
172 | 'collation' => 'A',
173 | 'null' => false,
174 | ),
175 | ),
176 | ),
177 | 'uid' =>
178 | array (
179 | 'alias' => 'uid',
180 | 'primary' => false,
181 | 'unique' => false,
182 | 'type' => 'BTREE',
183 | 'columns' =>
184 | array (
185 | 'uid' =>
186 | array (
187 | 'length' => '',
188 | 'collation' => 'A',
189 | 'null' => false,
190 | ),
191 | ),
192 | ),
193 | ),
194 | 'aggregates' =>
195 | array (
196 | 'Document' =>
197 | array (
198 | 'class' => 'modResource',
199 | 'local' => 'docid',
200 | 'foreign' => 'id',
201 | 'cardinality' => 'one',
202 | 'owner' => 'foreign',
203 | ),
204 | ),
205 | );
206 |
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/sqlsrv/fileattachmediasource.class.php:
--------------------------------------------------------------------------------
1 | 'fileattach',
4 | 'version' => '1.1',
5 | 'extends' => 'modMediaSource',
6 | 'fields' =>
7 | array (
8 | ),
9 | 'fieldMeta' =>
10 | array (
11 | ),
12 | );
13 |
--------------------------------------------------------------------------------
/core/components/fileattach/model/fileattach/sqlsrv/fileitem.class.php:
--------------------------------------------------------------------------------
1 | 'fileattach',
4 | 'version' => '1.1',
5 | 'table' => 'files',
6 | 'extends' => 'xPDOSimpleObject',
7 | 'fields' =>
8 | array (
9 | 'fid' => '',
10 | 'name' => '',
11 | 'internal_name' => '',
12 | 'path' => '',
13 | 'description' => '',
14 | 'hash' => NULL,
15 | 'tag' => '',
16 | 'private' => 0,
17 | 'download' => 0,
18 | 'docid' => 0,
19 | 'uid' => 0,
20 | 'rank' => 0,
21 | ),
22 | 'fieldMeta' =>
23 | array (
24 | 'fid' =>
25 | array (
26 | 'dbtype' => 'nvarchar',
27 | 'precision' => '40',
28 | 'phptype' => 'string',
29 | 'null' => false,
30 | 'default' => '',
31 | ),
32 | 'name' =>
33 | array (
34 | 'dbtype' => 'nvarchar',
35 | 'precision' => '255',
36 | 'phptype' => 'string',
37 | 'null' => false,
38 | 'default' => '',
39 | ),
40 | 'internal_name' =>
41 | array (
42 | 'dbtype' => 'nvarchar',
43 | 'precision' => '255',
44 | 'phptype' => 'string',
45 | 'null' => false,
46 | 'default' => '',
47 | ),
48 | 'path' =>
49 | array (
50 | 'dbtype' => 'nvarchar',
51 | 'precision' => '100',
52 | 'phptype' => 'string',
53 | 'null' => false,
54 | 'default' => '',
55 | ),
56 | 'description' =>
57 | array (
58 | 'dbtype' => 'nvarchar',
59 | 'precision' => '255',
60 | 'phptype' => 'string',
61 | 'null' => false,
62 | 'default' => '',
63 | ),
64 | 'hash' =>
65 | array (
66 | 'dbtype' => 'nvarchar',
67 | 'precision' => '50',
68 | 'phptype' => 'string',
69 | 'null' => true,
70 | ),
71 | 'tag' =>
72 | array (
73 | 'dbtype' => 'nvarchar',
74 | 'precision' => '50',
75 | 'phptype' => 'string',
76 | 'null' => false,
77 | 'default' => '',
78 | ),
79 | 'private' =>
80 | array (
81 | 'dbtype' => 'bit',
82 | 'phptype' => 'boolean',
83 | 'null' => false,
84 | 'default' => 0,
85 | ),
86 | 'download' =>
87 | array (
88 | 'dbtype' => 'int',
89 | 'precision' => '10',
90 | 'phptype' => 'integer',
91 | 'attributes' => 'unsigned',
92 | 'null' => false,
93 | 'default' => 0,
94 | ),
95 | 'docid' =>
96 | array (
97 | 'dbtype' => 'int',
98 | 'precision' => '10',
99 | 'phptype' => 'integer',
100 | 'null' => false,
101 | 'default' => 0,
102 | ),
103 | 'uid' =>
104 | array (
105 | 'dbtype' => 'int',
106 | 'precision' => '10',
107 | 'phptype' => 'integer',
108 | 'null' => false,
109 | 'default' => 0,
110 | ),
111 | 'rank' =>
112 | array (
113 | 'dbtype' => 'int',
114 | 'precision' => '10',
115 | 'phptype' => 'integer',
116 | 'attributes' => 'unsigned',
117 | 'null' => false,
118 | 'default' => 0,
119 | ),
120 | ),
121 | 'indexes' =>
122 | array (
123 | 'fid' =>
124 | array (
125 | 'alias' => 'fid',
126 | 'primary' => false,
127 | 'unique' => false,
128 | 'type' => 'BTREE',
129 | 'columns' =>
130 | array (
131 | 'fid' =>
132 | array (
133 | 'length' => '',
134 | 'collation' => 'A',
135 | 'null' => false,
136 | ),
137 | ),
138 | ),
139 | 'name' =>
140 | array (
141 | 'alias' => 'name',
142 | 'primary' => false,
143 | 'unique' => false,
144 | 'type' => 'BTREE',
145 | 'columns' =>
146 | array (
147 | 'name' =>
148 | array (
149 | 'length' => '',
150 | 'collation' => 'A',
151 | 'null' => false,
152 | ),
153 | ),
154 | ),
155 | 'docid' =>
156 | array (
157 | 'alias' => 'docid',
158 | 'primary' => false,
159 | 'unique' => false,
160 | 'type' => 'BTREE',
161 | 'columns' =>
162 | array (
163 | 'docid' =>
164 | array (
165 | 'length' => '',
166 | 'collation' => 'A',
167 | 'null' => false,
168 | ),
169 | ),
170 | ),
171 | 'uid' =>
172 | array (
173 | 'alias' => 'uid',
174 | 'primary' => false,
175 | 'unique' => false,
176 | 'type' => 'BTREE',
177 | 'columns' =>
178 | array (
179 | 'uid' =>
180 | array (
181 | 'length' => '',
182 | 'collation' => 'A',
183 | 'null' => false,
184 | ),
185 | ),
186 | ),
187 | ),
188 | 'aggregates' =>
189 | array (
190 | 'Document' =>
191 | array (
192 | 'class' => 'modResource',
193 | 'local' => 'docid',
194 | 'foreign' => 'id',
195 | 'cardinality' => 'one',
196 | 'owner' => 'foreign',
197 | ),
198 | ),
199 | );
200 |
--------------------------------------------------------------------------------
/core/components/fileattach/model/schema/fileattach.mysql.schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/core/components/fileattach/model/schema/fileattach.sqlsrv.schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/access.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Set private flag
27 | */
28 | class FileItemAccessProcessor extends modObjectProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach');
32 | public $permission = 'save';
33 |
34 | /**
35 | * @return array|string
36 | */
37 | public function process() {
38 | if (!$this->checkPermissions())
39 | return $this->failure($this->modx->lexicon('access_denied'));
40 |
41 | $private = ($this->getProperty('private'))? true : false;
42 | $ids = $this->modx->fromJSON($this->getProperty('ids'));
43 |
44 | if (empty($ids))
45 | return $this->failure($this->modx->lexicon('fileattach.item_err_ns'));
46 |
47 | foreach ($ids as $id) {
48 | /** @var FileItemItem $object */
49 | if (!$object = $this->modx->getObject($this->classKey, $id))
50 | return $this->failure($this->modx->lexicon('fileattach.item_err_nf'));
51 |
52 | if (!$object->setPrivate($private))
53 | return $this->failure($this->modx->lexicon('fileattach.item_err_nr'));
54 | }
55 |
56 | return $this->success();
57 | }
58 | }
59 |
60 | return 'FileItemAccessProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/create.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Create an Item
27 | */
28 | class FileItemCreateProcessor extends modObjectCreateProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach');
32 | public $permission = 'create';
33 |
34 | /**
35 | * @return bool
36 | */
37 | public function beforeSet() {
38 | $docid = (int) $this->getProperty('docid');
39 |
40 | if (!$docid)
41 | $this->modx->error->addField('docid', $this->modx->lexicon('notset'));
42 |
43 | $name = trim($this->getProperty('name'));
44 | $name = $this->object->sanitizeName($name);
45 | $this->setProperty('name', $name);
46 |
47 | $this->setProperty('fid', $this->object->generateName());
48 |
49 | if (empty($name))
50 | $this->modx->error->addField('name', $this->modx->lexicon('fileattach.item_err_name'));
51 |
52 | return parent::beforeSet();
53 | }
54 | }
55 |
56 | return 'FileItemCreateProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/get.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Get an Item
27 | */
28 | class FileItemGetProcessor extends modObjectGetProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach:default');
32 | public $permission = 'view';
33 |
34 |
35 | /**
36 | * We doing special check of permission
37 | * because of our objects is not an instances of modAccessibleObject
38 | *
39 | * @return mixed
40 | */
41 | public function process() {
42 | if (!$this->checkPermissions())
43 | return $this->failure($this->modx->lexicon('access_denied'));
44 |
45 | return parent::process();
46 | }
47 |
48 | }
49 |
50 | return 'FileItemGetProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/getlist.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Get a list of Items
27 | */
28 | class FileItemGetListProcessor extends modObjectGetListProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $defaultSortField = 'id';
32 | public $defaultSortDirection = 'DESC';
33 | public $permission = 'list';
34 |
35 | /**
36 | * * We doing special check of permission
37 | * because of our objects is not an instances of modAccessibleObject
38 | *
39 | * @return boolean|string
40 | */
41 | public function beforeQuery() {
42 | if (!$this->checkPermissions())
43 | return $this->modx->lexicon('access_denied');
44 |
45 | return true;
46 | }
47 |
48 |
49 | /**
50 | * @param xPDOQuery $c
51 | *
52 | * @return xPDOQuery
53 | */
54 | public function prepareQueryBeforeCount(xPDOQuery $c) {
55 | $docid = (int) $this->getProperty('docid');
56 | $uid = trim($this->getProperty('uid'));
57 | $query = trim($this->getProperty('query'));
58 |
59 | $c->select($this->modx->getSelectColumns('FileItem', 'FileItem'));
60 |
61 | if ($query)
62 | $c->where(array('name:LIKE' => "%$query%"));
63 |
64 | if ($uid || ($docid == 0)) {
65 | $c->select('User.username');
66 | $c->leftJoin('modUser', 'User', 'User.id=FileItem.uid');
67 | }
68 |
69 | if ($uid)
70 | $c->where(array('User.username:LIKE' => "%$uid%"));
71 |
72 | if ($docid > 0)
73 | $c->where(array('docid' => $docid));
74 | else {
75 | $c->select('Res.pagetitle');
76 | $c->leftJoin('modResource', 'Res', 'Res.id=FileItem.docid');
77 | }
78 |
79 | return $c;
80 | }
81 | }
82 |
83 | return 'FileItemGetListProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/hash.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Reset download counter
27 | */
28 | class FileItemCalcHashProcessor extends modObjectGetProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach');
32 | public $permission = 'save';
33 |
34 | public function cleanup() {
35 | $hash = sha1($this->object->getFullPath());
36 |
37 | $this->object->set('hash', $hash);
38 | $this->object->save();
39 |
40 | return $this->success('', array('hash' => $hash));
41 | }
42 | }
43 |
44 | return 'FileItemCalcHashProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/rank.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Set rank
27 | */
28 | class FileItemSetRankProcessor extends modObjectProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach');
32 | public $permission = 'save';
33 |
34 | /**
35 | * @return array|string
36 | */
37 | public function process() {
38 | if (!$this->checkPermissions())
39 | return $this->failure($this->modx->lexicon('access_denied'));
40 |
41 | $ranklist = $this->modx->fromJSON($this->getProperty('rank'));
42 |
43 | if (empty($ranklist))
44 | return $this->failure($this->modx->lexicon('fileattach.item_err_ns'));
45 |
46 | foreach ($ranklist as $id => $value) {
47 | /** @var FileItemItem $object */
48 | if (!$object = $this->modx->getObject($this->classKey, $id))
49 | return $this->failure($this->modx->lexicon('fileattach.item_err_nf'));
50 |
51 | $object->set('rank', $value);
52 | $object->save();
53 | }
54 |
55 | return $this->success();
56 | }
57 | }
58 |
59 | return 'FileItemSetRankProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/remove.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Remove an Items
27 | */
28 | class FileItemRemoveProcessor extends modObjectProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('File');
32 | public $permission = 'remove';
33 |
34 |
35 | /**
36 | * @return array|string
37 | */
38 | public function process() {
39 | if (!$this->checkPermissions())
40 | return $this->failure($this->modx->lexicon('access_denied'));
41 |
42 | $ids = $this->modx->fromJSON($this->getProperty('ids'));
43 | if (empty($ids))
44 | return $this->failure($this->modx->lexicon('fileattach.item_err_ns'));
45 |
46 | foreach ($ids as $id) {
47 | /** @var FileItem $object */
48 | if (!$object = $this->modx->getObject($this->classKey, $id))
49 | return $this->failure($this->modx->lexicon('fileattach.item_err_nf'));
50 |
51 | $object->remove();
52 | }
53 |
54 | return $this->success();
55 | }
56 | }
57 |
58 | return 'FileItemRemoveProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/reset.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Reset download counter
27 | */
28 | class FileItemResetProcessor extends modObjectProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach');
32 | public $permission = 'save';
33 |
34 | /**
35 | * @return array|string
36 | */
37 | public function process() {
38 | if (!$this->checkPermissions())
39 | return $this->failure($this->modx->lexicon('access_denied'));
40 |
41 | $ids = $this->modx->fromJSON($this->getProperty('ids'));
42 |
43 | if (empty($ids))
44 | return $this->failure($this->modx->lexicon('fileattach.item_err_ns'));
45 |
46 | foreach ($ids as $id) {
47 | /** @var FileItemItem $object */
48 | if (!$object = $this->modx->getObject($this->classKey, $id))
49 | return $this->failure($this->modx->lexicon('fileattach.item_err_nf'));
50 |
51 | $object->set('download', 0);
52 | $object->save();
53 | }
54 |
55 | return $this->success();
56 | }
57 | }
58 |
59 | return 'FileItemResetProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/searchres.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Searches for specific resources and returns them in an array.
27 | *
28 | * @param integer $start The page to start on
29 | * @param integer $limit (optional) The number of results to limit by
30 | * @param string $sort The column to sort by
31 | * @param string $dir The direction to sort
32 | * @return array An array of modResources
33 | *
34 | * @package modx
35 | * @subpackage processors.resource
36 | */
37 | class modFileItemSearchResourceProcessor extends modObjectGetListProcessor {
38 | public $classKey = 'modResource';
39 | public $languageTopics = array('resource');
40 | public $permission = 'search';
41 | public $defaultSortField = 'pagetitle';
42 |
43 | /** @var array $contextKeys */
44 | public $contextKeys = array();
45 | /** @var array $actions */
46 | public $actions = array();
47 | /** @var string $charset */
48 | public $charset = 'UTF-8';
49 |
50 | public function beforeQuery() {
51 | $this->contextKeys = $this->getContextKeys();
52 | if (empty($this->contextKeys))
53 | return $this->modx->lexicon('permission_denied');
54 |
55 | return true;
56 | }
57 |
58 | public function prepareQueryBeforeCount(xPDOQuery $c) {
59 | $id = $this->getProperty('id');
60 | $query = $this->getProperty('query');
61 | $templates = $this->modx->getOption('fileattach.templates');
62 |
63 | $where = array('context_key:IN' => $this->contextKeys);
64 |
65 | if ($templates != '')
66 | $where['template:IN'] = explode(',', $templates);
67 |
68 | if (!empty($id)) $where['id'] = $id;
69 | if (!empty($query)) $where['pagetitle:LIKE'] = "%$query%";
70 |
71 | $c->select('id,pagetitle,description');
72 | $c->where($where);
73 |
74 | return $c;
75 | }
76 |
77 | /**
78 | * Get a collection of Context keys that the User can access for all the Resources
79 | * @return array
80 | */
81 | public function getContextKeys() {
82 | $contextKeys = array();
83 | $contexts = $this->modx->getCollection('modContext', array('key:!=' => 'mgr'));
84 |
85 | /** @var modContext $context */
86 | foreach ($contexts as $context) {
87 | if ($context->checkPolicy('list'))
88 | $contextKeys[] = $context->get('key');
89 | }
90 |
91 | return $contextKeys;
92 | }
93 |
94 | public function beforeIteration(array $list) {
95 | $this->charset = $this->modx->getOption('modx_charset',null,'UTF-8');
96 | return $list;
97 | }
98 |
99 | public function prepareRow(xPDOObject $object) {
100 | $objectArray = $object->toArray();
101 |
102 | $objectArray['pagetitle'] = htmlentities($objectArray['pagetitle'],ENT_COMPAT,$this->charset);
103 | $objectArray['description'] = htmlentities($objectArray['description'],ENT_COMPAT,$this->charset);
104 |
105 | return array(
106 | 'id' => $objectArray['id'],
107 | 'pagetitle' => $objectArray['pagetitle'],
108 | 'description' => $objectArray['description'],
109 | );
110 | }
111 | }
112 |
113 | return 'modFileItemSearchResourceProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/update.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Update an Item
27 | */
28 | class FileItemUpdateProcessor extends modObjectUpdateProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('fileattach');
32 | public $permission = 'save';
33 |
34 |
35 | /**
36 | * We doing special check of permission
37 | * because of our objects is not an instances of modAccessibleObject
38 | *
39 | * @return bool|string
40 | */
41 | public function beforeSave() {
42 | if (!$this->checkPermissions())
43 | return $this->modx->lexicon('access_denied');
44 |
45 | return true;
46 | }
47 |
48 |
49 | /**
50 | * @return bool
51 | */
52 | public function beforeSet() {
53 | $id = (int)$this->getProperty('id');
54 | $docid = (int)$this->getProperty('docid');
55 |
56 | if (empty($id))
57 | return $this->modx->lexicon('fileattach.item_err_ns');
58 |
59 | if (!$docid)
60 | $this->modx->error->addField('docid', $this->modx->lexicon('notset'));
61 |
62 | $private = ($this->getProperty('private'))? true : false;
63 |
64 | // Allow filename change only in private mode. May be changed further
65 | $name = trim($this->getProperty('name'));
66 | $name = $this->object->sanitizeName($name);
67 | if (empty($name))
68 | $this->modx->error->addField('name', $this->modx->lexicon('fileattach.item_err_name'));
69 |
70 | // If file is open we should rename file, otherwize just change field value
71 | if (!$this->object->get('private')) {
72 | $this->unsetProperty('name');
73 |
74 | // Rename if name changed
75 | if ($name != $this->object->get('name'))
76 | if (!$this->object->rename($name))
77 | $this->modx->error->addField('name', $this->modx->lexicon('fileattach.item_err_nr'));
78 | }
79 |
80 | if (!$this->object->setPrivate($private))
81 | $this->modx->error->addField('name', $this->modx->lexicon('fileattach.item_err_nr'));
82 |
83 | return parent::beforeSet();
84 | }
85 | }
86 |
87 | return 'FileItemUpdateProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/mgr/upload.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Upload files to a directory
27 | *
28 | * @param string $docid resource ID
29 | */
30 | class modFileAttachUploadProcessor extends modProcessor {
31 | /** @var modMediaSource $source */
32 | private $source;
33 | private $privatemode;
34 | private $filename;
35 | public $path;
36 | private $localpath;
37 |
38 | private $calc_hash;
39 | private $user_folders;
40 | private $doc_folders;
41 |
42 | public function checkPermissions() {
43 | return $this->modx->hasPermission('file_upload');
44 | }
45 |
46 | public function getLanguageTopics() {
47 | return array('file');
48 | }
49 |
50 | public function initialize() {
51 | $this->calc_hash = $this->modx->getOption('fileattach.calchash');
52 | $this->user_folders = $this->modx->getOption('fileattach.user_folders');
53 | $this->doc_folders = $this->modx->getOption('fileattach.put_docid');
54 | $this->path = $this->modx->getOption('fileattach.files_path');
55 | $this->privatemode = $this->modx->getOption('fileattach.private');
56 | $this->translit = $this->modx->getOption('fileattach.translit');
57 |
58 | $this->setDefaultProperties(array('docid' => 0));
59 |
60 | $this->localpath = '';
61 |
62 | if ($this->user_folders)
63 | $this->localpath .= (int) $this->modx->user->get('id') . '/';
64 |
65 | if ($this->doc_folders)
66 | $this->localpath .= (int) $this->getProperty('docid') . '/';
67 |
68 | $this->setProperty('path', $this->path . $this->localpath);
69 | $this->setProperty('source', $this->modx->getOption('fileattach.mediasource'));
70 |
71 | if (!$this->getProperty('path')) return $this->modx->lexicon('file_folder_err_ns');
72 |
73 | return true;
74 | }
75 |
76 | public function process() {
77 | if (!$this->getSource())
78 | return $this->failure($this->modx->lexicon('permission_denied'));
79 |
80 | $this->source->setRequestProperties($this->getProperties());
81 | $this->source->initialize();
82 |
83 | if (!$this->source->checkPolicy('create'))
84 | return $this->failure($this->modx->lexicon('permission_denied'));
85 |
86 | // Create subfolder
87 | if ($this->user_folders || $this->doc_folders) {
88 | $path = $this->source->getBasePath() . $this->getProperty('path');
89 | $d = $this->source->fileHandler->make($path, array(), 'modDirectory');
90 |
91 | if (!$d->exists()) {
92 | if (!$this->source->createContainer($this->getProperty('path'), ''))
93 | return $this->failure($this->modx->lexicon('permission_denied'));
94 | }
95 | }
96 |
97 | $path = $this->source->getBasePath() . $this->getProperty('path');
98 | $list = array();
99 |
100 | $this->modx->loadClass('FileItem');
101 |
102 | // Create serie of FileItem objects
103 | foreach ($_FILES as $file) {
104 | $filename = $file['name'];
105 | $ext = pathinfo($filename, PATHINFO_EXTENSION);
106 | $ext = strtolower($ext);
107 |
108 | if ($this->translit)
109 | $filename = modResource::filterPathSegment($this->modx, $filename);
110 |
111 | // Generate name and check for existence
112 | if ($this->privatemode)
113 | $this->filename = FileItem::generateName() . ".$ext";
114 | else
115 | $this->filename = $filename;
116 |
117 | $fullpath = '';
118 |
119 | while(1) {
120 | $fullpath = $path . '/' . $this->filename;
121 | $f = $this->source->fileHandler->make($fullpath, array(), 'modFile');
122 | if (!$f->exists()) break;
123 |
124 | // Generate new name again
125 | if ($this->privatemode)
126 | $this->filename = FileItem::generateName() . ".$ext";
127 | else
128 | $this->filename = '_' . $this->filename;
129 | }
130 |
131 | $success = $this->source->uploadObjectsToContainer(
132 | $this->getProperty('path'),
133 | array(array( // emulate a $_FILES object
134 | "name" => $this->filename,
135 | "tmp_name" => $file['tmp_name'],
136 | "error" => "0")
137 | ));
138 |
139 | if (empty($success)) {
140 | $msg = '';
141 | $errors = $this->source->getErrors();
142 | foreach ($errors as $k => $msg) {
143 | $this->modx->error->addField($k,$msg);
144 | }
145 |
146 | return $this->failure($msg);
147 | } else {
148 | $fid = FileItem::generateName();
149 | $fileitem = $this->modx->newObject('FileItem', array(
150 | 'fid' => $fid,
151 | 'docid' => $this->getProperty('docid'),
152 | 'name' => $filename,
153 | 'internal_name' => $this->filename,
154 | 'path' => $this->localpath,
155 | 'private' => $this->privatemode,
156 | 'uid' => $this->modx->user->get('id'),
157 | 'hash' => ($this->calc_hash)? sha1_file($fullpath) : NULL
158 | ));
159 |
160 | if (!$fileitem->save())
161 | return $this->failure($this->modx->lexicon('fileattach.item_err_save'));
162 |
163 | $list[] = array(
164 | 'id' => $fileitem->get('id'),
165 | 'fid' => $fid,
166 | 'name' => $filename);
167 |
168 | $this->modx->invokeEvent('faOnUploadItem', array(
169 | 'id' => $this->getProperty('docid'),
170 | 'object' => &$fileitem)
171 | );
172 | }
173 | }
174 |
175 | $this->modx->invokeEvent('faOnUpload', array('id' => $this->getProperty('docid')));
176 |
177 | return $this->outputArray($list, count($list));
178 | }
179 |
180 | /**
181 | * Get the active Source
182 | * @return modMediaSource|boolean
183 | */
184 | public function getSource() {
185 | if (empty($this->source)) {
186 | $this->modx->loadClass('sources.modMediaSource');
187 | $this->source = modMediaSource::getDefaultSource($this->modx,$this->getProperty('source'));
188 | }
189 |
190 | if (empty($this->source) || !$this->source->getWorkingContext())
191 | return false;
192 |
193 | return $this->source;
194 | }
195 | }
196 |
197 | return 'modFileAttachUploadProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/web/download.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | class FileItemDownloadProcessor extends modObjectProcessor {
26 | public $objectType = 'FileItem';
27 | public $classKey = 'FileItem';
28 | public $primaryKeyField = 'fid';
29 | public $languageTopics = array('fileattach:default');
30 | public $permission = 'fileattach.download';
31 | private $primaryKey;
32 |
33 | /**
34 | * {@inheritDoc}
35 | * @return boolean
36 | */
37 | public function initialize() {
38 | $this->primaryKey = $this->getProperty($this->primaryKeyField, false);
39 | if (empty($this->primaryKey))
40 | return $this->modx->lexicon('fileattach.item_err_ns');
41 |
42 | $this->object = $this->modx->getObject($this->classKey, array($this->primaryKeyField => $this->primaryKey));
43 | if (empty($this->object))
44 | return $this->modx->lexicon('fileattach.item_err_nfs', array($this->primaryKeyField => $this->primaryKey));
45 |
46 | return parent::initialize();
47 | }
48 |
49 |
50 | /*
51 | * {@inheritDoc}
52 | * @return redirect or bytestream
53 | */
54 | public function process() {
55 | @session_write_close();
56 |
57 | $perform_count = true;
58 |
59 | // If file is private then redirect else read file directly
60 | if ($this->object->get('private')) {
61 | // Get file info
62 | $filename = $this->object->getFullPath();
63 | $filesize = filesize($filename);
64 | $mtime = filemtime($filename);
65 |
66 | if (isset($_SERVER['HTTP_RANGE'])) {
67 | // Get range
68 | $range = str_replace('bytes=', '', $_SERVER['HTTP_RANGE']);
69 | list($start, $end) = explode('-', $range);
70 |
71 | // Check data
72 | if (empty($start)) {
73 | header($_SERVER['SERVER_PROTOCOL'] . ' 416 Requested Range Not Satisfiable');
74 | return;
75 | } else
76 | $perform_count = false;
77 |
78 | // Check range
79 | $start = intval($start);
80 | $end = intval($end);
81 |
82 | if (($end == 0) || ($end < $start) || ($end >= $filesize)) $end = $filesize - 1;
83 |
84 | $remain = $end - $start;
85 |
86 | if ($remain == 0) {
87 | header($_SERVER['SERVER_PROTOCOL'] . ' 416 Requested Range Not Satisfiable');
88 | return;
89 | }
90 |
91 | header($_SERVER['SERVER_PROTOCOL'] . ' 206 Partial Content');
92 | header("Content-Range: bytes $start-$end/$filesize");
93 | } else {
94 | $remain = $filesize;
95 | }
96 |
97 | // Put headers
98 | $inline = (int) $this->getProperty('inline');
99 | if (!$inline) {
100 | header('Content-Type: application/force-download');
101 | header('Content-Disposition: attachment; filename="' . $this->object->get('name') . '"');
102 | $perform_count = false;
103 | }
104 |
105 | header('Last-Modified: ' . gmdate('r', $mtime));
106 | header('ETag: ' . sprintf('%x-%x-%x', fileinode($filename), $filesize, $mtime));
107 | header('Accept-Ranges: bytes');
108 | header('Content-Length: ' . $remain);
109 | header('Connection: close');
110 |
111 | if ($range) {
112 | $fh = fopen($filename, 'rb');
113 | fseek($fh, $start);
114 |
115 | // Output contents
116 | $blocksize = 8192;
117 |
118 | while (!feof($fh) && ($remain > 0)) {
119 | echo fread($fh, ($remain > $blocksize)? $blocksize : $remain);
120 | flush();
121 |
122 | $remain -= $blocksize;
123 | }
124 |
125 | fclose($fh);
126 | } else {
127 | readfile($filename);
128 | }
129 | } else {
130 | // In public mode redirect to file url
131 | $fileurl = $this->object->getUrl();
132 | header("Location: $fileurl", true, 302);
133 | }
134 |
135 | // Count downloads if allowed by config
136 | if ($perform_count && $this->modx->getOption('fileattach.download', null, true)) {
137 | $c = $this->modx->newQuery($this->classKey);
138 | $c->command('update');
139 | $c->set(array(
140 | 'download' => $this->object->get('download') + 1
141 | ));
142 | $c->where(array(
143 | 'fid' => $this->primaryKey,
144 | ));
145 | $c->prepare();
146 | $c->stmt->execute();
147 | }
148 | }
149 | }
150 |
151 | return 'FileItemDownloadProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/web/getlist.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Get a list of Items
27 | */
28 | class FileItemGetListProcessor extends modObjectGetListProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $defaultSortField = 'id';
32 | public $defaultSortDirection = 'DESC';
33 | public $permission = 'fileattach.list';
34 |
35 | /**
36 | * * We doing special check of permission
37 | * because of our objects is not an instances of modAccessibleObject
38 | *
39 | * @return boolean|string
40 | */
41 | public function beforeQuery() {
42 | if (!$this->checkPermissions())
43 | return $this->modx->lexicon('access_denied');
44 |
45 | $docid = (int) $this->getProperty('docid');
46 |
47 | if (!$docid)
48 | return $this->modx->lexicon('fileattach.item_err_ns');
49 |
50 | return true;
51 | }
52 |
53 |
54 | /**
55 | * @param xPDOQuery $c
56 | *
57 | * @return xPDOQuery
58 | */
59 | public function prepareQueryBeforeCount(xPDOQuery $c) {
60 | $docid = (int) $this->getProperty('docid');
61 | $query = trim($this->getProperty('query'));
62 |
63 | $c->select($this->modx->getSelectColumns('FileItem'));
64 |
65 | if ($query)
66 | $c->where(array('name:LIKE' => "%$query%"));
67 |
68 | $c->where(array('docid' => $docid));
69 |
70 | return $c;
71 | }
72 |
73 | public function prepareRow(xPDOObject $object) {
74 | $resArray = array(
75 | 'id' => $object->get('id'),
76 | 'fid' => $object->get('fid'),
77 | 'name' => $object->get('name'),
78 | 'hash' => $object->get('hash')
79 | );
80 |
81 | return $resArray;
82 | }
83 | }
84 |
85 | return 'FileItemGetListProcessor';
--------------------------------------------------------------------------------
/core/components/fileattach/processors/web/remove.class.php:
--------------------------------------------------------------------------------
1 |
6 | *
7 | * This file is part of FileAttach, tool to attach files to resources with
8 | * MODX Revolution's Manager.
9 | *
10 | * FileAttach is free software; you can redistribute it and/or modify it under the
11 | * terms of the GNU General Public License as published by the Free Software
12 | * Foundation version 3,
13 | *
14 | * FileAttach is distributed in the hope that it will be useful, but WITHOUT ANY
15 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along with
19 | * FileAttach; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 | * Suite 330, Boston, MA 02111-1307 USA
21 | *
22 | * @package FileAttach
23 | */
24 |
25 | /**
26 | * Remove an Items
27 | */
28 | class FileItemRemoveProcessor extends modObjectProcessor {
29 | public $objectType = 'FileItem';
30 | public $classKey = 'FileItem';
31 | public $languageTopics = array('File');
32 | public $permission = 'fileattach.remove';
33 | public $permission2 = 'fileattach.totallist';
34 |
35 |
36 | /**
37 | * @return array|string
38 | */
39 | public function process() {
40 | if (!$this->checkPermissions())
41 | return $this->failure($this->modx->lexicon('access_denied'));
42 |
43 | $adminmode = $this->modx->hasPermission($this->permission2);
44 |
45 | $docid = (int) $this->getProperty('docid');
46 |
47 | if (!$docid)
48 | return $this->failure($this->modx->lexicon('fileattach.item_err_ns'));
49 |
50 | $ids = $this->modx->fromJSON($this->getProperty('ids'));
51 | if (empty($ids))
52 | return $this->failure($this->modx->lexicon('fileattach.item_err_ns'));
53 |
54 | foreach ($ids as $id) {
55 | /** @var FileItem $object */
56 | if (!$object = $this->modx->getObject($this->classKey, $id))
57 | return $this->failure($this->modx->lexicon('fileattach.item_err_nf'));
58 |
59 | // Forbid deletion for another resources
60 | if ($object->get('docid') != $docid)
61 | return $this->failure($this->modx->lexicon('fileattach.item_err_remove'));
62 |
63 | // Allow remove only for admins and file owners
64 | if ($adminmode || (($this->modx->user->get('id') == $object->get('uid'))))
65 | $object->remove();
66 | else
67 | return $this->failure($this->modx->lexicon('fileattach.item_err_remove'));
68 | }
69 |
70 | return $this->success();
71 | }
72 | }
73 |
74 | return 'FileItemRemoveProcessor';
--------------------------------------------------------------------------------