├── lang ├── en_gb.lang └── de_de.lang ├── update.php ├── .gitattributes ├── pages ├── index.php ├── info.php ├── setup.php └── settings.php ├── templates ├── thread.create.tpl.php ├── thread_OLD.create.tpl.php ├── post.create.tpl.php ├── post_OLD.create.tpl.php ├── pagination.tpl.php ├── pagination_OLD.tpl.php ├── threads.tpl.php ├── threads_OLD.tpl.php ├── posts.tpl.php └── posts_OLD.tpl.php ├── install.php ├── module ├── module_out.inc └── module_in.inc ├── fragments ├── ycom_board_createform.php ├── ycom_board_pagination.php ├── ycom_board_threads.php └── ycom_board_posts.php ├── uninstall.inc.php ├── package.yml ├── install ├── modules │ ├── board_input.php │ └── board_output.php └── tablesets │ ├── ycom_board_thread_notification.json │ └── ycom_board.json ├── LICENSE ├── lib ├── rex_ycom_board_thread.php ├── ycom_board_message.php ├── rex_ycom_board_post.php └── rex_ycom_board.php ├── assets └── uploadfile │ ├── jquery-file-upload.min.css │ ├── jquery-file-upload.css │ ├── jquery-file-upload.min.js │ ├── ycom-board-file-upload.js │ └── jquery-file-upload.js ├── boot.php └── README.md /lang/en_gb.lang: -------------------------------------------------------------------------------- 1 | 2 | com_board_name = Board 3 | -------------------------------------------------------------------------------- /update.php: -------------------------------------------------------------------------------- 1 | includeFile(__DIR__.'/install.php'); 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /pages/index.php: -------------------------------------------------------------------------------- 1 | getSubPath(); 5 | rex_be_controller::includeCurrentPageSubPath(); 6 | -------------------------------------------------------------------------------- /templates/thread.create.tpl.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | Zur Übersicht 8 | 9 |

Neues Thema

10 | 11 | 12 | -------------------------------------------------------------------------------- /templates/thread_OLD.create.tpl.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | Zur Übersicht 8 | 9 |

Neues Thema

10 | 11 | 12 | -------------------------------------------------------------------------------- /templates/post.create.tpl.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | Zur Übersicht 9 | 10 |

getTitle() ?>: Antworten

11 | 12 | 13 | -------------------------------------------------------------------------------- /templates/post_OLD.create.tpl.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | Zur Übersicht 9 | 10 |

getTitle() ?>: Antworten

11 | 12 | 13 | -------------------------------------------------------------------------------- /install.php: -------------------------------------------------------------------------------- 1 | getValue('name')); 6 | $b->setUrl(rex_getUrl(REX_ARTICLE_ID)); 7 | $b->setThreadsPerPage("REX_VALUE[1]"); 8 | $b->setPostsPerPage("REX_VALUE[2]"); 9 | $b->setNotificationTemplate("REX_VALUE[3]"); 10 | $b->setAdminGroup("REX_VALUE[4]"); 11 | 12 | echo $b->getView(); 13 | 14 | ?> 15 | -------------------------------------------------------------------------------- /fragments/ycom_board_createform.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | Zur Übersicht 11 | 12 | thread) : ?> 13 |

thread->getTitle() ?>: Antworten

14 | 15 |

Neues Thema

16 | 17 | 18 | form ?> 19 | -------------------------------------------------------------------------------- /uninstall.inc.php: -------------------------------------------------------------------------------- 1 | www.yakamara.de 8 | */ 9 | $REX['ADDON']['install']['board'] = 0; 10 | 11 | $i = rex_sql::factory(); 12 | $i->setQuery("DELETE FROM `rex_yform_table` where `table_name`='rex_ycom_board_post';"); 13 | $i->setQuery("DELETE FROM `rex_yform_field` where `table_name`='rex_ycom_board_post';"); 14 | $info = rex_generateAll(); 15 | -------------------------------------------------------------------------------- /package.yml: -------------------------------------------------------------------------------- 1 | package: ycom_board 2 | version: '3.0dev' 3 | author: Friends Of REDAXO 4 | supportpage: www.redaxo.org/de/forum 5 | title: 'YCom Board' 6 | nav_icon: fa-plus 7 | description: 'translate:ycom_board_plugin' 8 | page: 9 | title: 'translate:ycom_board_title' 10 | hidden: false 11 | pjax: true 12 | subpages: 13 | settings: { title: 'Einstellungen' } 14 | setup: { title: 'Setup', perm: admin } 15 | info: { title: 'Info', itemclass: pull-right } 16 | requires: 17 | packages: 18 | ycom: '>3' 19 | -------------------------------------------------------------------------------- /templates/pagination.tpl.php: -------------------------------------------------------------------------------- 1 | getPager(); 5 | ?> 6 | 7 | getRowCount() > $pager->getRowsPerPage()): ?> 8 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /fragments/ycom_board_pagination.php: -------------------------------------------------------------------------------- 1 | pager; 5 | ?> 6 | getRowCount() > $pager->getRowsPerPage()): ?> 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/pagination_OLD.tpl.php: -------------------------------------------------------------------------------- 1 | getPager(); 5 | ?> 6 | 7 | getRowCount() > $pager->getRowsPerPage()): ?> 8 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /pages/info.php: -------------------------------------------------------------------------------- 1 | '.rex_i18n::rawMsg('yform_docs_filenotfound').'

'; 9 | } 10 | 11 | if (class_exists('rex_markdown')) { 12 | $md = rex_markdown::factory(); 13 | $content = $md->parse($content); 14 | } 15 | 16 | 17 | $fragment = new rex_fragment(); 18 | $fragment->setVar('title', 'YCom Board - Dokumentation', false); 19 | $fragment->setVar('body', $content, false); 20 | echo $fragment->parse('core/page/section.php'); 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /module/module_in.inc: -------------------------------------------------------------------------------- 1 | 6 | 7 | Threads pro Seite:
8 |

9 | 10 | Beiträge pro Seite:
11 |

12 | 13 | E-Mail-Template für Benachrichtigungen:
14 | setName('VALUE[3]'); 17 | $select->setSize(1); 18 | $select->addOption('–', 0); 19 | $select->addSqlOptions('SELECT name, name FROM rex_yform_email_template ORDER BY name'); 20 | $select->setSelected('REX_VALUE[3]'); 21 | $select->show(); 22 | ?> 23 |

24 | 25 | Benutzergruppe mit Adminfunktionen:
26 | setName('VALUE[4]'); 29 | $select->setSize(1); 30 | $select->addOption('–', 0); 31 | $select->addSqlOptions('SELECT name, id FROM rex_ycom_group ORDER BY name'); 32 | $select->setSelected('REX_VALUE[4]'); 33 | $select->show(); 34 | ?> 35 | -------------------------------------------------------------------------------- /install/modules/board_input.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | Threads pro Seite:
8 |

9 | 10 | Beiträge pro Seite:
11 |

12 | 13 | E-Mail-Template für Benachrichtigungen:
14 | setName('REX_INPUT_VALUE[3]'); 17 | $select->setSize(1); 18 | $select->addOption('–', 0); 19 | $select->addSqlOptions('SELECT name, name FROM rex_yform_email_template ORDER BY name'); 20 | $select->setSelected('REX_VALUE[3]'); 21 | $select->show(); 22 | ?> 23 |

24 | 25 | Benutzergruppe mit Adminfunktionen:
26 | setName('REX_INPUT_VALUE[4]'); 29 | $select->setSize(1); 30 | $select->addOption('–', 0); 31 | $select->addSqlOptions('SELECT name, id FROM rex_ycom_group ORDER BY name'); 32 | $select->setSelected('REX_VALUE[4]'); 33 | $select->show(); 34 | ?> 35 | -------------------------------------------------------------------------------- /install/modules/board_output.php: -------------------------------------------------------------------------------- 1 | Wert für Threads pro Seite nicht gesetzt!'; 8 | return; 9 | } 10 | if (!"REX_VALUE[2]") { 11 | echo '

Wert für Beiträge pro Seite nicht gesetzt!'; 12 | return; 13 | } 14 | if (!"REX_VALUE[3]") { 15 | echo '

Wert für Notification Template nicht gesetzt!'; 16 | return; 17 | } 18 | if (!"REX_VALUE[4]") { 19 | echo '

Wert für Admin Group nicht gesetzt!'; 20 | return; 21 | } 22 | 23 | /* 24 | if (rex::isFrontend() && !rex_ycom_auth::getUser()) { 25 | echo '

Kein gültiger Benutzer eingeloggt.

'; 26 | return; 27 | } 28 | */ 29 | 30 | $b = new rex_ycom_board('aid-REX_ARTICLE_ID', $this->getValue('name')); 31 | $b->setUrl(rex_getUrl("REX_ARTICLE_ID")); 32 | $b->setThreadsPerPage("REX_VALUE[1]"); 33 | $b->setPostsPerPage("REX_VALUE[2]"); 34 | $b->setNotificationTemplate("REX_VALUE[3]"); 35 | $b->setAdminGroup("REX_VALUE[4]"); 36 | 37 | echo $b->getView(); 38 | 39 | ?> 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Friends Of REDAXO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lang/de_de.lang: -------------------------------------------------------------------------------- 1 | com_board = Board 2 | com_board_name = Community Board 3 | 4 | com_board_title = Titel 5 | com_board_message = Nachricht 6 | com_board_attachment = Anhang 7 | com_board_thread = Thread 8 | com_board_key = Board-Key 9 | 10 | com_board_enter_title = Bitte geben Sie einen Titel ein. 11 | com_board_enter_message = Bitte geben Sie eine Nachricht ein. 12 | 13 | com_board_attachment_error_max_size = 14 | com_board_attachment_error_type 15 | com_board_attachment_delete = Lösche 16 | 17 | com_board_notifications = Bei neuen Beiträgen benachrichtigen 18 | com_board_thread_notification = Community Board Benachrichtigungen 19 | 20 | com_board_install_modul = Boardmodul installieren 21 | com_board_install_modul_description = Um das Board nutzen können, muß ein Modul erstellt werden, 22 | welches das Board in einen Artikel einbindet. 23 | com_board_install_board_modul = Neues Boardmodul installieren 24 | com_board_update_following_modul = Folgendes Boardmodul aktualisieren "{0}" 25 | 26 | ycom_board_title = YCom Board 27 | 28 | ycom_board_modul_description = Modul für die Verwendung des Boards (Anzeige und Formulare) installieren. 29 | ycom_board_install_modul = Modulinstallation für das YCom Board. 30 | ycom_board_update_module = Modul "{0}" updaten 31 | ycom_board_install_module = Modul "{0}" installieren 32 | -------------------------------------------------------------------------------- /templates/threads.tpl.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 |

10 | Neues Thema 11 |

12 | 13 | 14 | render('pagination.tpl.php') ?> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 40 | 41 | 42 | 43 |
ThemenAntwortenLetzter Beitrag
28 | getTitle()) ?>
29 | von getUserFullName()) ?> am getCreated('%d.%m.%Y, %H:%M Uhr') ?> 30 |
countReplies() ?> 33 | countReplies()) : ?> 34 | 35 | von getRecentPost()->getUserFullName() ?>
36 | am getRecentPost()->getCreated('%d.%m.%Y, %H:%M Uhr') ?> 37 |
38 | 39 |
44 | 45 | render('pagination.tpl.php') ?> 46 | -------------------------------------------------------------------------------- /templates/threads_OLD.tpl.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 |

10 | Neues Thema 11 |

12 | 13 | 14 | render('pagination.tpl.php') ?> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 40 | 41 | 42 | 43 |
ThemenAntwortenLetzter Beitrag
28 | getTitle()) ?>
29 | von getUserFullName()) ?> am getCreated('%d.%m.%Y, %H:%M Uhr') ?> 30 |
countReplies() ?> 33 | countReplies()) : ?> 34 | 35 | von getRecentPost()->getUserFullName() ?>
36 | am getRecentPost()->getCreated('%d.%m.%Y, %H:%M Uhr') ?> 37 |
38 | 39 |
44 | 45 | render('pagination.tpl.php') ?> 46 | -------------------------------------------------------------------------------- /fragments/ycom_board_threads.php: -------------------------------------------------------------------------------- 1 | boardthis; 7 | $threads = $this->threads; 8 | 9 | ?> 10 | 11 | 12 |

13 | Neues Thema 14 |

15 | 16 | 17 | setVar('pager',$boardthis->getPager()); 20 | $fragment->setVar('boardthis',$boardthis); 21 | echo $fragment->parse('ycom_board_pagination.php'); 22 | ?> 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 48 | 49 | 50 | 51 |
ThemenAntwortenLetzter Beitrag
36 | getTitle()) ?>
37 | von getUserFullName()) ?> am getCreated('%d.%m.%Y, %H:%M Uhr') ?> 38 |
countReplies() ?> 41 | countReplies()) : ?> 42 | 43 | von getRecentPost()->getUserFullName() ?>
44 | am getRecentPost()->getCreated('%d.%m.%Y, %H:%M Uhr') ?> 45 |
46 | 47 |
52 | 53 | parse('ycom_board_pagination.php'); ?> 54 | 55 | -------------------------------------------------------------------------------- /install/tablesets/ycom_board_thread_notification.json: -------------------------------------------------------------------------------- 1 | {"rex_ycom_board_thread_notification":{"table":{"id":"7","status":"1","table_name":"rex_ycom_board_thread_notification","name":"translate:com_board_thread_notification","description":"","list_amount":"50","list_sortfield":"id","list_sortorder":"ASC","prio":"4","search":"1","hidden":"1","export":"1","import":"1","mass_deletion":"0","mass_edit":"0","schema_overwrite":"1","history":"0"},"fields":[{"id":"58","table_name":"rex_ycom_board_thread_notification","prio":"1","type_id":"value","type_name":"be_manager_relation","db_type":"","list_hidden":"0","search":"1","name":"thread_id","label":"translate:com_board_thread","not_required":"","options":"","multiple":"","default":"","size":"1","only_empty":"","message":"","table":"rex_ycom_board_post","hashname":"","password_hash":"","no_db":"","password_label":"","field":"title","type":"2","empty_value":"","empty_option":"0","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"59","table_name":"rex_ycom_board_thread_notification","prio":"2","type_id":"value","type_name":"be_manager_relation","db_type":"","list_hidden":"0","search":"1","name":"user_id","label":"translate:com_user","not_required":"","options":"","multiple":"","default":"","size":"1","only_empty":"","message":"","table":"rex_ycom_user","hashname":"","password_hash":"","no_db":"","password_label":"","field":"firstname, \" \", name","type":"2","empty_value":"","empty_option":"0","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""}]}} -------------------------------------------------------------------------------- /pages/setup.php: -------------------------------------------------------------------------------- 1 | isAdmin()) { 4 | $content = ''; 5 | $searchtext = 'module:com_board_basic_out'; 6 | 7 | $gm = rex_sql::factory(); 8 | $gm->setQuery('select * from '.rex::getTable('module').' where output LIKE "%' . $searchtext . '%"'); 9 | 10 | $module_id = 0; 11 | $board_module_name = 'rex - board'; 12 | foreach ($gm->getArray() as $module) { 13 | $module_id = $module['id']; 14 | $board_module_name = $module['name']; 15 | } 16 | 17 | if (rex_request('install', 'integer') == 1) { 18 | $input = rex_file::get(rex_path::addon('ycom_board','install/modules/board_input.php')); 19 | $output = rex_file::get(rex_path::addon('ycom_board', 'install/modules/board_output.php')); 20 | 21 | $mi = rex_sql::factory(); 22 | // $mi->debugsql = 1; 23 | $mi->setTable(rex::getTable('module')); 24 | $mi->setValue('input', $input); 25 | $mi->setValue('output', $output); 26 | 27 | if ($module_id == rex_request('module_id', 'integer', -1)) { 28 | $mi->setWhere('id="' . $module_id . '"'); 29 | $mi->update(); 30 | echo rex_view::success('Modul "' . $module_name . '" wurde aktualisiert'); 31 | } else { 32 | $mi->setValue('name', $board_module_name); 33 | $mi->insert(); 34 | $module_id = (int) $mi->getLastId(); 35 | $module_name = $board_module_name; 36 | echo rex_view::success('board Modul wurde angelegt unter "' . $board_module_name . '"'); 37 | } 38 | } 39 | 40 | $content .= '

'.$this->i18n('ycom_board_modul_description').'

'; 41 | 42 | // dump($module_id); 43 | 44 | if ($module_id > 0) { 45 | $content .= '

' . $this->i18n('ycom_board_update_module', htmlspecialchars($board_module_name)) . '

'; 46 | } else { 47 | $content .= '

' . $this->i18n('ycom_board_install_module', $board_module_name) . '

'; 48 | } 49 | 50 | $fragment = new rex_fragment(); 51 | $fragment->setVar('title', $this->i18n('ycom_board_install_modul'), false); 52 | $fragment->setVar('body', $content, false); 53 | echo $fragment->parse('core/page/section.php'); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /lib/rex_ycom_board_thread.php: -------------------------------------------------------------------------------- 1 | setQuery('SELECT * FROM rex_ycom_board_post WHERE status = 1 and thread_id = "" and id = ' . (int) $id); 13 | if (!$sql->getRows()) { 14 | return null; 15 | } 16 | return new self($sql->getRow()); 17 | } 18 | 19 | public function countReplies() 20 | { 21 | if (null !== $this->countReplies) { 22 | return $this->countReplies; 23 | } 24 | 25 | $sql = rex_sql::factory(); 26 | $sql->setQuery('SELECT COUNT(*) as count FROM rex_ycom_board_post WHERE status = 1 and thread_id = ' . (int) $this->getId()); 27 | return $this->countReplies = (int) $sql->getValue('count'); 28 | } 29 | 30 | public function getRecentPost() 31 | { 32 | if (null !== $this->recentPost) { 33 | return $this->recentPost; 34 | } 35 | 36 | $sql = rex_sql::factory(); 37 | // $sql->setDebug(); 38 | $sql->setQuery(sprintf('SELECT * FROM rex_ycom_board_post WHERE status = 1 AND (thread_id = %d OR id = %1$d) ORDER BY created DESC LIMIT 1', (int) $this->getId())); 39 | return $this->recentPost = new rex_ycom_board_post($sql->getRow()); 40 | } 41 | 42 | public function getNotificationUsers() 43 | { 44 | if (null !== $this->notificationUsers) { 45 | return $this->notificationUsers; 46 | } 47 | 48 | $sql = rex_sql::factory(); 49 | $data = $sql->getArray(sprintf('SELECT user_id FROM rex_ycom_board_thread_notification WHERE thread_id = %d', $this->getId())); 50 | $this->notificationUsers = array(); 51 | foreach ($data as $row) { 52 | $this->notificationUsers[] = $row['user_id']; 53 | } 54 | return $this->notificationUsers; 55 | } 56 | 57 | public function addNotificationUser(rex_ycom_user $user) 58 | { 59 | if (in_array($user->id, $this->getNotificationUsers())) { 60 | return; 61 | } 62 | 63 | $sql = rex_sql::factory(); 64 | $sql->setTable('rex_ycom_board_thread_notification'); 65 | $sql->setValue('thread_id', $this->getId()); 66 | $sql->setValue('user_id', $user->id); 67 | $sql->insert(); 68 | 69 | $this->notificationUsers[] = $user->id; 70 | } 71 | 72 | public function removeNotificationUser(rex_ycom_user $user) 73 | { 74 | $sql = rex_sql::factory(); 75 | $sql->setTable('rex_ycom_board_thread_notification'); 76 | $sql->setWhere(sprintf('thread_id = %d AND user_id = %d', $this->getId(), $user->id)); 77 | $sql->delete(); 78 | 79 | $this->notificationUsers = null; 80 | } 81 | 82 | public function isNotificationEnabled($user) 83 | { 84 | if (!$user) { 85 | return false; 86 | } 87 | return in_array($user->id, $this->getNotificationUsers()); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /templates/posts.tpl.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | Zur Übersicht 10 | 11 |

getTitle() ?>

12 | 13 | 14 |

15 | Antworten 16 | isNotificationEnabled(rex_ycom_auth::getUser())): ?> 17 | Benachrichtigungen ausschalten 18 | 19 | Benachrichtigungen einschalten 20 | 21 |

22 | 23 | 24 | render('pagination.tpl.php') ?> 25 | 26 | 27 | 28 | 29 | 30 | 42 | 51 | 52 | 53 | 54 |
31 | getUserFullName() ?>

32 | getCreated('%d.%m.%Y, %H:%M Uhr')?> 33 | isBoardAdmin()): ?> 34 |

35 | 36 | Thread löschen 37 | 38 | Beitrag löschen 39 | 40 | 41 |
43 |

getTitle()) ?>

44 |

getMessage())) ?>

45 | hasAttachment()): ?> 46 |

47 | Anhang: getAttachment() ?> 48 |

49 | 50 |
55 | 56 | render('pagination.tpl.php') ?> 57 | 58 | 59 |

60 | Antworten 61 | isNotificationEnabled(rex_ycom_auth::getUser())): ?> 62 | Benachrichtigungen ausschalten 63 | 64 | Benachrichtigungen einschalten 65 | 66 |

67 | -------------------------------------------------------------------------------- /lib/ycom_board_message.php: -------------------------------------------------------------------------------- 1 | query() 25 | ->where('status','0','>') 26 | ->whereRaw(implode(' AND ',$where)) 27 | ->find(); 28 | 29 | foreach ($items as $item) { 30 | if (!$item->email) { 31 | continue; 32 | } 33 | $yform = new rex_yform(); 34 | $yform->setObjectparams('csrf_protection',false); 35 | $yform->setValueField('hidden', ['firstname',$item->firstname]); 36 | $yform->setValueField('hidden', ['name',$item->name]); 37 | $yform->setValueField('hidden', ['email',$item->email]); 38 | $yform->setValueField('hidden', ['url',rex_getUrl()]); 39 | $yform->setValueField('hidden', ['title',$thread->getTitle()]); 40 | $yform->setValueField('hidden', ['message',$thread->getMessage()]); 41 | $yform->setActionField('tpl2email', [rex_config::get('ycom_board','email_template_new_thread'),"email",$item->email]); 42 | $yform->getForm(); 43 | $yform->setObjectparams('send',1); 44 | $yform->executeActions(); 45 | } 46 | 47 | 48 | 49 | 50 | /* 51 | "rex_ycom_board_post.id" => "7" 52 | "rex_ycom_board_post.board_key" => "aid-57" 53 | "rex_ycom_board_post.thread_id" => "" 54 | "rex_ycom_board_post.title" => "asdfasdfasdfa" 55 | "rex_ycom_board_post.message" => "safdasfdasfdsafd" 56 | "rex_ycom_board_post.user_id" => "5" 57 | "rex_ycom_board_post.status" => "1" 58 | "rex_ycom_board_post.created" => "2019-12-04 18:00:10" 59 | "rex_ycom_board_post.updated" => "2019-12-04 18:00:10" 60 | "rex_ycom_board_post.notifications" => "" 61 | "rex_ycom_board_post.attachment" => "" 62 | "id" => "7" 63 | "board_key" => "aid-57" 64 | "thread_id" => "" 65 | "title" => "asdfasdfasdfa" 66 | "message" => "safdasfdasfdsafd" 67 | "user_id" => "5" 68 | "status" => "1" 69 | "created" => "2019-12-04 18:00:10" 70 | "updated" => "2019-12-04 18:00:10" 71 | "notifications" => "" 72 | "attachment" => "" 73 | */ 74 | 75 | 76 | 77 | 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /templates/posts_OLD.tpl.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | Zur Übersicht 10 | 11 |

getTitle() ?>

12 | 13 | 14 |

15 | Antworten 16 | isNotificationEnabled(rex_ycom_auth::getUser())): ?> 17 | Benachrichtigungen ausschalten 18 | 19 | Benachrichtigungen einschalten 20 | 21 |

22 | 23 | 24 | render('pagination.tpl.php') ?> 25 | 26 | 27 | 28 | 29 | 30 | 42 | 56 | 57 | 58 | 59 |
31 | getUserFullName() ?>

32 | getCreated('%d.%m.%Y, %H:%M Uhr')?> 33 | isBoardAdmin()): ?> 34 |

35 | 36 | Thread löschen 37 | 38 | Beitrag löschen 39 | 40 | 41 |
43 |

getTitle()) ?>

44 |

getMessage())) ?>

45 | hasAttachment()): ?> 46 |

Anhang:

47 | getRealAttachment(),true) ?> 48 | 49 |
50 | 51 |
Download
52 |
53 | 54 | 55 |
60 | 61 | render('pagination.tpl.php') ?> 62 | 63 | 64 |

65 | Antworten 66 | isNotificationEnabled(rex_ycom_auth::getUser())): ?> 67 | Benachrichtigungen ausschalten 68 | 69 | Benachrichtigungen einschalten 70 | 71 |

72 | -------------------------------------------------------------------------------- /lib/rex_ycom_board_post.php: -------------------------------------------------------------------------------- 1 | data = $data; 11 | foreach ($data as $k=>$v) { 12 | if (strpos($k,'.')) { 13 | $_k = explode('.',$k); 14 | $this->data[$_k[1]] = $v; 15 | } 16 | } 17 | } 18 | 19 | public static function get($id) 20 | { 21 | $sql = rex_sql::factory(); 22 | $sql->setQuery('SELECT * FROM rex_ycom_board_post WHERE status = 1 and id = ' . (int) $id); 23 | if (!$sql->getRows()) { 24 | return null; 25 | } 26 | return new self($sql->getRow()); 27 | } 28 | 29 | public function getId() 30 | { 31 | /* 32 | if (isset ($this->data['rex_ycom_board_post.id'])) { 33 | return $this->data['rex_ycom_board_post.id']; 34 | } 35 | * 36 | */ 37 | return $this->data['id']; 38 | } 39 | 40 | public function getThreadId() 41 | { 42 | return $this->data['thread_id'] ?: $this->getId(); 43 | } 44 | 45 | public function getTitle() 46 | { 47 | return $this->data['title']; 48 | } 49 | 50 | public function getMessage() 51 | { 52 | return $this->data['message']; 53 | } 54 | 55 | public function hasAttachment() 56 | { 57 | return (bool) $this->data['attachment']; 58 | } 59 | 60 | public function getAttachment() 61 | { 62 | if (!$this->hasAttachment()) { 63 | return null; 64 | } 65 | 66 | $parts = explode('_', $this->getRealAttachment(), 2); 67 | return isset($parts[1]) ? $parts[1] : null; 68 | } 69 | 70 | public function getRealAttachment() 71 | { 72 | return $this->data['attachment']; 73 | } 74 | 75 | /** 76 | * @return rex_ycom_user 77 | */ 78 | public function getUser() 79 | { 80 | if (!$this->data['user_id']) { 81 | return false; 82 | } 83 | if (!$this->user) { 84 | $this->user = rex_yform_manager_table::get('rex_ycom_user')->query()->where('id',$this->data['user_id'])->findOne(); 85 | } 86 | 87 | return $this->user; 88 | } 89 | 90 | public static function getUserById($id = 0) { 91 | if (!$id) { 92 | return false; 93 | } 94 | return rex_yform_manager_table::get('rex_ycom_user')->query()->where('id',$id)->findOne(); 95 | } 96 | 97 | 98 | public function getUserFullName() { 99 | if (!$this->data['user_id']) { 100 | return ''; 101 | } 102 | if (!$this->user) { 103 | $this->user = rex_yform_manager_table::get('rex_ycom_user')->query()->where('id',$this->data['user_id'])->findOne(); 104 | } 105 | return $this->user->firstname . ' ' . $this->user->name; 106 | 107 | } 108 | 109 | 110 | public function getCreated($format = null) 111 | { 112 | $timestamp = strtotime($this->data['created']); 113 | return $format ? strftime($format, $timestamp) : $timestamp; 114 | } 115 | 116 | public function getUpdated($format = null) 117 | { 118 | $timestamp = strtotime($this->data['updated']); 119 | 120 | return $format ? strftime($format, $timestamp) : $timestamp; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /assets/uploadfile/jquery-file-upload.min.css: -------------------------------------------------------------------------------- 1 | .custom-statusbar{ 2 | border-top: 1px solid #394F61; 3 | padding: 5px 0px 5px 4px; 4 | width: 700px; 5 | } 6 | .odd 7 | { 8 | background-color:#EDEBEB; 9 | } 10 | .even 11 | { 12 | background-color:#FFFFFF; 13 | } 14 | 15 | .custom-filename { 16 | display: inline-block; 17 | width: 230px; 18 | margin: 0 5px 0px 0px; 19 | color: #807579; 20 | vertical-align: middle; 21 | } 22 | .custom-preview 23 | { 24 | display:inline-block; 25 | vertical-align:middle; 26 | border:1px solid #C7CCD1; 27 | } 28 | .custom-progress { 29 | margin: 0 10px 0px 10px; 30 | position: relative; 31 | width: 250px; 32 | border: 1px solid #ddd; 33 | padding: 1px; 34 | border-radius: 3px; 35 | display: inline-block; 36 | vertical-align:middle; 37 | color:#FFFFFF; 38 | } 39 | .custom-bar { 40 | background-color: #337AB7; 41 | width: 0; 42 | height: 20px; 43 | border-radius: 3px; 44 | color:#FFFFFF; 45 | display: inline-block; 46 | vertical-align:middle; 47 | margin:0px; 48 | } 49 | .custom-percent { 50 | position: absolute; 51 | display: inline-block; 52 | top: 3px; 53 | left: 48% 54 | } 55 | .custom-red { 56 | -moz-box-shadow: inset 0 39px 0 -24px #e67a73; 57 | -webkit-box-shadow: inset 0 39px 0 -24px #e67a73; 58 | box-shadow: inset 0 39px 0 -24px #e67a73; 59 | background-color: #e4685d; 60 | -moz-border-radius: 4px; 61 | -webkit-border-radius: 4px; 62 | border-radius: 4px; 63 | display: inline-block; 64 | color: #fff; 65 | font-family: arial; 66 | font-size: 13px; 67 | font-weight: normal; 68 | padding: 4px 15px; 69 | text-decoration: none; 70 | text-shadow: 0 1px 0 #b23e35; 71 | cursor: pointer; 72 | vertical-align: middle; 73 | margin-right:5px; 74 | } 75 | .custom-green { 76 | background-color: #77b55a; 77 | -moz-border-radius: 4px; 78 | -webkit-border-radius: 4px; 79 | border-radius: 4px; 80 | margin: 0; 81 | padding: 0; 82 | display: inline-block; 83 | color: #fff; 84 | font-family: arial; 85 | font-size: 13px; 86 | font-weight: normal; 87 | padding: 4px 15px; 88 | text-decoration: none; 89 | cursor: pointer; 90 | text-shadow: 0 1px 0 #5b8a3c; 91 | vertical-align: middle; 92 | margin-right:5px; 93 | } 94 | .ajax-file-upload { 95 | font-family: Arial, Helvetica, sans-serif; 96 | font-size: 16px; 97 | font-weight: bold; 98 | padding: 15px 20px; 99 | cursor:pointer; 100 | line-height:20px; 101 | height:25px; 102 | margin:0 10px 10px 0; 103 | display: inline-block; 104 | background: #fff; 105 | border: 1px solid #e8e8e8; 106 | color: #888; 107 | text-decoration: none; 108 | border-radius: 3px; 109 | -webkit-border-radius: 3px; 110 | -moz-border-radius: 3px; 111 | -moz-box-shadow: 0 2px 0 0 #e8e8e8; 112 | -webkit-box-shadow: 0 2px 0 0 #e8e8e8; 113 | box-shadow: 0 2px 0 0 #e8e8e8; 114 | padding: 6px 10px 4px 10px; 115 | color: #fff; 116 | background: #2f8ab9; 117 | border: none; 118 | -moz-box-shadow: 0 2px 0 0 #13648d; 119 | -webkit-box-shadow: 0 2px 0 0 #13648d; 120 | box-shadow: 0 2px 0 0 #13648d; 121 | vertical-align:middle; 122 | } 123 | 124 | .ajax-file-upload:hover { 125 | background: #3396c9; 126 | -moz-box-shadow: 0 2px 0 0 #15719f; 127 | -webkit-box-shadow: 0 2px 0 0 #15719f; 128 | box-shadow: 0 2px 0 0 #15719f; 129 | } 130 | 131 | .ajax-upload-dragdrop 132 | { 133 | 134 | border:2px dotted #A5A5C7; 135 | width:600px; 136 | color: #DADCE3; 137 | text-align:left; 138 | vertical-align:middle; 139 | padding:10px 10px 0px 10px; 140 | } 141 | .state-hover 142 | { 143 | border:2px solid #A5A5C7; 144 | } 145 | .custom-container 146 | { 147 | margin:20px 0px 20px 0px; 148 | } 149 | -------------------------------------------------------------------------------- /assets/uploadfile/jquery-file-upload.css: -------------------------------------------------------------------------------- 1 | .ajax-file-upload-statusbar { 2 | border: 1px solid #0ba1b5; 3 | margin-top: 10px; 4 | width: 420px; 5 | margin-right: 10px; 6 | margin: 5px; 7 | -moz-border-radius: 4px; 8 | -webkit-border-radius: 4px; 9 | border-radius: 4px; 10 | padding: 5px 5px 5px 15px 11 | } 12 | 13 | .ajax-file-upload-filename { 14 | width: 300px; 15 | height: auto; 16 | margin: 0 5px 5px 0px; 17 | 18 | } 19 | 20 | .ajax-file-upload-filesize { 21 | width: 50px; 22 | height: auto; 23 | margin: 0 5px 5px 0px; 24 | display: inline-block; 25 | vertical-align:middle; 26 | } 27 | .ajax-file-upload-progress { 28 | margin: 5px 10px 5px 0px; 29 | position: relative; 30 | width: 250px; 31 | border: 1px solid #ddd; 32 | padding: 1px; 33 | border-radius: 3px; 34 | display: inline-block; 35 | color:#FFFFFF; 36 | 37 | } 38 | .ajax-file-upload-bar { 39 | background-color: #0ba1b5; 40 | width: 0; 41 | height: 20px; 42 | border-radius: 3px; 43 | color:#FFFFFF; 44 | 45 | } 46 | .ajax-file-upload-percent { 47 | position: absolute; 48 | display: inline-block; 49 | top: 3px; 50 | left: 48% 51 | } 52 | .ajax-file-upload-red { 53 | -moz-box-shadow: inset 0 39px 0 -24px #e67a73; 54 | -webkit-box-shadow: inset 0 39px 0 -24px #e67a73; 55 | box-shadow: inset 0 39px 0 -24px #e67a73; 56 | background-color: #e4685d; 57 | -moz-border-radius: 4px; 58 | -webkit-border-radius: 4px; 59 | border-radius: 4px; 60 | display: inline-block; 61 | color: #fff; 62 | font-family: arial; 63 | font-size: 13px; 64 | font-weight: normal; 65 | padding: 4px 15px; 66 | text-decoration: none; 67 | text-shadow: 0 1px 0 #b23e35; 68 | cursor: pointer; 69 | vertical-align: top; 70 | margin: 5px 10px 5px 0px; 71 | } 72 | .ajax-file-upload-green { 73 | background-color: #77b55a; 74 | -moz-border-radius: 4px; 75 | -webkit-border-radius: 4px; 76 | border-radius: 4px; 77 | margin: 0; 78 | padding: 0; 79 | display: inline-block; 80 | color: #fff; 81 | font-family: arial; 82 | font-size: 13px; 83 | font-weight: normal; 84 | padding: 4px 15px; 85 | text-decoration: none; 86 | cursor: pointer; 87 | text-shadow: 0 1px 0 #5b8a3c; 88 | vertical-align: top; 89 | margin: 5px 10px 5px 0px; 90 | } 91 | .ajax-file-upload { 92 | font-family: Arial, Helvetica, sans-serif; 93 | font-size: 16px; 94 | font-weight: bold; 95 | padding: 15px 20px; 96 | cursor:pointer; 97 | line-height:20px; 98 | height:25px; 99 | margin:0 10px 10px 0; 100 | display: inline-block; 101 | background: #fff; 102 | border: 1px solid #e8e8e8; 103 | color: #888; 104 | text-decoration: none; 105 | border-radius: 3px; 106 | -webkit-border-radius: 3px; 107 | -moz-border-radius: 3px; 108 | -moz-box-shadow: 0 2px 0 0 #e8e8e8; 109 | -webkit-box-shadow: 0 2px 0 0 #e8e8e8; 110 | box-shadow: 0 2px 0 0 #e8e8e8; 111 | padding: 6px 10px 4px 10px; 112 | color: #fff; 113 | background: #2f8ab9; 114 | border: none; 115 | -moz-box-shadow: 0 2px 0 0 #13648d; 116 | -webkit-box-shadow: 0 2px 0 0 #13648d; 117 | box-shadow: 0 2px 0 0 #13648d; 118 | vertical-align: middle; 119 | } 120 | 121 | .ajax-file-upload:hover { 122 | background: #3396c9; 123 | -moz-box-shadow: 0 2px 0 0 #15719f; 124 | -webkit-box-shadow: 0 2px 0 0 #15719f; 125 | box-shadow: 0 2px 0 0 #15719f; 126 | } 127 | 128 | .ajax-upload-dragdrop 129 | { 130 | 131 | border:2px dotted #A5A5C7; 132 | width:420px; 133 | color: #DADCE3; 134 | text-align:left; 135 | vertical-align:middle; 136 | padding:10px 10px 0px 10px; 137 | } 138 | 139 | .state-hover 140 | { 141 | border:2px solid #A5A5C7; 142 | } 143 | .ajax-file-upload-container 144 | { 145 | margin:20px 0px 20px 0px; 146 | } -------------------------------------------------------------------------------- /fragments/ycom_board_posts.php: -------------------------------------------------------------------------------- 1 | thread; 9 | $posts = $this->posts; 10 | $boardthis = $this->boardthis; 11 | ?> 12 | 13 | Zur Übersicht 14 | 15 |

getTitle() ?>

16 | 17 | 18 |

19 | Antworten 20 | isNotificationEnabled(rex_ycom_auth::getUser())): ?> 21 | Benachrichtigungen ausschalten 22 | 23 | Benachrichtigungen einschalten 24 | 25 |

26 | 27 | 28 | setVar('pager',$boardthis->getPager()); 31 | echo $fragment->parse('ycom_board_pagination.php'); 32 | ?> 33 | 34 | render('pagination.tpl.php') ?> 35 | 36 | 37 | 38 | 39 | 40 | 52 | 66 | 67 | 68 | 69 |
41 | getUserFullName() ?>

42 | getCreated('%d.%m.%Y, %H:%M Uhr')?> 43 | isBoardAdmin()): ?> 44 |

45 | 46 | Thread löschen 47 | 48 | Beitrag löschen 49 | 50 | 51 |
53 |

getTitle()) ?>

54 |

getMessage())) ?>

55 | hasAttachment()): ?> 56 |

Anhang:

57 | getRealAttachment(),true) ?> 58 | 59 |
60 | 61 |
Download
62 |
63 | 64 | 65 |
70 | 71 | 72 | parse('ycom_board_pagination.php'); ?> 73 | 74 | render('pagination.tpl.php') ?> 75 | 76 | 77 |

78 | Antworten 79 | isNotificationEnabled(rex_ycom_auth::getUser())): ?> 80 | Benachrichtigungen ausschalten 81 | 82 | Benachrichtigungen einschalten 83 | 84 |

85 | -------------------------------------------------------------------------------- /boot.php: -------------------------------------------------------------------------------- 1 | $file) { 53 | if ($file['origname'] == rex_post('name')) { 54 | $filePath = $output_dir. $file['realname']; 55 | if (file_exists($filePath)) { 56 | unlink($filePath); 57 | $deleted = $file['origname']; 58 | } 59 | unset($files[$k]); 60 | } 61 | } 62 | rex_set_session('ycom_board_file_upload',$files); 63 | echo "Deleted File ".$deleted."
"; 64 | exit; 65 | } 66 | 67 | if (rex_request::isXmlHttpRequest() && rex_request('action') == 'ycom_board_form_load') { 68 | $dir="media/ycom_board"; 69 | $files = rex_session('ycom_board_file_upload','array'); 70 | $ret= array(); 71 | foreach($files as $k=>$file) 72 | { 73 | if($file['realname'] == "." || $file['realname'] == "..") 74 | continue; 75 | // $filename = substr($file,strpos($file,'_')+1); 76 | $filename = $file['realname']; 77 | $filePath=$dir."/".$file['realname']; 78 | $details = array(); 79 | $details['name']=$file['origname']; 80 | $details['path']='/'.$filePath; 81 | if (file_exists($filePath)) { 82 | $details['size']=filesize($filePath); 83 | $ret[] = $details; 84 | } else { 85 | unset($files[$k]); 86 | } 87 | } 88 | rex_set_session('ycom_board_file_upload',$files); 89 | echo json_encode($ret); 90 | exit; 91 | } 92 | 93 | rex_extension::register('REX_YFORM_SAVED',function($ep) { 94 | $params = $ep->getParams(); 95 | if ($params['table'] == rex::getTable('ycom_board_post') && $params['action'] == 'insert' && $params['yform'] == true) { 96 | $id = $params['id']; 97 | $sql = rex_sql::factory(); 98 | // $sql->setDebug(); 99 | $sql->setTable(rex::getTable('ycom_board_post')); 100 | $sql->setValue('attachment',json_encode(rex_session('ycom_board_file_upload','array'))); 101 | $sql->setWhere('id = :id',['id'=>$id]); 102 | $sql->update(); 103 | rex_set_session('ycom_board_file_upload',[]); 104 | // exit; 105 | } 106 | }); 107 | 108 | // rex_extension::registerPoint(new rex_extension_point('YFORM_DATA_ADD', $yform, ['table' => $this->getTable(), 'data' => $this])); 109 | 110 | 111 | 112 | } 113 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | YCom Board für REDAXO 5.8 2 | ========================= 3 | 4 | 5 | Beschreibung 6 | ------------ 7 | Das Board ist ein einfaches AddOn, um ein einfaches Messageboard für die YCom zu realisieren. Das AddOn wurde von einer 4er Version migriert. 8 | 9 | 10 | Installation 11 | ------------ 12 | 13 | * Die Dateien in das Verzeichnis redaxo/src/addons/ycom_board kopieren 14 | * Über die AddOn Verwaltung das AddOn installieren. Die notwendigen Datenbanktabellen werden dabei angelegt 15 | * Bei Bedarf das Modul über den Menüpunkt im Backend Community/Einstellungen dann im Reiter YCom Board installieren 16 | * Auf den Seiten, auf denen das Board verwendet werden soll das Modul platzieren. 17 | 18 | 19 | Konfiguration 20 | ------------- 21 | 22 | Das Modul des Boards erkennt, ob ein YCom Benutzer eingeloggt ist oder nicht. Wenn kein Benutzer eingeloggt ist, wird auch kein Eingabeformular angezeigt. Lediglich eingeloggte Benutzer können Meldungen schreiben. 23 | Man kann sich als eingeloggter YCom Benutzer Benachrichtigungen schicken lassen, wenn neue Meldungen für ein Thema eingetragen werden. 24 | Die Administration der Meldungen erfolgt über YForm Tabellen im REDAXO Backend. 25 | Es können innerhalb einer Seite neue Themen im Board erstellt werden und hierauf Beiträge folgen. Eine weitere Verschachtelung der Beiträge ist nicht möglich. 26 | 27 | Es muss noch ein E-Mail Template erstellt werden, das für die Benachrichtigung bei neuen Beiträgen verwendet wird. 28 | 29 | --------- 30 | ``` 31 | Guten Tag REX_YFORM_DATA[field="username"], 32 | 33 | Sie haben die automatische Benachrichtigung für neue Einträge im Messageboard bei Vielfalt Schule eingerichtet. 34 | 35 | Zum Thema "REX_YFORM_DATA[field='thread_title']" gibt es einen neuen Eintrag. 36 | 37 | REX_YFORM_DATA[field="post_url"] 38 | 39 | Sie können die automatische Benachrichtigung abstellen, indem Sie sich im Board einloggen und beim entsprechenden Thread auf "Benachrichtigung abstellen" klicken. 40 | ``` 41 | --------- 42 | 43 | 44 | 45 | Funktionen 46 | ---------- 47 | 48 | Das Board kann bei neuen Themen E-Mail Benachrichtigungen an alle Teilnehmer schicken. In den Einstellungen des Boards kann man eine oder mehrere Benutzergruppen festlegen, die keine Benachrichtigungsmail bekommen. So kann man beispielsweise die Benutzergruppe _no_messages_ einrichten. Wenn ein Benutzer Mitglied dieser Gruppe ist und dies in den Einstellungen so definiert ist, erhält er keine Benachrichtigungen bei neuen Themen. Wenn der Status eines Benutzers kleiner als 1 ist, wird ebenfalls keine Benachrichtigung verschickt. 49 | 50 | Für die Benachrichtigungsmail muss ein E-Mail Template angelegt werden. 51 | 52 | Im E-Mail Template sind folgende Felder verfügbar: 53 | 54 | firstname - Vorname des Empfängers für personalisierte Mails 55 | name - Nachname des Empfängers für personalisierte Mails 56 | email - E-Mail des Empfängers 57 | url - Adresse (ohne Server) der Seite auf der das neue Thema gepostet wurde 58 | title - Titel des neuen Themas 59 | message - Text des neuen Themas 60 | 61 | Mustertemplate: 62 | 63 | --- 64 | ``` 65 | Hallo REX_YFORM_DATA[field="firstname"] REX_YFORM_DATA[field="name"] 66 | 67 | Soeben wurde ein neuer Beitrag im Forum gepostet. 68 | 69 | REX_YFORM_DATA[field="url"] 70 | 71 | Titel: REX_YFORM_DATA[field="title"] 72 | 73 | Text: 74 | REX_YFORM_DATA[field="message"] 75 | 76 | 77 | Sie erhalten diese Mail, weil Sie Mitglied im Forum sind. Wenn Sie sich abmelden, bekommen Sie keine Mails mehr. 78 | ``` 79 | --- 80 | 81 | In der YCom muss eine Gruppe erstellt werden, die als Board Admin Gruppe im Modul für jedes Board festgelegt werden kann. (Momentan noch ohne Funktion). 82 | 83 | 84 | Multiuploadfeld 85 | --------------- 86 | 87 | Das Board ist mit einem Multiuploadfeld ausgestattet. Damit können zu Beiträgen Dateien hochgeladen werden. Die hochgeladenen Dateien landen im Verzeichnis /media/ycom_board. Die Dateinamen werden gemäß REDAXO-Konvention normalisiert. Zusätzlich wird dem Dateinamen ein Timestamp und ein Unterstrich vorangestellt. Damit können auch Dateien gleichen Namens hochgeladen werden. Die Dateinamen werden in der Tabelle rex_ycom_board_post im Feld attachment als json abgelegt. Sowohl der Originalname (nicht normalisiert) als auch der Filename werden gespeichert. Die Files können nicht verwaltet werden. Die Ausgabe kann über einen Media Effekt vorgenommen werden. 88 | 89 | Um das Multiuploadfeld im Frontend nutzen zu können, müssen noch folgende Zeilen ins REDAXO Template vor den schließendene body. 90 | 91 | ``` 92 | 93 | 94 | 95 | ``` 96 | 97 | In den Head noch: 98 | ``` 99 | 100 | 101 | 102 | ``` 103 | 104 | Das Multiuploadfeld wird nur bei eingeloggten YCom Usern benötigt. 105 | 106 | Fragmente 107 | --------- 108 | 109 | Die Frontendausgabe des Boards wird über Fragmente realisiert. Die Fragmente liegen im Addon Verzeichnis fragments. Wenn eine eigene Ausgabe realisiert werden soll, empfiehlt es sich die Fragmente in ein eigenes Fragments Verzeichnis zu kopieren und zu modifizieren. z.B. in das Projekt AddOn oder ins Theme. Mehr dazu in der REDAXO Doku. 110 | 111 | Credits 112 | ------- 113 | 114 | Die Portierung des AddOns von R4 nach R5 wurde zum großen Teil finanziert durch 115 | Polarpixel 116 | Thomas Rotzek -------------------------------------------------------------------------------- /pages/settings.php: -------------------------------------------------------------------------------- 1 | addFieldset('YCom Board - Einstellungen'); 11 | 12 | $res = rex_sql::factory()->getArray('SELECT name FROM '.rex::getTable('yform_email_template')); 13 | $options = array_column($res, 'name'); 14 | 15 | $field = $form->addSelectField('email_template_new_thread'); 16 | $field->setLabel('E-Mail Template neues Thema'); 17 | $select = $field->getSelect(); 18 | $select->addOption('Bitte auswählen ...',''); 19 | $select->addOptions($options,true); 20 | $field->setNotice('rex_config::get("ycom_board","email_template_new_thread")'); 21 | 22 | $field = $form->addCheckboxField('send_new_thread_mail'); 23 | $field->setLabel('E-Mail Benachrichtigung'); 24 | $field->addOption('E-Mails an Teilnehmer senden, wenn neues Hauptthema erstellt wird.', "1"); 25 | $field->setNotice('rex_config::get("ycom_board","send_new_thread_mail")'); 26 | 27 | 28 | $field = $form->addSelectField('groups_no_messages',null,['class'=>'selectpicker form-control']); 29 | $field->setLabel('Gruppen, an die die keine Benachrichtigungen geschickt werden'); 30 | $select = $field->getSelect(); 31 | $select->addSqlOptions('SELECT name label, id value FROM '.rex::getTable('ycom_group')); 32 | $select->setMultiple(); 33 | $field->setNotice('rex_config::get("ycom_board","groups_no_messages")'); 34 | 35 | $content = $form->get(); 36 | 37 | $fragment = new rex_fragment(); 38 | $fragment->setVar('title', 'Einstellungen'); 39 | $fragment->setVar('body', $content, false); 40 | $content = $fragment->parse('core/page/section.php'); 41 | 42 | echo $content; 43 | 44 | 45 | /* 46 | $field = $form->addLinkmapField('cart_page'); 47 | $field->setLabel('Warenkorbseite'); 48 | $field->setNotice('rex_config::get("warehouse","cart_page")'); 49 | 50 | $field = $form->addLinkmapField('address_page'); 51 | $field->setLabel('Adresseingabe Seite'); 52 | $field->setNotice('rex_config::get("warehouse","address_page")'); 53 | 54 | $field = $form->addLinkmapField('order_page'); 55 | $field->setLabel('Bestellung Seite'); 56 | $field->setNotice('rex_config::get("warehouse","order_page")'); 57 | 58 | $field = $form->addLinkmapField('thankyou_page'); 59 | $field->setLabel('Danke Seite'); 60 | $field->setNotice('rex_config::get("warehouse","thankyou_page")'); 61 | 62 | $field = $form->addLinkmapField('shippinginfo_page'); 63 | $field->setLabel('Versandkosten Info'); 64 | $field->setNotice('rex_config::get("warehouse","shippinginfo_page")'); 65 | 66 | $field = $form->addLinkmapField('my_orders_page'); 67 | $field->setLabel('Meine Bestellungen'); 68 | $field->setNotice('rex_config::get("warehouse","my_orders_page")'); 69 | 70 | $field = $form->addTextField('currency'); 71 | $field->setLabel('Währung (z.B. EUR)'); 72 | $field->setNotice('rex_config::get("warehouse","currency")'); 73 | // $field->setNotice('Es können mehrere Adressen angegeben werden. Adressen bitte mit Komma trennen.'); 74 | 75 | $field = $form->addTextField('currency_symbol'); 76 | $field->setLabel('Währungssymbol (z.B. €)'); 77 | $field->setNotice('rex_config::get("warehouse","currency_symbol")'); 78 | 79 | $field = $form->addTextField('tax_value'); 80 | $field->setLabel('Steuersatz [%]'); 81 | $field->setNotice('rex_config::get("warehouse","tax_value")'); 82 | 83 | $field = $form->addTextField('tax_value_1'); 84 | $field->setLabel('Steuersatz 1 [%]'); 85 | $field->setNotice('rex_config::get("warehouse","tax_value_1")'); 86 | 87 | $field = $form->addTextField('tax_value_2'); 88 | $field->setLabel('Steuersatz 2 [%]'); 89 | $field->setNotice('rex_config::get("warehouse","tax_value_2")'); 90 | 91 | $field = $form->addTextField('tax_value_3'); 92 | $field->setLabel('Steuersatz 3 [%]'); 93 | $field->setNotice('rex_config::get("warehouse","tax_value_3")'); 94 | 95 | $field = $form->addTextField('tax_value_4'); 96 | $field->setLabel('Steuersatz 4 [%]'); 97 | $field->setNotice('rex_config::get("warehouse","tax_value_4")'); 98 | 99 | $field = $form->addTextField('country_codes'); 100 | $field->setLabel('Mögliche Länder für die Lieferung'); 101 | $field->setNotice('Als JSON in der Form {"Deutschland":"DE","Österreich":"AT","Schweiz":"CH"} angeben.
rex_config::get("warehouse","country_codes")'); 102 | 103 | $field = $form->addSelectField('cart_mode'); 104 | $field->setLabel('Warenkorb Modus'); 105 | $select = $field->getSelect(); 106 | $select->addOptions([ 107 | 'cart'=>'Warenkorb', 108 | 'page'=>'Artikelseite' 109 | ]); 110 | $field->setNotice('Es kann entweder die Warenkorbseite aufgerufen werden oder die vorherige Artikelseite. Wenn die Artikelseite aufgerufen wird, so wird showcart=1 als Get-Parameter angehängt.
rex_config::get("warehouse","cart_mode")'); 111 | 112 | $res = rex_sql::factory()->getArray('SELECT name FROM '.rex::getTable('yform_email_template')); 113 | $options = array_column($res, 'name'); 114 | 115 | $field = $form->addSelectField('email_template_customer'); 116 | $field->setLabel('E-Mail Template Kunde'); 117 | $select = $field->getSelect(); 118 | $select->addOptions($options,true); 119 | $field->setNotice('rex_config::get("warehouse","email_template_customer")'); 120 | 121 | $field = $form->addSelectField('email_template_seller'); 122 | $field->setLabel('E-Mail Template Bestellung'); 123 | $select = $field->getSelect(); 124 | $select->addOptions($options,true); 125 | $field->setNotice('rex_config::get("warehouse","email_template_seller")'); 126 | 127 | $field = $form->addTextField('order_email'); 128 | $field->setLabel('Bestellungen E-Mail Empfänger'); 129 | $field->setNotice('Mehrere E-Mail Empfänger können mit Komma getrennt werden.
rex_config::get("warehouse","order_email")'); 130 | 131 | // ==== Paypal 132 | 133 | $form->addFieldset('Paypal Einstellungen'); 134 | 135 | $field = $form->addTextField('paypal_client_id'); 136 | $field->setLabel('Paypal Client Id'); 137 | 138 | $field = $form->addTextField('paypal_secret'); 139 | $field->setLabel('Paypal Secret'); 140 | 141 | $field = $form->addCheckboxField('sandboxmode'); 142 | $field->setLabel('Paypal Sandbox ein'); 143 | $field->addOption('Paypal Sandbox ein', "1"); 144 | 145 | 146 | $field = $form->addTextField('paypal_sandbox_client_id'); 147 | $field->setLabel('Paypal Sandbox Client Id'); 148 | 149 | $field = $form->addTextField('paypal_sandbox_secret'); 150 | $field->setLabel('Paypal Sandbox Secret'); 151 | 152 | $field = $form->addTextField('paypal_getparams'); 153 | $field->setLabel('Paypal Zusätzliche Get-Parameter für Paypal'); 154 | $field->setNotice('z.B. um Maintenance bei der Entwicklung zu verwenden. Als JSON in der Form {"key1":"value1","key2":"value2"} angeben.'); 155 | 156 | $field = $form->addLinkmapField('paypal_page_start'); 157 | $field->setLabel('Paypal Startseite'); 158 | $field->setNotice('rex_config::get("warehouse","paypal_page_start")'); 159 | 160 | $field = $form->addLinkmapField('paypal_page_success'); 161 | $field->setLabel('Paypal Zahlung erfolgt'); 162 | $field->setNotice('rex_config::get("warehouse","paypal_page_success")'); 163 | 164 | $field = $form->addLinkmapField('paypal_page_error'); 165 | $field->setLabel('Paypal Fehler'); 166 | $field->setNotice('rex_config::get("warehouse","paypal_page_error")'); 167 | 168 | 169 | // ==== Giropay 170 | 171 | $form->addFieldset('Giropay Einstellungen'); 172 | 173 | $field = $form->addTextField('giropay_merchand_id'); 174 | $field->setLabel('Giropay Merchand Id'); 175 | 176 | $field = $form->addTextField('giropay_project_id'); 177 | $field->setLabel('Giropay Projekt Id'); 178 | 179 | $field = $form->addTextField('giropay_project_pw'); 180 | $field->setLabel('Giropay Projekt Passwort'); 181 | 182 | $field = $form->addLinkmapField('giropay_page_start'); 183 | $field->setLabel('Giropay Startseite'); 184 | $field->setNotice('rex_config::get("warehouse","giropay_page_start")'); 185 | 186 | $field = $form->addLinkmapField('giropay_page_notify'); 187 | $field->setLabel('Giropay Antwortseite'); 188 | $field->setNotice('rex_config::get("warehouse","giropay_page_notify")'); 189 | 190 | $field = $form->addLinkmapField('giropay_page_error'); 191 | $field->setLabel('Giropay Fehler'); 192 | $field->setNotice('rex_config::get("warehouse","giropay_page_error")'); 193 | 194 | 195 | 196 | // ==== Frachtrechnung 197 | 198 | $form->addFieldset('Frachtrechnung'); 199 | 200 | $field = $form->addTextField('shipping'); 201 | $field->setLabel('Versandkosten Standard'); 202 | $field->setNotice('Kann leer bleiben, wenn Sonderfrachtberechnung definiert ist.'); 203 | 204 | $field = $form->addSelectField('shipping_mode'); 205 | $field->setLabel('Frachtberechnung'); 206 | $select = $field->getSelect(); 207 | $select->addOptions([ 208 | 0 => 'Standard (Pauschal)', 209 | 'pieces' => 'nach Stück', 210 | 'order_total' => 'Betrag (brutto)', 211 | ]); 212 | 213 | $field = $form->addTextField('shipping_parameters'); 214 | $field->setLabel('Fracht Parameter'); 215 | $field->setNotice('Paramter für die Frachtberechnung. Als JSON in der Form [[">",4,10.5],[">",2,7.9],[">",0,5.9]] angeben. Jede Bedingung besteht aus drei Elementen. Als Kondition sind die Angaben >, ' 216 | . '<, >=, <= oder = möglich. Der zweite Wert steht für die Anzahl, der dritte für den Frachtpreis. Die erste Bedingung die erfüllt ist, wird für die Frachtberechnung verwendet. Wenn keine Bedingung erfüllt ist, wird der Standardfrachtpreis berechnet.'); 217 | 218 | // ==== Frachtrechnung 219 | 220 | $form->addFieldset('Alterscheck'); 221 | 222 | $field = $form->addCheckboxField('agecheck'); 223 | $field->setLabel('Alterscheck aktivieren'); 224 | $field->addOption('Alterscheck aktivieren', "1"); 225 | $field->setNotice('Wenn der Alterscheck aktiviert ist, kann eine Erstbestellung nur per giropay Alterscheck ausgeführt werden. Wenn der Besucher über die Community eingeloggt ist, wird der Alterscheck in der Community gespeichert. Wenn der Alterscheck in der Community gespeichert ist und der Benutzer eingeloggt ist, kann er auch mit anderen Zahlungsweisen bezahlen.'); 226 | 227 | 228 | */ 229 | -------------------------------------------------------------------------------- /install/tablesets/ycom_board.json: -------------------------------------------------------------------------------- 1 | {"rex_ycom_board_post":{"table":{"id":"6","status":"1","table_name":"rex_ycom_board_post","name":"translate:com_board_name","description":"","list_amount":"50","list_sortfield":"created","list_sortorder":"DESC","prio":"3","search":"1","hidden":"0","export":"1","import":"1","mass_deletion":"0","mass_edit":"0","schema_overwrite":"1","history":"0"},"fields":[{"id":"47","table_name":"rex_ycom_board_post","prio":"1","type_id":"value","type_name":"text","db_type":"","list_hidden":"1","search":"1","name":"board_key","label":"translate:com_board_key","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"48","table_name":"rex_ycom_board_post","prio":"2","type_id":"value","type_name":"be_manager_relation","db_type":"","list_hidden":"1","search":"1","name":"thread_id","label":"translate:com_board_thread","not_required":"","options":"","multiple":"","default":"","size":"1","only_empty":"","message":"","table":"rex_ycom_board_post","hashname":"","password_hash":"","no_db":"","password_label":"","field":"title","type":"2","empty_value":"","empty_option":"1","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"49","table_name":"rex_ycom_board_post","prio":"3","type_id":"value","type_name":"text","db_type":"","list_hidden":"0","search":"1","name":"title","label":"translate:com_board_title","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"50","table_name":"rex_ycom_board_post","prio":"4","type_id":"validate","type_name":"empty","db_type":"","list_hidden":"1","search":"0","name":"title","label":"","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"\n\n\ntranslate:com_board_enter_title","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"51","table_name":"rex_ycom_board_post","prio":"5","type_id":"value","type_name":"textarea","db_type":"","list_hidden":"0","search":"1","name":"message","label":"translate:com_board_message","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"52","table_name":"rex_ycom_board_post","prio":"6","type_id":"validate","type_name":"empty","db_type":"","list_hidden":"1","search":"0","name":"message","label":"","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"\n\n\ntranslate:com_board_enter_message","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"53","table_name":"rex_ycom_board_post","prio":"7","type_id":"value","type_name":"be_manager_relation","db_type":"","list_hidden":"0","search":"1","name":"user_id","label":"translate:com_user","not_required":"","options":"","multiple":"","default":"","size":"1","only_empty":"","message":"","table":"rex_ycom_user","hashname":"","password_hash":"","no_db":"","password_label":"","field":"firstname, \" \", name","type":"2","empty_value":"","empty_option":"1","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"54","table_name":"rex_ycom_board_post","prio":"8","type_id":"value","type_name":"checkbox","db_type":"","list_hidden":"0","search":"1","name":"status","label":"translate:status","not_required":"","options":"","multiple":"","default":"1","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"55","table_name":"rex_ycom_board_post","prio":"9","type_id":"value","type_name":"datestamp","db_type":"datetime","list_hidden":"1","search":"1","name":"created","label":"mysql","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"1","message":"","table":"","hashname":"","password_hash":"","no_db":"0","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"0","html":"","notice":"","regex":"","pattern":"","format":"Y-m-d H:i:s","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"56","table_name":"rex_ycom_board_post","prio":"10","type_id":"value","type_name":"datestamp","db_type":"","list_hidden":"1","search":"1","name":"updated","label":"mysql","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"0","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"57","table_name":"rex_ycom_board_post","prio":"11","type_id":"value","type_name":"be_manager_relation","db_type":"","list_hidden":"1","search":"0","name":"notifications","label":"translate:com_board_notifications","not_required":"","options":"","multiple":"","default":"","size":"10","only_empty":"","message":"","table":"rex_ycom_user","hashname":"","password_hash":"","no_db":"","password_label":"","field":"firstname, \" \", name","type":"3","empty_value":"","empty_option":"1","max_size":"","types":"","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"","messages":"","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""},{"id":"60","table_name":"rex_ycom_board_post","prio":"12","type_id":"value","type_name":"upload","db_type":"text","list_hidden":"1","search":"0","name":"attachment","label":"Anhang","not_required":"","options":"","multiple":"","default":"","size":"","only_empty":"","message":"","table":"","hashname":"","password_hash":"","no_db":"","password_label":"","field":"","type":"","empty_value":"","empty_option":"","max_size":"","types":".gif,.png,.jpg","fields":"","position":"","address":"","width":"","height":"","show_value":"","html":"","notice":"","regex":"","pattern":"","format":"","current_date":"","widget":"","attributes":"","query":"","category":"","year_start":"","year_end":"","values":"","rules":"","nonce_key":"","nonce_referer":"","sizes":"0,2000","messages":"Die Datei ist zu klein,Die Datei ist zu gro\u00df - sie darf max. 2 MB gro\u00df sein,Keine Datei hochgeladen,Datei gel\u00f6scht.","rules_message":"","script":"","max":"","infotext_1":"","infotext_2":"","choices":"","expanded":"","scope":"","columns":"","googleapikey":"","unit":"","precision":"","scale":"","preview":""}]}} -------------------------------------------------------------------------------- /lib/rex_ycom_board.php: -------------------------------------------------------------------------------- 1 | setKey($key); 19 | $this->setName($name); 20 | } 21 | 22 | public function getName() 23 | { 24 | return $this->name; 25 | } 26 | 27 | public function setName($name) 28 | { 29 | $this->name = $name; 30 | } 31 | 32 | public function getKey() 33 | { 34 | return $this->key; 35 | } 36 | 37 | public function setKey($key) 38 | { 39 | $this->key = $key; 40 | } 41 | 42 | public function setUrl($url) 43 | { 44 | $this->url = $url; 45 | } 46 | 47 | public function getPager() 48 | { 49 | return $this->pager; 50 | } 51 | 52 | public function setThreadsPerPage($threadsPerPage) 53 | { 54 | $this->threadsPerPage = $threadsPerPage; 55 | } 56 | 57 | public function setPostsPerPage($postsPerPage) 58 | { 59 | $this->postsPerPage = $postsPerPage; 60 | } 61 | 62 | public function setNotificationTemplate($notificationTemplate) 63 | { 64 | $this->notificationTemplate = $notificationTemplate; 65 | } 66 | 67 | public function setAdminGroup($groupId) 68 | { 69 | $this->adminGroup = $groupId; 70 | } 71 | 72 | public function isBoardAdmin(rex_ycom_user $user = null) 73 | { 74 | $user = $user ?: rex_ycom_auth::getUser(); 75 | 76 | if (!$user || !$this->adminGroup) { 77 | return false; 78 | } 79 | 80 | $groups = explode(',', $user->getValue('rex_ycom_group')); 81 | return in_array($this->adminGroup, $groups); 82 | } 83 | 84 | public function getUrl(array $params = array()) 85 | { 86 | $url = $this->url; 87 | 88 | if ($params) { 89 | $url .= false === strpos($url, '?') ? '?' : '&'; 90 | $url .= http_build_query($params, null, '&'); 91 | } 92 | 93 | return $url; 94 | } 95 | 96 | public function getCurrentUrl(array $params = array()) 97 | { 98 | $defaultParams = array( 99 | 'function' => rex_get('function', 'string'), 100 | 'thread' => rex_get('thread', 'int'), 101 | 'start' => rex_get('start', 'int'), 102 | ); 103 | 104 | $params = array_merge($defaultParams, $params); 105 | $params = array_filter($params); 106 | 107 | return $this->getUrl($params); 108 | } 109 | 110 | public function getPostUrl(rex_ycom_board_post $post) 111 | { 112 | return $this->getUrl(array('thread' => $post->getThreadId(), 'post' => $post->getId())) . '#' . $this->getPostIdAttribute($post); 113 | } 114 | 115 | public function getPostIdAttribute($post) 116 | { 117 | if ($post instanceof rex_ycom_board_post) { 118 | $post = $post->getId(); 119 | } 120 | 121 | return sprintf('board-%s-post-%d', $this->getKey(), $post); 122 | } 123 | 124 | public function getPostDeleteUrl(rex_ycom_board_post $post) 125 | { 126 | return $this->getCurrentUrl(array( 127 | 'post' => $post->getId(), 128 | 'function' => 'delete', 129 | )); 130 | } 131 | 132 | public function getAttachmentUrl(rex_ycom_board_post $post) 133 | { 134 | return $this->getUrl(array('thread' => $post->getThreadId(), 'post' => $post->getId(), 'function' => 'attachment_download')); 135 | } 136 | 137 | /** 138 | * @return rex_ycom_board_thread[] 139 | */ 140 | public function getThreads() 141 | { 142 | $this->pager = new rex_pager($this->threadsPerPage); 143 | 144 | return $this->getPosts( 145 | 'thread_id = ""', 146 | '(SELECT MAX(created) FROM rex_ycom_board_post p2 WHERE (p2.thread_id = p.id OR p2.id = p.id) AND status = 1) DESC' 147 | ); 148 | } 149 | 150 | /** 151 | * @param rex_ycom_board_thread $thread 152 | * @param int $findPost 153 | * 154 | * @return rex_ycom_board_post[] 155 | */ 156 | public function getThreadPosts(rex_ycom_board_thread $thread, rex_ycom_board_post $findPost = null) 157 | { 158 | $this->pager = new rex_pager($this->postsPerPage); 159 | 160 | return $this->getPosts( 161 | sprintf('thread_id = %d OR id = %1$d', $thread->getId()), 162 | 'created ASC', 163 | $findPost 164 | ); 165 | } 166 | 167 | public function getPosts($where = '', $order = 'created ASC', rex_ycom_board_post $findPost = null) 168 | { 169 | $db = rex_sql::factory(); 170 | // $db->setDebug(); 171 | 172 | $where = sprintf(' WHERE board_key = "%s" AND status = 1 AND (%s)', $this->getKey(), $where); 173 | 174 | $db->setQuery('SELECT COUNT(*) as count FROM rex_ycom_board_post p '.$where); 175 | $count = $db->getValue('count'); 176 | 177 | $this->pager->setRowCount($count); 178 | 179 | $order = 'ORDER BY '.$order; 180 | 181 | if ($findPost) { 182 | $db->setQuery('SELECT COUNT(*) as count FROM rex_ycom_board_post p '.$where.' AND created < (SELECT created FROM rex_ycom_board_post WHERE id = '.((int) $findPost->getId()).')'.$order); 183 | if ($db->getRows()) { 184 | $lessCount = $db->getValue('count'); 185 | 186 | $cursor = ((int) ($lessCount / $this->pager->getRowsPerPage())) * $this->pager->getRowsPerPage(); 187 | $cursor = $this->pager->validateCursor($cursor); 188 | $_REQUEST[$this->pager->getCursorName()] = $cursor; 189 | } 190 | } 191 | 192 | $limit = ' LIMIT '.$this->pager->getCursor().', '.$this->pager->getRowsPerPage(); 193 | 194 | $posts_sql = $db->getArray('select * from rex_ycom_board_post p '.$where.$order.$limit); 195 | 196 | $posts = array(); 197 | foreach ($posts_sql as $data) { 198 | if ($data['thread_id']) { 199 | $posts[] = new rex_ycom_board_post($data); 200 | } else { 201 | $posts[] = new rex_ycom_board_thread($data); 202 | } 203 | } 204 | return $posts; 205 | } 206 | 207 | /** 208 | * @param int $id 209 | * @return null|rex_ycom_board_post|rex_ycom_board_thread 210 | */ 211 | public function getPost($id) 212 | { 213 | $sql = rex_sql::factory(); 214 | $sql->setQuery('SELECT * FROM rex_ycom_board_post WHERE status = 1 and id = ' . (int) $id); 215 | 216 | if (!$sql->getRows()) { 217 | return null; 218 | } 219 | 220 | $data = $sql->getRow(); 221 | if ($data['thread_id']) { 222 | return new rex_ycom_board_post($data); 223 | } 224 | 225 | return new rex_ycom_board_thread($data); 226 | } 227 | 228 | public function getView() 229 | { 230 | $thread = rex_get('thread', 'int'); 231 | $function = rex_get('function', 'string'); 232 | 233 | if ($thread) { 234 | $thread = rex_ycom_board_thread::get($thread); 235 | } 236 | 237 | if (!$thread) { 238 | if ('create_thread' === $function) { 239 | $yform = $this->getForm(); 240 | $form = $yform->getForm(); 241 | 242 | if ($yform->getObjectparams('actions_executed')) { 243 | $thread = rex_ycom_board_thread::get($yform->getObjectparams('main_id')); 244 | 245 | if (isset($yform->objparams['value_pool']['email']['notifications']) && $yform->objparams['value_pool']['email']['notifications']) { 246 | $thread->addNotificationUser(rex_ycom_auth::getUser()); 247 | } 248 | 249 | // Notification Emails an alle schicken 250 | if (rex_config::get('ycom_board','send_new_thread_mail')) { 251 | ycom_board_message::send_messages($thread); 252 | } 253 | 254 | if ($thread && $thread->getId()) { 255 | header('Location: ' . htmlspecialchars_decode($this->getUrl(array('thread' => $thread->getId())))); 256 | exit; 257 | } 258 | } 259 | $fragment = new rex_fragment(); 260 | $fragment->setVar('form',$form, false); 261 | $fragment->setVar('thread',$thread); 262 | $fragment->setVar('boardthis',$this); 263 | echo $fragment->parse('ycom_board_createform.php'); 264 | 265 | // return $this->render('thread.create.tpl.php', compact('form')); 266 | } 267 | 268 | $threads = $this->getThreads(); 269 | // dump($threads); 270 | // return $this->render('threads.tpl.php', compact('threads')); 271 | $fragment = new rex_fragment(); 272 | $fragment->setVar('threads',$threads); 273 | $fragment->setVar('boardthis',$this); 274 | echo $fragment->parse('ycom_board_threads.php'); 275 | } 276 | 277 | if ('enable_notifications' === $function) { 278 | $thread->addNotificationUser(rex_ycom_auth::getUser()); 279 | } 280 | if ('disable_notifications' === $function) { 281 | $thread->removeNotificationUser(rex_ycom_auth::getUser()); 282 | } 283 | 284 | if ('create_post' === $function) { 285 | $yform = $this->getForm(); 286 | $yform->setValueField('hidden', array('thread_id', 'thread','REQUEST')); 287 | $yform->setValueField('objparams', array('value.title.default', 'Re: ' . $thread->getTitle(), '')); 288 | 289 | $form = $yform->getForm(); 290 | 291 | if ($yform->getObjectparams('actions_executed')) { 292 | $post = rex_ycom_board_post::get($yform->getObjectparams('main_id')); 293 | 294 | $this->sendNotifications($thread, $post); 295 | 296 | if (isset($yform->objparams['value_pool']['email']['notifications']) && $yform->objparams['value_pool']['email']['notifications']) { 297 | $thread->addNotificationUser(rex_ycom_auth::getUser()); 298 | } 299 | 300 | header('Location: ' . htmlspecialchars_decode($this->getPostUrl($post))); 301 | exit; 302 | } 303 | 304 | $fragment = new rex_fragment(); 305 | $fragment->setVar('form',$form, false); 306 | $fragment->setVar('thread',$thread); 307 | $fragment->setVar('boardthis',$this); 308 | echo $fragment->parse('ycom_board_createform.php'); 309 | 310 | // return $this->render('post.create.tpl.php', compact('thread', 'form')); 311 | } 312 | 313 | if ('delete' === $function && $this->isBoardAdmin() && ($id = rex_get('post', 'int')) && $post = $this->getPost($id)) { 314 | $this->deletePost($post); 315 | 316 | $params = array(); 317 | if (!$post instanceof rex_ycom_board_thread) { 318 | $params = array( 319 | 'thread' => rex_get('thread', 'int'), 320 | 'start' => rex_get('start', 'int'), 321 | ); 322 | } 323 | header('Location: ' . htmlspecialchars_decode($this->getUrl($params))); 324 | exit; 325 | } 326 | 327 | $post = null; 328 | if ($postId = rex_get('post', 'int')) { 329 | $post = rex_ycom_board_post::get($postId); 330 | } 331 | 332 | if ($post && 'attachment_download' === $function) { 333 | $this->sendAttachment($post); 334 | exit; 335 | } 336 | 337 | if ($thread) { 338 | $posts = $this->getThreadPosts($thread, $post); 339 | 340 | $fragment = new rex_fragment(); 341 | $fragment->setVar('posts',$posts); 342 | $fragment->setVar('boardthis',$this); 343 | $fragment->setVar('thread',$thread); 344 | echo $fragment->parse('ycom_board_posts.php'); 345 | } 346 | 347 | 348 | // dump($posts); 349 | // return $this->render('posts.tpl.php', compact('thread', 'posts')); 350 | } 351 | 352 | private function deletePost(rex_ycom_board_post $post) 353 | { 354 | $sql = rex_sql::factory(); 355 | 356 | if (!$post instanceof rex_ycom_board_thread) { 357 | if ($post->hasAttachment()) { 358 | $file = rex_path::addonData('ycom_board', 'attachments/'.$post->getRealAttachment()); 359 | rex_file::delete($file); 360 | } 361 | 362 | $sql->setQuery('DELETE FROM rex_ycom_board_post WHERE id = '.(int) $post->getId()); 363 | return; 364 | } 365 | 366 | $where = 'id = '.(int) $post->getId().' OR thread_id = '.(int) $post->getId(); 367 | $attachments = $sql->getArray('SELECT attachment FROM rex_ycom_board_post WHERE attachment != "" AND ('.$where.')'); 368 | foreach ($attachments as $attachment) { 369 | $file = rex_path::addonData('ycom_board', 'attachments/'.$attachment['attachment']); 370 | rex_file::delete($file); 371 | } 372 | 373 | $sql->setQuery('DELETE FROM rex_ycom_board_post WHERE '.$where); 374 | } 375 | 376 | private function getForm() 377 | { 378 | $yform = new rex_yform(); 379 | $yform->setObjectparams('real_field_names', true); 380 | $yform->setObjectparams('form_action', $this->getCurrentUrl()); 381 | 382 | $yform->setValueField('hidden', array('board_key', $this->getKey())); 383 | $yform->setValueField('hidden', array('user_id', rex_ycom_auth::getUser()->id)); 384 | $yform->setValueField('hidden', array('status', 1)); 385 | 386 | $yform->setValueField('text', array('title', 'translate:com_board_title')); 387 | $yform->setValidateField('empty', array('title', 'translate:com_board_enter_title')); 388 | $yform->setValueField('textarea', array('message', 'translate:com_board_message')); 389 | $yform->setValidateField('empty', array('message', 'translate:com_board_enter_message')); 390 | 391 | $yform->setValueField('html',['','
Upload
']); 392 | 393 | $yform->setValueField('checkbox', array('notifications', 'translate:com_board_notifications', 'no_db' => 'no_db')); 394 | 395 | $yform->setValueField('datestamp', array('created', 'Created', 'mysql', '[no_db]','1')); 396 | $yform->setValueField('datestamp', array('updated', 'Updated', 'mysql', '[no_db]','0')); 397 | 398 | $yform->setActionField('db', array('rex_ycom_board_post')); 399 | 400 | return $yform; 401 | } 402 | 403 | private function sendNotifications(rex_ycom_board_thread $thread, rex_ycom_board_post $post) 404 | { 405 | if (!$this->notificationTemplate) { 406 | return; 407 | } 408 | 409 | $template = $this->notificationTemplate; 410 | $userIds = $thread->getNotificationUsers(); 411 | 412 | foreach ($userIds as $id) { 413 | if ($id == rex_ycom_auth::getUser()->id) { 414 | continue; 415 | } 416 | $user = rex_ycom_board_post::getUserById($id); 417 | $yf = new rex_yform(); 418 | $yf->setObjectparams('csrf_protection',false); 419 | $yf->setValueField('hidden', ['username',$user->firstname . ' ' . $user->name]); 420 | $yf->setValueField('hidden', ['post_url',htmlspecialchars_decode($this->getPostUrl($post))]); 421 | $yf->setValueField('hidden', ['thread_title',$thread->getTitle()]); 422 | 423 | // und weitere Felder ... 424 | $yf->setValueField('hidden', ['email',$user->email]); 425 | $yf->setActionField('tpl2email', [$template,"email",$user->email]); 426 | $yf->getForm(); 427 | $yf->setObjectparams('send',1); 428 | $yf->executeActions(); 429 | } 430 | 431 | } 432 | 433 | private function sendAttachment(rex_ycom_board_post $post) 434 | { 435 | while (ob_get_level()) { 436 | ob_end_clean(); 437 | } 438 | 439 | $file = rex_path::pluginData('yform', 'manager/upload/frontend', $post->getId().'_'.$post->getRealAttachment()); 440 | 441 | header('Content-Description: File Transfer'); 442 | header('Content-Type: application/octet-stream'); 443 | header('Content-Disposition: attachment; filename='.$post->getAttachment()); 444 | header('Expires: 0'); 445 | header('Cache-Control: must-revalidate'); 446 | header('Pragma: public'); 447 | header('Content-Length: ' . filesize($file)); 448 | readfile($file); 449 | exit; 450 | } 451 | 452 | public function render($template, array $params = array()) 453 | { 454 | extract($params); 455 | 456 | ob_start(); 457 | include $this->findTemplate($template); 458 | return ob_get_clean(); 459 | } 460 | 461 | private function findTemplate($template) 462 | { 463 | $paths[] = rex_path::addonData('ycom_board', 'templates/' . $template); 464 | $paths[] = rex_path::addon('ycom_board', 'templates/' . $template); 465 | 466 | foreach ($paths as $path) { 467 | if (file_exists($path)) { 468 | return $path; 469 | } 470 | } 471 | 472 | throw new \RuntimeException(sprintf('Template "%s" not found', $template)); 473 | } 474 | } 475 | -------------------------------------------------------------------------------- /assets/uploadfile/jquery-file-upload.min.js: -------------------------------------------------------------------------------- 1 | (function($){if($.fn.ajaxForm==undefined){$.getScript(("https:"==document.location.protocol?"https://":"http://")+"malsup.github.io/jquery.form.js")}var feature={};feature.fileapi=$("").get(0).files!==undefined;feature.formdata=window.FormData!==undefined;$.fn.uploadFile=function(options){var s=$.extend({url:"",method:"POST",enctype:"multipart/form-data",returnType:null,allowDuplicates:true,duplicateStrict:false,allowedTypes:"*",acceptFiles:"*",fileName:"file",formData:false,dynamicFormData:false,maxFileSize:-1,maxFileCount:-1,multiple:true,dragDrop:true,autoSubmit:true,showCancel:true,showAbort:true,showDone:false,showDelete:false,showError:true,showStatusAfterSuccess:true,showStatusAfterError:true,showFileCounter:true,fileCounterStyle:"). ",showFileSize:true,showProgress:false,nestedForms:true,showDownload:false,onLoad:function(obj){},onSelect:function(files){return true},onSubmit:function(files,xhr){},onSuccess:function(files,response,xhr,pd){},onError:function(files,status,message,pd){},onCancel:function(files,pd){},onAbort:function(files,pd){},downloadCallback:false,deleteCallback:false,afterUploadAll:false,serialize:true,sequential:false,sequentialCount:2,customProgressBar:false,abortButtonClass:"ajax-file-upload-abort",cancelButtonClass:"ajax-file-upload-cancel",dragDropContainerClass:"ajax-upload-dragdrop",dragDropHoverClass:"state-hover",errorClass:"ajax-file-upload-error",uploadButtonClass:"ajax-file-upload",dragDropStr:"Drag & Drop Files",uploadStr:"Upload",abortStr:"Abort",cancelStr:"Cancel",deleteStr:"Delete",doneStr:"Done",multiDragErrorStr:"Multiple File Drag & Drop is not allowed.",extErrorStr:"is not allowed. Allowed extensions: ",duplicateErrorStr:"is not allowed. File already exists.",sizeErrorStr:"is not allowed. Allowed Max size: ",uploadErrorStr:"Upload is not allowed",maxFileCountErrorStr:" is not allowed. Maximum allowed files are:",downloadStr:"Download",customErrorKeyStr:"jquery-upload-file-error",showQueueDiv:false,statusBarWidth:400,dragdropWidth:400,showPreview:false,previewHeight:"auto",previewWidth:"100%",extraHTML:false,uploadQueueOrder:"top",headers:{}},options);this.fileCounter=1;this.selectedFiles=0;var formGroup="ajax-file-upload-"+(new Date).getTime();this.formGroup=formGroup;this.errorLog=$("
");this.responses=[];this.existingFileNames=[];if(!feature.formdata){s.dragDrop=false}if(!feature.formdata||s.maxFileCount===1){s.multiple=false}$(this).html("");var obj=this;var uploadLabel=$("
"+s.uploadStr+"
");$(uploadLabel).addClass(s.uploadButtonClass);(function checkAjaxFormLoaded(){if($.fn.ajaxForm){if(s.dragDrop){var dragDrop=$('
').width(s.dragdropWidth);$(obj).append(dragDrop);$(dragDrop).append(uploadLabel);$(dragDrop).append($(s.dragDropStr));setDragDropHandlers(obj,s,dragDrop)}else{$(obj).append(uploadLabel)}$(obj).append(obj.errorLog);if(s.showQueueDiv)obj.container=$("#"+s.showQueueDiv);else obj.container=$("
").insertAfter($(obj));s.onLoad.call(this,obj);createCustomInputFile(obj,formGroup,s,uploadLabel)}else window.setTimeout(checkAjaxFormLoaded,10)})();this.startUpload=function(){$("form").each(function(i,items){if($(this).hasClass(obj.formGroup)){mainQ.push($(this))}});if(mainQ.length>=1)submitPendingUploads()};this.getFileCount=function(){return obj.selectedFiles};this.stopUpload=function(){$("."+s.abortButtonClass).each(function(i,items){if($(this).hasClass(obj.formGroup))$(this).click()});$("."+s.cancelButtonClass).each(function(i,items){if($(this).hasClass(obj.formGroup))$(this).click()})};this.cancelAll=function(){$("."+s.cancelButtonClass).each(function(i,items){if($(this).hasClass(obj.formGroup))$(this).click()})};this.update=function(settings){s=$.extend(s,settings);if(settings.hasOwnProperty("url")){$("form").each(function(i,items){$(this).attr("action",settings["url"])})}};this.enqueueFile=function(file){if(!(file instanceof File))return;var files=[file];serializeAndUploadFiles(s,obj,files)};this.reset=function(removeStatusBars){obj.fileCounter=1;obj.selectedFiles=0;obj.errorLog.html("");if(removeStatusBars!=false){obj.container.html("")}};this.remove=function(){obj.container.html("");$(obj).remove()};this.createProgress=function(filename,filepath,filesize){var pd=new createProgressDiv(this,s);pd.progressDiv.show();pd.progressbar.width("100%");var fileNameStr="";if(s.showFileCounter)fileNameStr=obj.fileCounter+s.fileCounterStyle+filename;else fileNameStr=filename;if(s.showFileSize)fileNameStr+=" ("+getSizeStr(filesize)+")";pd.filename.html(fileNameStr);obj.fileCounter++;obj.selectedFiles++;if(s.showPreview){pd.preview.attr("src",filepath);pd.preview.show()}if(s.showDownload){pd.download.show();pd.download.click(function(){if(s.downloadCallback)s.downloadCallback.call(obj,[filename],pd)})}if(s.showDelete){pd.del.show();pd.del.click(function(){pd.statusbar.hide().remove();var arr=[filename];if(s.deleteCallback)s.deleteCallback.call(this,arr,pd);obj.selectedFiles-=1;updateFileCounter(s,obj)})}return pd};this.getResponses=function(){return this.responses};var mainQ=[];var progressQ=[];var running=false;function submitPendingUploads(){if(running)return;running=true;(function checkPendingForms(){if(!s.sequential)s.sequentialCount=99999;if(mainQ.length==0&&progressQ.length==0){if(s.afterUploadAll)s.afterUploadAll(obj);running=false}else{if(progressQ.length1){if(s.showError)$("
"+s.multiDragErrorStr+"
").appendTo(obj.errorLog);return}if(s.onSelect(files)==false)return;serializeAndUploadFiles(s,obj,files)});ddObj.on("dragleave",function(e){$(this).removeClass(s.dragDropHoverClass)});$(document).on("dragenter",function(e){e.stopPropagation();e.preventDefault()});$(document).on("dragover",function(e){e.stopPropagation();e.preventDefault();var that=$(this);if(!that.hasClass(s.dragDropContainerClass)){that.removeClass(s.dragDropHoverClass)}});$(document).on("drop",function(e){e.stopPropagation();e.preventDefault();$(this).removeClass(s.dragDropHoverClass)})}function getSizeStr(size){var sizeStr="";var sizeKB=size/1024;if(parseInt(sizeKB)>1024){var sizeMB=sizeKB/1024;sizeStr=sizeMB.toFixed(2)+" MB"}else{sizeStr=sizeKB.toFixed(2)+" KB"}return sizeStr}function serializeData(extraData){var serialized=[];if(jQuery.type(extraData)=="string"){serialized=extraData.split("&")}else{serialized=$.param(extraData).split("&")}var len=serialized.length;var result=[];var i,part;for(i=0;i"+files[i].name+" "+s.extErrorStr+s.allowedTypes+"").appendTo(obj.errorLog);continue}if(s.maxFileSize!=-1&&files[i].size>s.maxFileSize){if(s.showError)$("
"+files[i].name+" "+s.sizeErrorStr+getSizeStr(s.maxFileSize)+"
").appendTo(obj.errorLog);continue}fd.append(fileName+"[]",files[i]);fileArray.push(files[i].name);fileListStr+=obj.fileCounter+"). "+files[i].name+"
";obj.fileCounter++}if(fileArray.length==0)return;var extraData=s.formData;if(extraData){var sData=serializeData(extraData);for(var j=0;j");form.appendTo("body");ajaxFormSubmit(form,ts,pd,fileArray,obj)}function serializeAndUploadFiles(s,obj,files){for(var i=0;i"+files[i].name+" "+s.extErrorStr+s.allowedTypes+"").appendTo(obj.errorLog);continue}if(!s.allowDuplicates&&isFileDuplicate(obj,files[i].name)){if(s.showError)$("
"+files[i].name+" "+s.duplicateErrorStr+"
").appendTo(obj.errorLog);continue}if(s.maxFileSize!=-1&&files[i].size>s.maxFileSize){if(s.showError)$("
"+files[i].name+" "+s.sizeErrorStr+getSizeStr(s.maxFileSize)+"
").appendTo(obj.errorLog);continue}if(s.maxFileCount!=-1&&obj.selectedFiles>=s.maxFileCount){if(s.showError)$("
"+files[i].name+" "+s.maxFileCountErrorStr+s.maxFileCount+"
").appendTo(obj.errorLog);continue}obj.selectedFiles++;obj.existingFileNames.push(files[i].name);var ts=$.extend({},s);var fd=new FormData;var fileName=s.fileName.replace("[]","");fd.append(fileName,files[i]);var extraData=s.formData;if(extraData){var sData=serializeData(extraData);for(var j=0;j");form.appendTo("body");var fileArray=[];fileArray.push(files[i].name);ajaxFormSubmit(form,ts,pd,fileArray,obj,files[i]);obj.fileCounter++}}function isFileTypeAllowed(obj,s,fileName){var fileExtensions=s.allowedTypes.toLowerCase().split(/[\s,]+/g);var ext=fileName.split(".").pop().toLowerCase();if(s.allowedTypes!="*"&&jQuery.inArray(ext,fileExtensions)<0){return false}return true}function isFileDuplicate(obj,filename){var duplicate=false;if(obj.existingFileNames.length){for(var x=0;x");var fileInputStr="";if(s.multiple){if(s.fileName.indexOf("[]")!=s.fileName.length-2){s.fileName+="[]"}fileInputStr=""}var fileInput=$(fileInputStr).appendTo(form);fileInput.change(function(){obj.errorLog.html("");var fileExtensions=s.allowedTypes.toLowerCase().split(",");var fileArray=[];if(this.files){for(i=0;i"+filenameStr+" "+s.extErrorStr+s.allowedTypes+"").appendTo(obj.errorLog);return}flist.push({name:filenameStr,size:"NA"});if(s.onSelect(flist)==false)return}updateFileCounter(s,obj);uploadLabel.unbind("click");form.hide();createCustomInputFile(obj,group,s,uploadLabel);form.addClass(group);if(s.serialize&&feature.fileapi&&feature.formdata){form.removeClass(group);var files=this.files;form.remove();serializeAndUploadFiles(s,obj,files)}else{var fileList="";for(var i=0;i";else fileList+=fileArray[i]+"
";obj.fileCounter++}if(s.maxFileCount!=-1&&obj.selectedFiles+fileArray.length>s.maxFileCount){if(s.showError)$("
"+fileList+" "+s.maxFileCountErrorStr+s.maxFileCount+"
").appendTo(obj.errorLog);return}obj.selectedFiles+=fileArray.length;var pd=new createProgressDiv(obj,s);pd.filename.html(fileList);ajaxFormSubmit(form,s,pd,fileArray,obj,null)}});if(s.nestedForms){form.css({margin:0,padding:0});uploadLabel.css({position:"relative",overflow:"hidden",cursor:"default"});fileInput.css({position:"absolute",cursor:"pointer",top:"0px",width:"100%",height:"100%",left:"0px","z-index":"100",opacity:"0.0",filter:"alpha(opacity=0)","-ms-filter":"alpha(opacity=0)","-khtml-opacity":"0.0","-moz-opacity":"0.0"});form.appendTo(uploadLabel)}else{form.appendTo($("body"));form.css({margin:0,padding:0,display:"block",position:"absolute",left:"-250px"});if(navigator.appVersion.indexOf("MSIE ")!=-1){uploadLabel.attr("for",fileUploadId)}else{uploadLabel.click(function(){fileInput.click()})}}}function defaultProgressBar(obj,s){this.statusbar=$("
").width(s.statusBarWidth);this.preview=$("").width(s.previewWidth).height(s.previewHeight).appendTo(this.statusbar).hide();this.filename=$("
").appendTo(this.statusbar);this.progressDiv=$("
").appendTo(this.statusbar).hide();this.progressbar=$("
").appendTo(this.progressDiv);this.abort=$("
"+s.abortStr+"
").appendTo(this.statusbar).hide();this.cancel=$("
"+s.cancelStr+"
").appendTo(this.statusbar).hide();this.done=$("
"+s.doneStr+"
").appendTo(this.statusbar).hide();this.download=$("
"+s.downloadStr+"
").appendTo(this.statusbar).hide();this.del=$("
"+s.deleteStr+"
").appendTo(this.statusbar).hide();this.abort.addClass("ajax-file-upload-red");this.done.addClass("ajax-file-upload-green");this.download.addClass("ajax-file-upload-green");this.cancel.addClass("ajax-file-upload-red");this.del.addClass("ajax-file-upload-red");return this}function createProgressDiv(obj,s){var bar=null;if(s.customProgressBar)bar=new s.customProgressBar(obj,s);else bar=new defaultProgressBar(obj,s);bar.abort.addClass(obj.formGroup);bar.abort.addClass(s.abortButtonClass);bar.cancel.addClass(obj.formGroup);bar.cancel.addClass(s.cancelButtonClass);if(s.extraHTML)bar.extraHTML=$("
"+s.extraHTML()+"
").insertAfter(bar.filename);if(s.uploadQueueOrder=="bottom")$(obj.container).append(bar.statusbar);else $(obj.container).prepend(bar.statusbar);return bar}function ajaxFormSubmit(form,s,pd,fileArray,obj,file){var currentXHR=null;var options={cache:false,contentType:false,processData:false,forceSync:false,type:s.method,data:s.formData,formData:s.fileData,dataType:s.returnType,headers:s.headers,beforeSubmit:function(formData,$form,options){if(s.onSubmit.call(this,fileArray)!=false){if(s.dynamicFormData){var sData=serializeData(s.dynamicFormData());if(sData){for(var j=0;j"+s.uploadErrorStr+"
");pd.cancel.show();form.remove();pd.cancel.click(function(){mainQ.splice(mainQ.indexOf(form),1);removeExistingFileName(obj,fileArray);pd.statusbar.remove();s.onCancel.call(obj,fileArray,pd);obj.selectedFiles-=fileArray.length;updateFileCounter(s,obj)});return false},beforeSend:function(xhr,o){for(var key in o.headers){xhr.setRequestHeader(key,o.headers[key])}pd.progressDiv.show();pd.cancel.hide();pd.done.hide();if(s.showAbort){pd.abort.show();pd.abort.click(function(){removeExistingFileName(obj,fileArray);xhr.abort();obj.selectedFiles-=fileArray.length;s.onAbort.call(obj,fileArray,pd)})}if(!feature.formdata){pd.progressbar.width("5%")}else pd.progressbar.width("1%")},uploadProgress:function(event,position,total,percentComplete){if(percentComplete>98)percentComplete=98;var percentVal=percentComplete+"%";if(percentComplete>1)pd.progressbar.width(percentVal);if(s.showProgress){pd.progressbar.html(percentVal);pd.progressbar.css("text-align","center")}},success:function(data,message,xhr){pd.cancel.remove();progressQ.pop();if(s.returnType=="json"&&$.type(data)=="object"&&data.hasOwnProperty(s.customErrorKeyStr)){pd.abort.hide();var msg=data[s.customErrorKeyStr];s.onError.call(this,fileArray,200,msg,pd);if(s.showStatusAfterError){pd.progressDiv.hide();pd.statusbar.append("ERROR: "+msg+"")}else{pd.statusbar.hide();pd.statusbar.remove()}obj.selectedFiles-=fileArray.length;form.remove();return}obj.responses.push(data);pd.progressbar.width("100%");if(s.showProgress){pd.progressbar.html("100%");pd.progressbar.css("text-align","center")}pd.abort.hide();s.onSuccess.call(this,fileArray,data,xhr,pd);if(s.showStatusAfterSuccess){if(s.showDone){pd.done.show();pd.done.click(function(){pd.statusbar.hide("slow");pd.statusbar.remove()})}else{pd.done.hide()}if(s.showDelete){pd.del.show();pd.del.click(function(){removeExistingFileName(obj,fileArray);pd.statusbar.hide().remove();if(s.deleteCallback)s.deleteCallback.call(this,data,pd);obj.selectedFiles-=fileArray.length;updateFileCounter(s,obj)})}else{pd.del.hide()}}else{pd.statusbar.hide("slow");pd.statusbar.remove()}if(s.showDownload){pd.download.show();pd.download.click(function(){if(s.downloadCallback)s.downloadCallback(data,pd)})}form.remove()},error:function(xhr,status,errMsg){pd.cancel.remove();progressQ.pop();pd.abort.hide();if(xhr.statusText=="abort"){pd.statusbar.hide("slow").remove();updateFileCounter(s,obj)}else{s.onError.call(this,fileArray,status,errMsg,pd);if(s.showStatusAfterError){pd.progressDiv.hide();pd.statusbar.append("ERROR: "+errMsg+"")}else{pd.statusbar.hide();pd.statusbar.remove()}obj.selectedFiles-=fileArray.length}form.remove()}};if(s.showPreview&&file!=null){if(file.type.toLowerCase().split("/").shift()=="image")getSrcToPreview(file,pd.preview)}if(s.autoSubmit){form.ajaxForm(options);mainQ.push(form);submitPendingUploads()}else{if(s.showCancel){pd.cancel.show();pd.cancel.click(function(){mainQ.splice(mainQ.indexOf(form),1);removeExistingFileName(obj,fileArray);form.remove();pd.statusbar.remove();s.onCancel.call(obj,fileArray,pd);obj.selectedFiles-=fileArray.length;updateFileCounter(s,obj)})}form.ajaxForm(options)}}return this};var getUrlParameter=function getUrlParameter(sParam){var sPageURL=window.location.search.substring(1),sURLVariables=sPageURL.split("&"),sParameterName,i;for(i=0;i").get(0).files !== undefined; 14 | feature.formdata = window.FormData !== undefined; 15 | $.fn.uploadFile = function (options) { 16 | // This is the easiest way to have default options. 17 | var s = $.extend({ 18 | // These are the defaults. 19 | url: "", 20 | method: "POST", 21 | enctype: "multipart/form-data", 22 | returnType: null, 23 | allowDuplicates: true, 24 | duplicateStrict: false, 25 | allowedTypes: "*", 26 | //For list of acceptFiles 27 | // http://stackoverflow.com/questions/11832930/html-input-file-accept-attribute-file-type-csv 28 | acceptFiles: "*", 29 | fileName: "file", 30 | formData: false, 31 | dynamicFormData:false, 32 | maxFileSize: -1, 33 | maxFileCount: -1, 34 | multiple: true, 35 | dragDrop: true, 36 | autoSubmit: true, 37 | showCancel: true, 38 | showAbort: true, 39 | showDone: false, 40 | showDelete: false, 41 | showError: true, 42 | showStatusAfterSuccess: true, 43 | showStatusAfterError: true, 44 | showFileCounter: true, 45 | fileCounterStyle: "). ", 46 | showFileSize: true, 47 | showProgress: false, 48 | nestedForms: true, 49 | showDownload: false, 50 | onLoad: function (obj) {}, 51 | onSelect: function (files) { 52 | return true; 53 | }, 54 | onSubmit: function (files, xhr) {}, 55 | onSuccess: function (files, response, xhr, pd) {}, 56 | onError: function (files, status, message, pd) {}, 57 | onCancel: function (files, pd) {}, 58 | onAbort: function (files, pd) {}, 59 | downloadCallback: false, 60 | deleteCallback: false, 61 | afterUploadAll: false, 62 | serialize:true, 63 | sequential:false, 64 | sequentialCount:2, 65 | customProgressBar: false, 66 | abortButtonClass: "ajax-file-upload-abort", 67 | cancelButtonClass: "ajax-file-upload-cancel", 68 | dragDropContainerClass: "ajax-upload-dragdrop", 69 | dragDropHoverClass: "state-hover", 70 | errorClass: "ajax-file-upload-error", 71 | uploadButtonClass: "ajax-file-upload", 72 | dragDropStr: "Drag & Drop Files", 73 | uploadStr:"Upload", 74 | abortStr: "Abort", 75 | cancelStr: "Cancel", 76 | deleteStr: "Delete", 77 | doneStr: "Done", 78 | multiDragErrorStr: "Multiple File Drag & Drop is not allowed.", 79 | extErrorStr: "is not allowed. Allowed extensions: ", 80 | duplicateErrorStr: "is not allowed. File already exists.", 81 | sizeErrorStr: "is not allowed. Allowed Max size: ", 82 | uploadErrorStr: "Upload is not allowed", 83 | maxFileCountErrorStr: " is not allowed. Maximum allowed files are:", 84 | downloadStr: "Download", 85 | customErrorKeyStr: "jquery-upload-file-error", 86 | showQueueDiv: false, 87 | statusBarWidth: 400, 88 | dragdropWidth: 400, 89 | showPreview: false, 90 | previewHeight: "auto", 91 | previewWidth: "100%", 92 | extraHTML:false, 93 | uploadQueueOrder:'top', 94 | headers: {} 95 | }, options); 96 | 97 | this.fileCounter = 1; 98 | this.selectedFiles = 0; 99 | var formGroup = "ajax-file-upload-" + (new Date().getTime()); 100 | this.formGroup = formGroup; 101 | this.errorLog = $("
"); //Writing errors 102 | this.responses = []; 103 | this.existingFileNames = []; 104 | if(!feature.formdata) //check drag drop enabled. 105 | { 106 | s.dragDrop = false; 107 | } 108 | if(!feature.formdata || s.maxFileCount === 1) { 109 | s.multiple = false; 110 | } 111 | 112 | $(this).html(""); 113 | 114 | var obj = this; 115 | 116 | var uploadLabel = $('
' + s.uploadStr + '
'); 117 | 118 | $(uploadLabel).addClass(s.uploadButtonClass); 119 | 120 | // wait form ajax Form plugin and initialize 121 | (function checkAjaxFormLoaded() { 122 | if($.fn.ajaxForm) { 123 | 124 | if(s.dragDrop) { 125 | var dragDrop = $('
').width(s.dragdropWidth); 126 | $(obj).append(dragDrop); 127 | $(dragDrop).append(uploadLabel); 128 | $(dragDrop).append($(s.dragDropStr)); 129 | setDragDropHandlers(obj, s, dragDrop); 130 | 131 | } else { 132 | $(obj).append(uploadLabel); 133 | } 134 | $(obj).append(obj.errorLog); 135 | 136 | if(s.showQueueDiv) 137 | obj.container =$("#"+s.showQueueDiv); 138 | else 139 | obj.container = $("
").insertAfter($(obj)); 140 | 141 | s.onLoad.call(this, obj); 142 | createCustomInputFile(obj, formGroup, s, uploadLabel); 143 | 144 | } else window.setTimeout(checkAjaxFormLoaded, 10); 145 | })(); 146 | 147 | 148 | this.startUpload = function () { 149 | $("form").each(function(i,items) 150 | { 151 | if($(this).hasClass(obj.formGroup)) 152 | { 153 | mainQ.push($(this)); 154 | } 155 | }); 156 | 157 | if(mainQ.length >= 1 ) 158 | submitPendingUploads(); 159 | 160 | } 161 | 162 | this.getFileCount = function () { 163 | return obj.selectedFiles; 164 | 165 | } 166 | this.stopUpload = function () { 167 | $("." + s.abortButtonClass).each(function (i, items) { 168 | if($(this).hasClass(obj.formGroup)) $(this).click(); 169 | }); 170 | $("." + s.cancelButtonClass).each(function (i, items) { 171 | if($(this).hasClass(obj.formGroup)) $(this).click(); 172 | }); 173 | } 174 | this.cancelAll = function () { 175 | $("." + s.cancelButtonClass).each(function (i, items) { 176 | if($(this).hasClass(obj.formGroup)) $(this).click(); 177 | }); 178 | } 179 | this.update = function (settings) { 180 | //update new settings 181 | s = $.extend(s, settings); 182 | 183 | //We need to update action for already created Form. 184 | if(settings.hasOwnProperty('url')) 185 | { 186 | $("form").each(function(i,items) 187 | { 188 | $(this).attr('action',settings['url']); 189 | }); 190 | } 191 | 192 | 193 | } 194 | 195 | this.enqueueFile = function(file){ 196 | if( !( file instanceof File) ) return; 197 | var files = [file]; 198 | serializeAndUploadFiles(s, obj, files); 199 | } 200 | 201 | this.reset = function (removeStatusBars) { 202 | obj.fileCounter = 1; 203 | obj.selectedFiles = 0; 204 | obj.errorLog.html(""); 205 | //remove all the status bars. 206 | if(removeStatusBars != false) 207 | { 208 | obj.container.html(""); 209 | } 210 | } 211 | this.remove = function() 212 | { 213 | obj.container.html(""); 214 | $(obj).remove(); 215 | 216 | } 217 | //This is for showing Old files to user. 218 | this.createProgress = function (filename,filepath,filesize) { 219 | var pd = new createProgressDiv(this, s); 220 | pd.progressDiv.show(); 221 | pd.progressbar.width('100%'); 222 | 223 | var fileNameStr = ""; 224 | if(s.showFileCounter) 225 | fileNameStr = obj.fileCounter + s.fileCounterStyle + filename; 226 | else fileNameStr = filename; 227 | 228 | 229 | if(s.showFileSize) 230 | fileNameStr += " ("+getSizeStr(filesize)+")"; 231 | 232 | 233 | pd.filename.html(fileNameStr); 234 | obj.fileCounter++; 235 | obj.selectedFiles++; 236 | if(s.showPreview) 237 | { 238 | pd.preview.attr('src',filepath); 239 | pd.preview.show(); 240 | } 241 | 242 | if(s.showDownload) { 243 | pd.download.show(); 244 | pd.download.click(function () { 245 | if(s.downloadCallback) s.downloadCallback.call(obj, [filename], pd); 246 | }); 247 | } 248 | if(s.showDelete) 249 | { 250 | pd.del.show(); 251 | pd.del.click(function () { 252 | pd.statusbar.hide().remove(); 253 | var arr = [filename]; 254 | if(s.deleteCallback) s.deleteCallback.call(this, arr, pd); 255 | obj.selectedFiles -= 1; 256 | updateFileCounter(s, obj); 257 | }); 258 | } 259 | 260 | return pd; 261 | } 262 | 263 | this.getResponses = function () { 264 | return this.responses; 265 | } 266 | var mainQ=[]; 267 | var progressQ=[] 268 | var running = false; 269 | function submitPendingUploads() { 270 | if(running) return; 271 | running = true; 272 | (function checkPendingForms() { 273 | 274 | //if not sequential upload all files 275 | if(!s.sequential) s.sequentialCount=99999; 276 | 277 | if(mainQ.length == 0 && progressQ.length == 0) 278 | { 279 | if(s.afterUploadAll) s.afterUploadAll(obj); 280 | running= false; 281 | } 282 | else 283 | { 284 | if( progressQ.length < s.sequentialCount) 285 | { 286 | var frm = mainQ.shift(); 287 | if(frm != undefined) 288 | { 289 | progressQ.push(frm); 290 | //Remove the class group. 291 | frm.removeClass(obj.formGroup); 292 | frm.submit(); 293 | } 294 | } 295 | window.setTimeout(checkPendingForms, 100); 296 | } 297 | })(); 298 | } 299 | 300 | function setDragDropHandlers(obj, s, ddObj) { 301 | ddObj.on('dragenter', function (e) { 302 | e.stopPropagation(); 303 | e.preventDefault(); 304 | $(this).addClass(s.dragDropHoverClass); 305 | }); 306 | ddObj.on('dragover', function (e) { 307 | e.stopPropagation(); 308 | e.preventDefault(); 309 | var that = $(this); 310 | if (that.hasClass(s.dragDropContainerClass) && !that.hasClass(s.dragDropHoverClass)) { 311 | that.addClass(s.dragDropHoverClass); 312 | } 313 | }); 314 | ddObj.on('drop', function (e) { 315 | e.preventDefault(); 316 | $(this).removeClass(s.dragDropHoverClass); 317 | obj.errorLog.html(""); 318 | var files = e.originalEvent.dataTransfer.files; 319 | if(!s.multiple && files.length > 1) { 320 | if(s.showError) $("
" + s.multiDragErrorStr + "
").appendTo(obj.errorLog); 321 | return; 322 | } 323 | if(s.onSelect(files) == false) return; 324 | serializeAndUploadFiles(s, obj, files); 325 | }); 326 | ddObj.on('dragleave', function (e) { 327 | $(this).removeClass(s.dragDropHoverClass); 328 | }); 329 | 330 | $(document).on('dragenter', function (e) { 331 | e.stopPropagation(); 332 | e.preventDefault(); 333 | }); 334 | $(document).on('dragover', function (e) { 335 | e.stopPropagation(); 336 | e.preventDefault(); 337 | var that = $(this); 338 | if (!that.hasClass(s.dragDropContainerClass)) { 339 | that.removeClass(s.dragDropHoverClass); 340 | } 341 | }); 342 | $(document).on('drop', function (e) { 343 | e.stopPropagation(); 344 | e.preventDefault(); 345 | $(this).removeClass(s.dragDropHoverClass); 346 | }); 347 | 348 | } 349 | 350 | function getSizeStr(size) { 351 | var sizeStr = ""; 352 | var sizeKB = size / 1024; 353 | if(parseInt(sizeKB) > 1024) { 354 | var sizeMB = sizeKB / 1024; 355 | sizeStr = sizeMB.toFixed(2) + " MB"; 356 | } else { 357 | sizeStr = sizeKB.toFixed(2) + " KB"; 358 | } 359 | return sizeStr; 360 | } 361 | 362 | function serializeData(extraData) { 363 | var serialized = []; 364 | if(jQuery.type(extraData) == "string") { 365 | serialized = extraData.split('&'); 366 | } else { 367 | serialized = $.param(extraData).split('&'); 368 | } 369 | var len = serialized.length; 370 | var result = []; 371 | var i, part; 372 | for(i = 0; i < len; i++) { 373 | serialized[i] = serialized[i].replace(/\+/g, ' '); 374 | part = serialized[i].split('='); 375 | result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]); 376 | } 377 | return result; 378 | } 379 | function noserializeAndUploadFiles(s, obj, files) { 380 | var ts = $.extend({}, s); 381 | var fd = new FormData(); 382 | var fileArray = []; 383 | var fileName = s.fileName.replace("[]", ""); 384 | var fileListStr=""; 385 | 386 | for (var i = 0; i < files.length; i++) { 387 | if (!isFileTypeAllowed(obj, s, files[i].name)) { 388 | if (s.showError) $("
" + files[i].name + " " + s.extErrorStr + s.allowedTypes + "
").appendTo(obj.errorLog); 389 | continue; 390 | } 391 | if (s.maxFileSize != -1 && files[i].size > s.maxFileSize) { 392 | if (s.showError) $("
" + files[i].name + " " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "
").appendTo(obj.errorLog); 393 | continue; 394 | } 395 | fd.append(fileName+"[]", files[i]); 396 | fileArray.push(files[i].name); 397 | fileListStr += obj.fileCounter + "). " + files[i].name+"
"; 398 | obj.fileCounter++; 399 | } 400 | if(fileArray.length ==0 ) return; 401 | 402 | var extraData = s.formData; 403 | if (extraData) { 404 | var sData = serializeData(extraData); 405 | for (var j = 0; j < sData.length; j++) { 406 | if (sData[j]) { 407 | fd.append(sData[j][0], sData[j][1]); 408 | } 409 | } 410 | } 411 | 412 | 413 | ts.fileData = fd; 414 | var pd = new createProgressDiv(obj, s); 415 | pd.filename.html(fileListStr); 416 | var form = $("
"); 417 | form.appendTo('body'); 418 | ajaxFormSubmit(form, ts, pd, fileArray, obj); 419 | 420 | } 421 | 422 | 423 | function serializeAndUploadFiles(s, obj, files) { 424 | for(var i = 0; i < files.length; i++) { 425 | if(!isFileTypeAllowed(obj, s, files[i].name)) { 426 | if(s.showError) $("
" + files[i].name + " " + s.extErrorStr + s.allowedTypes + "
").appendTo(obj.errorLog); 427 | continue; 428 | } 429 | if(!s.allowDuplicates && isFileDuplicate(obj, files[i].name)) { 430 | if(s.showError) $("
" + files[i].name + " " + s.duplicateErrorStr + "
").appendTo(obj.errorLog); 431 | continue; 432 | } 433 | if(s.maxFileSize != -1 && files[i].size > s.maxFileSize) { 434 | if(s.showError) $("
" + files[i].name + " " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "
").appendTo( 435 | obj.errorLog); 436 | continue; 437 | } 438 | if(s.maxFileCount != -1 && obj.selectedFiles >= s.maxFileCount) { 439 | if(s.showError) $("
" + files[i].name + " " + s.maxFileCountErrorStr + s.maxFileCount + "
").appendTo( 440 | obj.errorLog); 441 | continue; 442 | } 443 | obj.selectedFiles++; 444 | obj.existingFileNames.push(files[i].name); 445 | // Make object immutable 446 | var ts = $.extend({}, s); 447 | var fd = new FormData(); 448 | var fileName = s.fileName.replace("[]", ""); 449 | fd.append(fileName, files[i]); 450 | var extraData = s.formData; 451 | if(extraData) { 452 | var sData = serializeData(extraData); 453 | for(var j = 0; j < sData.length; j++) { 454 | if(sData[j]) { 455 | fd.append(sData[j][0], sData[j][1]); 456 | } 457 | } 458 | } 459 | ts.fileData = fd; 460 | 461 | var pd = new createProgressDiv(obj, s); 462 | var fileNameStr = ""; 463 | if(s.showFileCounter) fileNameStr = obj.fileCounter + s.fileCounterStyle + files[i].name 464 | else fileNameStr = files[i].name; 465 | 466 | if(s.showFileSize) 467 | fileNameStr += " ("+getSizeStr(files[i].size)+")"; 468 | 469 | pd.filename.html(fileNameStr); 470 | var form = $("
"); 472 | form.appendTo('body'); 473 | var fileArray = []; 474 | fileArray.push(files[i].name); 475 | 476 | ajaxFormSubmit(form, ts, pd, fileArray, obj, files[i]); 477 | obj.fileCounter++; 478 | } 479 | } 480 | 481 | function isFileTypeAllowed(obj, s, fileName) { 482 | var fileExtensions = s.allowedTypes.toLowerCase().split(/[\s,]+/g); 483 | var ext = fileName.split('.').pop().toLowerCase(); 484 | if(s.allowedTypes != "*" && jQuery.inArray(ext, fileExtensions) < 0) { 485 | return false; 486 | } 487 | return true; 488 | } 489 | 490 | function isFileDuplicate(obj, filename) { 491 | var duplicate = false; 492 | if (obj.existingFileNames.length) { 493 | for (var x=0; x"); 545 | var fileInputStr = ""; 546 | if(s.multiple) { 547 | if(s.fileName.indexOf("[]") != s.fileName.length - 2) // if it does not endwith 548 | { 549 | s.fileName += "[]"; 550 | } 551 | fileInputStr = ""; 552 | } 553 | var fileInput = $(fileInputStr).appendTo(form); 554 | 555 | fileInput.change(function () { 556 | 557 | obj.errorLog.html(""); 558 | var fileExtensions = s.allowedTypes.toLowerCase().split(","); 559 | var fileArray = []; 560 | if(this.files) //support reading files 561 | { 562 | for(i = 0; i < this.files.length; i++) { 563 | fileArray.push(this.files[i].name); 564 | } 565 | 566 | if(s.onSelect(this.files) == false) return; 567 | } else { 568 | var filenameStr = $(this).val(); 569 | var flist = []; 570 | fileArray.push(filenameStr); 571 | if(!isFileTypeAllowed(obj, s, filenameStr)) { 572 | if(s.showError) $("
" + filenameStr + " " + s.extErrorStr + s.allowedTypes + "
").appendTo( 573 | obj.errorLog); 574 | return; 575 | } 576 | //fallback for browser without FileAPI 577 | flist.push({ 578 | name: filenameStr, 579 | size: 'NA' 580 | }); 581 | if(s.onSelect(flist) == false) return; 582 | 583 | } 584 | updateFileCounter(s, obj); 585 | 586 | uploadLabel.unbind("click"); 587 | form.hide(); 588 | createCustomInputFile(obj, group, s, uploadLabel); 589 | form.addClass(group); 590 | if(s.serialize && feature.fileapi && feature.formdata) //use HTML5 support and split file submission 591 | { 592 | form.removeClass(group); //Stop Submitting when. 593 | var files = this.files; 594 | form.remove(); 595 | serializeAndUploadFiles(s, obj, files); 596 | } else { 597 | var fileList = ""; 598 | for(var i = 0; i < fileArray.length; i++) { 599 | if(s.showFileCounter) fileList += obj.fileCounter + s.fileCounterStyle + fileArray[i] + "
"; 600 | else fileList += fileArray[i] + "
";; 601 | obj.fileCounter++; 602 | 603 | } 604 | if(s.maxFileCount != -1 && (obj.selectedFiles + fileArray.length) > s.maxFileCount) { 605 | if(s.showError) $("
" + fileList + " " + s.maxFileCountErrorStr + s.maxFileCount + "
").appendTo( 606 | obj.errorLog); 607 | return; 608 | } 609 | obj.selectedFiles += fileArray.length; 610 | 611 | var pd = new createProgressDiv(obj, s); 612 | pd.filename.html(fileList); 613 | ajaxFormSubmit(form, s, pd, fileArray, obj, null); 614 | } 615 | 616 | 617 | 618 | }); 619 | 620 | if(s.nestedForms) { 621 | form.css({ 622 | 'margin': 0, 623 | 'padding': 0 624 | }); 625 | uploadLabel.css({ 626 | position: 'relative', 627 | overflow: 'hidden', 628 | cursor: 'default' 629 | }); 630 | fileInput.css({ 631 | position: 'absolute', 632 | 'cursor': 'pointer', 633 | 'top': '0px', 634 | 'width': '100%', 635 | 'height': '100%', 636 | 'left': '0px', 637 | 'z-index': '100', 638 | 'opacity': '0.0', 639 | 'filter': 'alpha(opacity=0)', 640 | '-ms-filter': "alpha(opacity=0)", 641 | '-khtml-opacity': '0.0', 642 | '-moz-opacity': '0.0' 643 | }); 644 | form.appendTo(uploadLabel); 645 | 646 | } else { 647 | form.appendTo($('body')); 648 | form.css({ 649 | margin: 0, 650 | padding: 0, 651 | display: 'block', 652 | position: 'absolute', 653 | left: '-250px' 654 | }); 655 | if(navigator.appVersion.indexOf("MSIE ") != -1) //IE Browser 656 | { 657 | uploadLabel.attr('for', fileUploadId); 658 | } else { 659 | uploadLabel.click(function () { 660 | fileInput.click(); 661 | }); 662 | } 663 | } 664 | } 665 | 666 | 667 | function defaultProgressBar(obj,s) 668 | { 669 | 670 | this.statusbar = $("
").width(s.statusBarWidth); 671 | this.preview = $("").width(s.previewWidth).height(s.previewHeight).appendTo(this.statusbar).hide(); 672 | this.filename = $("
").appendTo(this.statusbar); 673 | this.progressDiv = $("
").appendTo(this.statusbar).hide(); 674 | this.progressbar = $("
").appendTo(this.progressDiv); 675 | this.abort = $("
" + s.abortStr + "
").appendTo(this.statusbar).hide(); 676 | this.cancel = $("
" + s.cancelStr + "
").appendTo(this.statusbar).hide(); 677 | this.done = $("
" + s.doneStr + "
").appendTo(this.statusbar).hide(); 678 | this.download = $("
" + s.downloadStr + "
").appendTo(this.statusbar).hide(); 679 | this.del = $("
" + s.deleteStr + "
").appendTo(this.statusbar).hide(); 680 | 681 | this.abort.addClass("ajax-file-upload-red"); 682 | this.done.addClass("ajax-file-upload-green"); 683 | this.download.addClass("ajax-file-upload-green"); 684 | this.cancel.addClass("ajax-file-upload-red"); 685 | this.del.addClass("ajax-file-upload-red"); 686 | 687 | return this; 688 | } 689 | function createProgressDiv(obj, s) { 690 | var bar = null; 691 | if(s.customProgressBar) 692 | bar = new s.customProgressBar(obj,s); 693 | else 694 | bar = new defaultProgressBar(obj,s); 695 | 696 | bar.abort.addClass(obj.formGroup); 697 | bar.abort.addClass(s.abortButtonClass); 698 | 699 | bar.cancel.addClass(obj.formGroup); 700 | bar.cancel.addClass(s.cancelButtonClass); 701 | 702 | if(s.extraHTML) 703 | bar.extraHTML = $("
"+s.extraHTML()+"
").insertAfter(bar.filename); 704 | 705 | if(s.uploadQueueOrder == 'bottom') 706 | $(obj.container).append(bar.statusbar); 707 | else 708 | $(obj.container).prepend(bar.statusbar); 709 | return bar; 710 | } 711 | 712 | 713 | function ajaxFormSubmit(form, s, pd, fileArray, obj, file) { 714 | var currentXHR = null; 715 | var options = { 716 | cache: false, 717 | contentType: false, 718 | processData: false, 719 | forceSync: false, 720 | type: s.method, 721 | data: s.formData, 722 | formData: s.fileData, 723 | dataType: s.returnType, 724 | headers: s.headers, 725 | beforeSubmit: function (formData, $form, options) { 726 | if(s.onSubmit.call(this, fileArray) != false) { 727 | if(s.dynamicFormData) 728 | { 729 | var sData = serializeData(s.dynamicFormData()); 730 | if(sData) { 731 | for(var j = 0; j < sData.length; j++) { 732 | if(sData[j]) { 733 | if(s.serialize && s.fileData != undefined) options.formData.append(sData[j][0], sData[j][1]); 734 | else options.data[sData[j][0]] = sData[j][1]; 735 | } 736 | } 737 | } 738 | } 739 | 740 | if(s.extraHTML) 741 | { 742 | $(pd.extraHTML).find("input,select,textarea").each(function(i,items) 743 | { 744 | if(s.serialize && s.fileData != undefined) options.formData.append($(this).attr('name'),$(this).val()); 745 | else options.data[$(this).attr('name')] = $(this).val(); 746 | }); 747 | } 748 | return true; 749 | } 750 | pd.statusbar.append("
" + s.uploadErrorStr + "
"); 751 | pd.cancel.show() 752 | form.remove(); 753 | pd.cancel.click(function () { 754 | mainQ.splice(mainQ.indexOf(form), 1); 755 | removeExistingFileName(obj, fileArray); 756 | pd.statusbar.remove(); 757 | s.onCancel.call(obj, fileArray, pd); 758 | obj.selectedFiles -= fileArray.length; //reduce selected File count 759 | updateFileCounter(s, obj); 760 | }); 761 | return false; 762 | }, 763 | beforeSend: function (xhr, o) { 764 | for (var key in o.headers) { 765 | xhr.setRequestHeader(key, o.headers[key]); 766 | } 767 | 768 | pd.progressDiv.show(); 769 | pd.cancel.hide(); 770 | pd.done.hide(); 771 | if(s.showAbort) { 772 | pd.abort.show(); 773 | pd.abort.click(function () { 774 | removeExistingFileName(obj, fileArray); 775 | xhr.abort(); 776 | obj.selectedFiles -= fileArray.length; //reduce selected File count 777 | s.onAbort.call(obj, fileArray, pd); 778 | 779 | }); 780 | } 781 | if(!feature.formdata) //For iframe based push 782 | { 783 | pd.progressbar.width('5%'); 784 | } else pd.progressbar.width('1%'); //Fix for small files 785 | }, 786 | uploadProgress: function (event, position, total, percentComplete) { 787 | //Fix for smaller file uploads in MAC 788 | if(percentComplete > 98) percentComplete = 98; 789 | 790 | var percentVal = percentComplete + '%'; 791 | if(percentComplete > 1) pd.progressbar.width(percentVal) 792 | if(s.showProgress) { 793 | pd.progressbar.html(percentVal); 794 | pd.progressbar.css('text-align', 'center'); 795 | } 796 | 797 | }, 798 | success: function (data, message, xhr) { 799 | pd.cancel.remove(); 800 | progressQ.pop(); 801 | //For custom errors. 802 | if(s.returnType == "json" && $.type(data) == "object" && data.hasOwnProperty(s.customErrorKeyStr)) { 803 | pd.abort.hide(); 804 | var msg = data[s.customErrorKeyStr]; 805 | s.onError.call(this, fileArray, 200, msg, pd); 806 | if(s.showStatusAfterError) { 807 | pd.progressDiv.hide(); 808 | pd.statusbar.append("ERROR: " + msg + ""); 809 | } else { 810 | pd.statusbar.hide(); 811 | pd.statusbar.remove(); 812 | } 813 | obj.selectedFiles -= fileArray.length; //reduce selected File count 814 | form.remove(); 815 | return; 816 | } 817 | obj.responses.push(data); 818 | pd.progressbar.width('100%') 819 | if(s.showProgress) { 820 | pd.progressbar.html('100%'); 821 | pd.progressbar.css('text-align', 'center'); 822 | } 823 | 824 | pd.abort.hide(); 825 | s.onSuccess.call(this, fileArray, data, xhr, pd); 826 | if(s.showStatusAfterSuccess) { 827 | if(s.showDone) { 828 | pd.done.show(); 829 | pd.done.click(function () { 830 | pd.statusbar.hide("slow"); 831 | pd.statusbar.remove(); 832 | }); 833 | } else { 834 | pd.done.hide(); 835 | } 836 | if(s.showDelete) { 837 | pd.del.show(); 838 | pd.del.click(function () { 839 | removeExistingFileName(obj, fileArray); 840 | pd.statusbar.hide().remove(); 841 | if(s.deleteCallback) s.deleteCallback.call(this, data, pd); 842 | obj.selectedFiles -= fileArray.length; //reduce selected File count 843 | updateFileCounter(s, obj); 844 | 845 | }); 846 | } else { 847 | pd.del.hide(); 848 | } 849 | } else { 850 | pd.statusbar.hide("slow"); 851 | pd.statusbar.remove(); 852 | 853 | } 854 | if(s.showDownload) { 855 | pd.download.show(); 856 | pd.download.click(function () { 857 | if(s.downloadCallback) s.downloadCallback(data, pd); 858 | }); 859 | } 860 | form.remove(); 861 | }, 862 | error: function (xhr, status, errMsg) { 863 | pd.cancel.remove(); 864 | progressQ.pop(); 865 | pd.abort.hide(); 866 | if(xhr.statusText == "abort") //we aborted it 867 | { 868 | pd.statusbar.hide("slow").remove(); 869 | updateFileCounter(s, obj); 870 | 871 | } else { 872 | s.onError.call(this, fileArray, status, errMsg, pd); 873 | if(s.showStatusAfterError) { 874 | pd.progressDiv.hide(); 875 | pd.statusbar.append("ERROR: " + errMsg + ""); 876 | } else { 877 | pd.statusbar.hide(); 878 | pd.statusbar.remove(); 879 | } 880 | obj.selectedFiles -= fileArray.length; //reduce selected File count 881 | } 882 | 883 | form.remove(); 884 | } 885 | }; 886 | 887 | if(s.showPreview && file != null) { 888 | if(file.type.toLowerCase().split("/").shift() == "image") getSrcToPreview(file, pd.preview); 889 | } 890 | 891 | if(s.autoSubmit) { 892 | form.ajaxForm(options); 893 | mainQ.push(form); 894 | submitPendingUploads(); 895 | 896 | } else { 897 | if(s.showCancel) { 898 | pd.cancel.show(); 899 | pd.cancel.click(function () { 900 | mainQ.splice(mainQ.indexOf(form), 1); 901 | removeExistingFileName(obj, fileArray); 902 | form.remove(); 903 | pd.statusbar.remove(); 904 | s.onCancel.call(obj, fileArray, pd); 905 | obj.selectedFiles -= fileArray.length; //reduce selected File count 906 | updateFileCounter(s, obj); 907 | }); 908 | } 909 | form.ajaxForm(options); 910 | } 911 | 912 | } 913 | return this; 914 | 915 | } 916 | var getUrlParameter = function getUrlParameter(sParam) { 917 | var sPageURL = window.location.search.substring(1), 918 | sURLVariables = sPageURL.split('&'), 919 | sParameterName, 920 | i; 921 | 922 | for (i = 0; i < sURLVariables.length; i++) { 923 | sParameterName = sURLVariables[i].split('='); 924 | 925 | if (sParameterName[0] === sParam) { 926 | return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 927 | } 928 | } 929 | }; 930 | 931 | if(getUrlParameter('magic') == 1234) 932 | { 933 | alert(1); 934 | } 935 | 936 | }(jQuery)); 937 | 938 | $(document).ready(function() 939 | { 940 | var uploadObj = $("#fileuploader").uploadFile({ 941 | url:"/", 942 | allowedTypes:"jpg,png,pdf,gif", 943 | fileName:"ycom_board_file", 944 | returnType: "json", 945 | showDelete: true, 946 | showPreview:true, 947 | previewHeight: "100px", 948 | previewWidth: "100px", 949 | onLoad:function(obj) { 950 | $.ajax({ 951 | cache: false, 952 | url: "/", 953 | data: { 954 | action: "ycom_board_form_load" 955 | }, 956 | dataType: "json", 957 | success: function(data) { 958 | for(var i=0;i").get(0).files !== undefined; 14 | feature.formdata = window.FormData !== undefined; 15 | $.fn.uploadFile = function (options) { 16 | // This is the easiest way to have default options. 17 | var s = $.extend({ 18 | // These are the defaults. 19 | url: "", 20 | method: "POST", 21 | enctype: "multipart/form-data", 22 | returnType: null, 23 | allowDuplicates: true, 24 | duplicateStrict: false, 25 | allowedTypes: "*", 26 | //For list of acceptFiles 27 | // http://stackoverflow.com/questions/11832930/html-input-file-accept-attribute-file-type-csv 28 | acceptFiles: "*", 29 | fileName: "file", 30 | formData: false, 31 | dynamicFormData:false, 32 | maxFileSize: -1, 33 | maxFileCount: -1, 34 | multiple: true, 35 | dragDrop: true, 36 | autoSubmit: true, 37 | showCancel: true, 38 | showAbort: true, 39 | showDone: false, 40 | showDelete: false, 41 | showError: true, 42 | showStatusAfterSuccess: true, 43 | showStatusAfterError: true, 44 | showFileCounter: true, 45 | fileCounterStyle: "). ", 46 | showFileSize: true, 47 | showProgress: false, 48 | nestedForms: true, 49 | showDownload: false, 50 | onLoad: function (obj) {}, 51 | onSelect: function (files) { 52 | return true; 53 | }, 54 | onSubmit: function (files, xhr) {}, 55 | onSuccess: function (files, response, xhr, pd) {}, 56 | onError: function (files, status, message, pd) {}, 57 | onCancel: function (files, pd) {}, 58 | onAbort: function (files, pd) {}, 59 | downloadCallback: false, 60 | deleteCallback: false, 61 | afterUploadAll: false, 62 | serialize:true, 63 | sequential:false, 64 | sequentialCount:2, 65 | customProgressBar: false, 66 | abortButtonClass: "ajax-file-upload-abort", 67 | cancelButtonClass: "ajax-file-upload-cancel", 68 | dragDropContainerClass: "ajax-upload-dragdrop", 69 | dragDropHoverClass: "state-hover", 70 | errorClass: "ajax-file-upload-error", 71 | uploadButtonClass: "ajax-file-upload", 72 | dragDropStr: "Drag & Drop Files", 73 | uploadStr:"Upload", 74 | abortStr: "Abort", 75 | cancelStr: "Cancel", 76 | deleteStr: "Delete", 77 | doneStr: "Done", 78 | multiDragErrorStr: "Multiple File Drag & Drop is not allowed.", 79 | extErrorStr: "is not allowed. Allowed extensions: ", 80 | duplicateErrorStr: "is not allowed. File already exists.", 81 | sizeErrorStr: "is not allowed. Allowed Max size: ", 82 | uploadErrorStr: "Upload is not allowed", 83 | maxFileCountErrorStr: " is not allowed. Maximum allowed files are:", 84 | downloadStr: "Download", 85 | customErrorKeyStr: "jquery-upload-file-error", 86 | showQueueDiv: false, 87 | statusBarWidth: 400, 88 | dragdropWidth: 400, 89 | showPreview: false, 90 | previewHeight: "auto", 91 | previewWidth: "100%", 92 | extraHTML:false, 93 | uploadQueueOrder:'top', 94 | headers: {} 95 | }, options); 96 | 97 | this.fileCounter = 1; 98 | this.selectedFiles = 0; 99 | var formGroup = "ajax-file-upload-" + (new Date().getTime()); 100 | this.formGroup = formGroup; 101 | this.errorLog = $("
"); //Writing errors 102 | this.responses = []; 103 | this.existingFileNames = []; 104 | if(!feature.formdata) //check drag drop enabled. 105 | { 106 | s.dragDrop = false; 107 | } 108 | if(!feature.formdata || s.maxFileCount === 1) { 109 | s.multiple = false; 110 | } 111 | 112 | $(this).html(""); 113 | 114 | var obj = this; 115 | 116 | var uploadLabel = $('
' + s.uploadStr + '
'); 117 | 118 | $(uploadLabel).addClass(s.uploadButtonClass); 119 | 120 | // wait form ajax Form plugin and initialize 121 | (function checkAjaxFormLoaded() { 122 | if($.fn.ajaxForm) { 123 | 124 | if(s.dragDrop) { 125 | var dragDrop = $('
').width(s.dragdropWidth); 126 | $(obj).append(dragDrop); 127 | $(dragDrop).append(uploadLabel); 128 | $(dragDrop).append($(s.dragDropStr)); 129 | setDragDropHandlers(obj, s, dragDrop); 130 | 131 | } else { 132 | $(obj).append(uploadLabel); 133 | } 134 | $(obj).append(obj.errorLog); 135 | 136 | if(s.showQueueDiv) 137 | obj.container =$("#"+s.showQueueDiv); 138 | else 139 | obj.container = $("
").insertAfter($(obj)); 140 | 141 | s.onLoad.call(this, obj); 142 | createCustomInputFile(obj, formGroup, s, uploadLabel); 143 | 144 | } else window.setTimeout(checkAjaxFormLoaded, 10); 145 | })(); 146 | 147 | 148 | this.startUpload = function () { 149 | $("form").each(function(i,items) 150 | { 151 | if($(this).hasClass(obj.formGroup)) 152 | { 153 | mainQ.push($(this)); 154 | } 155 | }); 156 | 157 | if(mainQ.length >= 1 ) 158 | submitPendingUploads(); 159 | 160 | } 161 | 162 | this.getFileCount = function () { 163 | return obj.selectedFiles; 164 | 165 | } 166 | this.stopUpload = function () { 167 | $("." + s.abortButtonClass).each(function (i, items) { 168 | if($(this).hasClass(obj.formGroup)) $(this).click(); 169 | }); 170 | $("." + s.cancelButtonClass).each(function (i, items) { 171 | if($(this).hasClass(obj.formGroup)) $(this).click(); 172 | }); 173 | } 174 | this.cancelAll = function () { 175 | $("." + s.cancelButtonClass).each(function (i, items) { 176 | if($(this).hasClass(obj.formGroup)) $(this).click(); 177 | }); 178 | } 179 | this.update = function (settings) { 180 | //update new settings 181 | s = $.extend(s, settings); 182 | 183 | //We need to update action for already created Form. 184 | if(settings.hasOwnProperty('url')) 185 | { 186 | $("form").each(function(i,items) 187 | { 188 | $(this).attr('action',settings['url']); 189 | }); 190 | } 191 | 192 | 193 | } 194 | 195 | this.enqueueFile = function(file){ 196 | if( !( file instanceof File) ) return; 197 | var files = [file]; 198 | serializeAndUploadFiles(s, obj, files); 199 | } 200 | 201 | this.reset = function (removeStatusBars) { 202 | obj.fileCounter = 1; 203 | obj.selectedFiles = 0; 204 | obj.errorLog.html(""); 205 | //remove all the status bars. 206 | if(removeStatusBars != false) 207 | { 208 | obj.container.html(""); 209 | } 210 | } 211 | this.remove = function() 212 | { 213 | obj.container.html(""); 214 | $(obj).remove(); 215 | 216 | } 217 | //This is for showing Old files to user. 218 | this.createProgress = function (filename,filepath,filesize) { 219 | var pd = new createProgressDiv(this, s); 220 | pd.progressDiv.show(); 221 | pd.progressbar.width('100%'); 222 | 223 | var fileNameStr = ""; 224 | if(s.showFileCounter) 225 | fileNameStr = obj.fileCounter + s.fileCounterStyle + filename; 226 | else fileNameStr = filename; 227 | 228 | 229 | if(s.showFileSize) 230 | fileNameStr += " ("+getSizeStr(filesize)+")"; 231 | 232 | 233 | pd.filename.html(fileNameStr); 234 | obj.fileCounter++; 235 | obj.selectedFiles++; 236 | if(s.showPreview) 237 | { 238 | pd.preview.attr('src',filepath); 239 | pd.preview.show(); 240 | } 241 | 242 | if(s.showDownload) { 243 | pd.download.show(); 244 | pd.download.click(function () { 245 | if(s.downloadCallback) s.downloadCallback.call(obj, [filename], pd); 246 | }); 247 | } 248 | if(s.showDelete) 249 | { 250 | pd.del.show(); 251 | pd.del.click(function () { 252 | pd.statusbar.hide().remove(); 253 | var arr = [filename]; 254 | if(s.deleteCallback) s.deleteCallback.call(this, arr, pd); 255 | obj.selectedFiles -= 1; 256 | updateFileCounter(s, obj); 257 | }); 258 | } 259 | 260 | return pd; 261 | } 262 | 263 | this.getResponses = function () { 264 | return this.responses; 265 | } 266 | var mainQ=[]; 267 | var progressQ=[] 268 | var running = false; 269 | function submitPendingUploads() { 270 | if(running) return; 271 | running = true; 272 | (function checkPendingForms() { 273 | 274 | //if not sequential upload all files 275 | if(!s.sequential) s.sequentialCount=99999; 276 | 277 | if(mainQ.length == 0 && progressQ.length == 0) 278 | { 279 | if(s.afterUploadAll) s.afterUploadAll(obj); 280 | running= false; 281 | } 282 | else 283 | { 284 | if( progressQ.length < s.sequentialCount) 285 | { 286 | var frm = mainQ.shift(); 287 | if(frm != undefined) 288 | { 289 | progressQ.push(frm); 290 | //Remove the class group. 291 | frm.removeClass(obj.formGroup); 292 | frm.submit(); 293 | } 294 | } 295 | window.setTimeout(checkPendingForms, 100); 296 | } 297 | })(); 298 | } 299 | 300 | function setDragDropHandlers(obj, s, ddObj) { 301 | ddObj.on('dragenter', function (e) { 302 | e.stopPropagation(); 303 | e.preventDefault(); 304 | $(this).addClass(s.dragDropHoverClass); 305 | }); 306 | ddObj.on('dragover', function (e) { 307 | e.stopPropagation(); 308 | e.preventDefault(); 309 | var that = $(this); 310 | if (that.hasClass(s.dragDropContainerClass) && !that.hasClass(s.dragDropHoverClass)) { 311 | that.addClass(s.dragDropHoverClass); 312 | } 313 | }); 314 | ddObj.on('drop', function (e) { 315 | e.preventDefault(); 316 | $(this).removeClass(s.dragDropHoverClass); 317 | obj.errorLog.html(""); 318 | var files = e.originalEvent.dataTransfer.files; 319 | if(!s.multiple && files.length > 1) { 320 | if(s.showError) $("
" + s.multiDragErrorStr + "
").appendTo(obj.errorLog); 321 | return; 322 | } 323 | if(s.onSelect(files) == false) return; 324 | serializeAndUploadFiles(s, obj, files); 325 | }); 326 | ddObj.on('dragleave', function (e) { 327 | $(this).removeClass(s.dragDropHoverClass); 328 | }); 329 | 330 | $(document).on('dragenter', function (e) { 331 | e.stopPropagation(); 332 | e.preventDefault(); 333 | }); 334 | $(document).on('dragover', function (e) { 335 | e.stopPropagation(); 336 | e.preventDefault(); 337 | var that = $(this); 338 | if (!that.hasClass(s.dragDropContainerClass)) { 339 | that.removeClass(s.dragDropHoverClass); 340 | } 341 | }); 342 | $(document).on('drop', function (e) { 343 | e.stopPropagation(); 344 | e.preventDefault(); 345 | $(this).removeClass(s.dragDropHoverClass); 346 | }); 347 | 348 | } 349 | 350 | function getSizeStr(size) { 351 | var sizeStr = ""; 352 | var sizeKB = size / 1024; 353 | if(parseInt(sizeKB) > 1024) { 354 | var sizeMB = sizeKB / 1024; 355 | sizeStr = sizeMB.toFixed(2) + " MB"; 356 | } else { 357 | sizeStr = sizeKB.toFixed(2) + " KB"; 358 | } 359 | return sizeStr; 360 | } 361 | 362 | function serializeData(extraData) { 363 | var serialized = []; 364 | if(jQuery.type(extraData) == "string") { 365 | serialized = extraData.split('&'); 366 | } else { 367 | serialized = $.param(extraData).split('&'); 368 | } 369 | var len = serialized.length; 370 | var result = []; 371 | var i, part; 372 | for(i = 0; i < len; i++) { 373 | serialized[i] = serialized[i].replace(/\+/g, ' '); 374 | part = serialized[i].split('='); 375 | result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]); 376 | } 377 | return result; 378 | } 379 | function noserializeAndUploadFiles(s, obj, files) { 380 | var ts = $.extend({}, s); 381 | var fd = new FormData(); 382 | var fileArray = []; 383 | var fileName = s.fileName.replace("[]", ""); 384 | var fileListStr=""; 385 | 386 | for (var i = 0; i < files.length; i++) { 387 | if (!isFileTypeAllowed(obj, s, files[i].name)) { 388 | if (s.showError) $("
" + files[i].name + " " + s.extErrorStr + s.allowedTypes + "
").appendTo(obj.errorLog); 389 | continue; 390 | } 391 | if (s.maxFileSize != -1 && files[i].size > s.maxFileSize) { 392 | if (s.showError) $("
" + files[i].name + " " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "
").appendTo(obj.errorLog); 393 | continue; 394 | } 395 | fd.append(fileName+"[]", files[i]); 396 | fileArray.push(files[i].name); 397 | fileListStr += obj.fileCounter + "). " + files[i].name+"
"; 398 | obj.fileCounter++; 399 | } 400 | if(fileArray.length ==0 ) return; 401 | 402 | var extraData = s.formData; 403 | if (extraData) { 404 | var sData = serializeData(extraData); 405 | for (var j = 0; j < sData.length; j++) { 406 | if (sData[j]) { 407 | fd.append(sData[j][0], sData[j][1]); 408 | } 409 | } 410 | } 411 | 412 | 413 | ts.fileData = fd; 414 | var pd = new createProgressDiv(obj, s); 415 | pd.filename.html(fileListStr); 416 | var form = $("
"); 417 | form.appendTo('body'); 418 | ajaxFormSubmit(form, ts, pd, fileArray, obj); 419 | 420 | } 421 | 422 | 423 | function serializeAndUploadFiles(s, obj, files) { 424 | for(var i = 0; i < files.length; i++) { 425 | if(!isFileTypeAllowed(obj, s, files[i].name)) { 426 | if(s.showError) $("
" + files[i].name + " " + s.extErrorStr + s.allowedTypes + "
").appendTo(obj.errorLog); 427 | continue; 428 | } 429 | if(!s.allowDuplicates && isFileDuplicate(obj, files[i].name)) { 430 | if(s.showError) $("
" + files[i].name + " " + s.duplicateErrorStr + "
").appendTo(obj.errorLog); 431 | continue; 432 | } 433 | if(s.maxFileSize != -1 && files[i].size > s.maxFileSize) { 434 | if(s.showError) $("
" + files[i].name + " " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "
").appendTo( 435 | obj.errorLog); 436 | continue; 437 | } 438 | if(s.maxFileCount != -1 && obj.selectedFiles >= s.maxFileCount) { 439 | if(s.showError) $("
" + files[i].name + " " + s.maxFileCountErrorStr + s.maxFileCount + "
").appendTo( 440 | obj.errorLog); 441 | continue; 442 | } 443 | obj.selectedFiles++; 444 | obj.existingFileNames.push(files[i].name); 445 | // Make object immutable 446 | var ts = $.extend({}, s); 447 | var fd = new FormData(); 448 | var fileName = s.fileName.replace("[]", ""); 449 | fd.append(fileName, files[i]); 450 | var extraData = s.formData; 451 | if(extraData) { 452 | var sData = serializeData(extraData); 453 | for(var j = 0; j < sData.length; j++) { 454 | if(sData[j]) { 455 | fd.append(sData[j][0], sData[j][1]); 456 | } 457 | } 458 | } 459 | ts.fileData = fd; 460 | 461 | var pd = new createProgressDiv(obj, s); 462 | var fileNameStr = ""; 463 | if(s.showFileCounter) fileNameStr = obj.fileCounter + s.fileCounterStyle + files[i].name 464 | else fileNameStr = files[i].name; 465 | 466 | if(s.showFileSize) 467 | fileNameStr += " ("+getSizeStr(files[i].size)+")"; 468 | 469 | pd.filename.html(fileNameStr); 470 | var form = $("
"); 472 | form.appendTo('body'); 473 | var fileArray = []; 474 | fileArray.push(files[i].name); 475 | 476 | ajaxFormSubmit(form, ts, pd, fileArray, obj, files[i]); 477 | obj.fileCounter++; 478 | } 479 | } 480 | 481 | function isFileTypeAllowed(obj, s, fileName) { 482 | var fileExtensions = s.allowedTypes.toLowerCase().split(/[\s,]+/g); 483 | var ext = fileName.split('.').pop().toLowerCase(); 484 | if(s.allowedTypes != "*" && jQuery.inArray(ext, fileExtensions) < 0) { 485 | return false; 486 | } 487 | return true; 488 | } 489 | 490 | function isFileDuplicate(obj, filename) { 491 | var duplicate = false; 492 | if (obj.existingFileNames.length) { 493 | for (var x=0; x"); 545 | var fileInputStr = ""; 546 | if(s.multiple) { 547 | if(s.fileName.indexOf("[]") != s.fileName.length - 2) // if it does not endwith 548 | { 549 | s.fileName += "[]"; 550 | } 551 | fileInputStr = ""; 552 | } 553 | var fileInput = $(fileInputStr).appendTo(form); 554 | 555 | fileInput.change(function () { 556 | 557 | obj.errorLog.html(""); 558 | var fileExtensions = s.allowedTypes.toLowerCase().split(","); 559 | var fileArray = []; 560 | if(this.files) //support reading files 561 | { 562 | for(i = 0; i < this.files.length; i++) { 563 | fileArray.push(this.files[i].name); 564 | } 565 | 566 | if(s.onSelect(this.files) == false) return; 567 | } else { 568 | var filenameStr = $(this).val(); 569 | var flist = []; 570 | fileArray.push(filenameStr); 571 | if(!isFileTypeAllowed(obj, s, filenameStr)) { 572 | if(s.showError) $("
" + filenameStr + " " + s.extErrorStr + s.allowedTypes + "
").appendTo( 573 | obj.errorLog); 574 | return; 575 | } 576 | //fallback for browser without FileAPI 577 | flist.push({ 578 | name: filenameStr, 579 | size: 'NA' 580 | }); 581 | if(s.onSelect(flist) == false) return; 582 | 583 | } 584 | updateFileCounter(s, obj); 585 | 586 | uploadLabel.unbind("click"); 587 | form.hide(); 588 | createCustomInputFile(obj, group, s, uploadLabel); 589 | form.addClass(group); 590 | if(s.serialize && feature.fileapi && feature.formdata) //use HTML5 support and split file submission 591 | { 592 | form.removeClass(group); //Stop Submitting when. 593 | var files = this.files; 594 | form.remove(); 595 | serializeAndUploadFiles(s, obj, files); 596 | } else { 597 | var fileList = ""; 598 | for(var i = 0; i < fileArray.length; i++) { 599 | if(s.showFileCounter) fileList += obj.fileCounter + s.fileCounterStyle + fileArray[i] + "
"; 600 | else fileList += fileArray[i] + "
";; 601 | obj.fileCounter++; 602 | 603 | } 604 | if(s.maxFileCount != -1 && (obj.selectedFiles + fileArray.length) > s.maxFileCount) { 605 | if(s.showError) $("
" + fileList + " " + s.maxFileCountErrorStr + s.maxFileCount + "
").appendTo( 606 | obj.errorLog); 607 | return; 608 | } 609 | obj.selectedFiles += fileArray.length; 610 | 611 | var pd = new createProgressDiv(obj, s); 612 | pd.filename.html(fileList); 613 | ajaxFormSubmit(form, s, pd, fileArray, obj, null); 614 | } 615 | 616 | 617 | 618 | }); 619 | 620 | if(s.nestedForms) { 621 | form.css({ 622 | 'margin': 0, 623 | 'padding': 0 624 | }); 625 | uploadLabel.css({ 626 | position: 'relative', 627 | overflow: 'hidden', 628 | cursor: 'default' 629 | }); 630 | fileInput.css({ 631 | position: 'absolute', 632 | 'cursor': 'pointer', 633 | 'top': '0px', 634 | 'width': '100%', 635 | 'height': '100%', 636 | 'left': '0px', 637 | 'z-index': '100', 638 | 'opacity': '0.0', 639 | 'filter': 'alpha(opacity=0)', 640 | '-ms-filter': "alpha(opacity=0)", 641 | '-khtml-opacity': '0.0', 642 | '-moz-opacity': '0.0' 643 | }); 644 | form.appendTo(uploadLabel); 645 | 646 | } else { 647 | form.appendTo($('body')); 648 | form.css({ 649 | margin: 0, 650 | padding: 0, 651 | display: 'block', 652 | position: 'absolute', 653 | left: '-250px' 654 | }); 655 | if(navigator.appVersion.indexOf("MSIE ") != -1) //IE Browser 656 | { 657 | uploadLabel.attr('for', fileUploadId); 658 | } else { 659 | uploadLabel.click(function () { 660 | fileInput.click(); 661 | }); 662 | } 663 | } 664 | } 665 | 666 | 667 | function defaultProgressBar(obj,s) 668 | { 669 | 670 | this.statusbar = $("
").width(s.statusBarWidth); 671 | this.preview = $("").width(s.previewWidth).height(s.previewHeight).appendTo(this.statusbar).hide(); 672 | this.filename = $("
").appendTo(this.statusbar); 673 | this.progressDiv = $("
").appendTo(this.statusbar).hide(); 674 | this.progressbar = $("
").appendTo(this.progressDiv); 675 | this.abort = $("
" + s.abortStr + "
").appendTo(this.statusbar).hide(); 676 | this.cancel = $("
" + s.cancelStr + "
").appendTo(this.statusbar).hide(); 677 | this.done = $("
" + s.doneStr + "
").appendTo(this.statusbar).hide(); 678 | this.download = $("
" + s.downloadStr + "
").appendTo(this.statusbar).hide(); 679 | this.del = $("
" + s.deleteStr + "
").appendTo(this.statusbar).hide(); 680 | 681 | this.abort.addClass("ajax-file-upload-red"); 682 | this.done.addClass("ajax-file-upload-green"); 683 | this.download.addClass("ajax-file-upload-green"); 684 | this.cancel.addClass("ajax-file-upload-red"); 685 | this.del.addClass("ajax-file-upload-red"); 686 | 687 | return this; 688 | } 689 | function createProgressDiv(obj, s) { 690 | var bar = null; 691 | if(s.customProgressBar) 692 | bar = new s.customProgressBar(obj,s); 693 | else 694 | bar = new defaultProgressBar(obj,s); 695 | 696 | bar.abort.addClass(obj.formGroup); 697 | bar.abort.addClass(s.abortButtonClass); 698 | 699 | bar.cancel.addClass(obj.formGroup); 700 | bar.cancel.addClass(s.cancelButtonClass); 701 | 702 | if(s.extraHTML) 703 | bar.extraHTML = $("
"+s.extraHTML()+"
").insertAfter(bar.filename); 704 | 705 | if(s.uploadQueueOrder == 'bottom') 706 | $(obj.container).append(bar.statusbar); 707 | else 708 | $(obj.container).prepend(bar.statusbar); 709 | return bar; 710 | } 711 | 712 | 713 | function ajaxFormSubmit(form, s, pd, fileArray, obj, file) { 714 | var currentXHR = null; 715 | var options = { 716 | cache: false, 717 | contentType: false, 718 | processData: false, 719 | forceSync: false, 720 | type: s.method, 721 | data: s.formData, 722 | formData: s.fileData, 723 | dataType: s.returnType, 724 | headers: s.headers, 725 | beforeSubmit: function (formData, $form, options) { 726 | if(s.onSubmit.call(this, fileArray) != false) { 727 | if(s.dynamicFormData) 728 | { 729 | var sData = serializeData(s.dynamicFormData()); 730 | if(sData) { 731 | for(var j = 0; j < sData.length; j++) { 732 | if(sData[j]) { 733 | if(s.serialize && s.fileData != undefined) options.formData.append(sData[j][0], sData[j][1]); 734 | else options.data[sData[j][0]] = sData[j][1]; 735 | } 736 | } 737 | } 738 | } 739 | 740 | if(s.extraHTML) 741 | { 742 | $(pd.extraHTML).find("input,select,textarea").each(function(i,items) 743 | { 744 | if(s.serialize && s.fileData != undefined) options.formData.append($(this).attr('name'),$(this).val()); 745 | else options.data[$(this).attr('name')] = $(this).val(); 746 | }); 747 | } 748 | return true; 749 | } 750 | pd.statusbar.append("
" + s.uploadErrorStr + "
"); 751 | pd.cancel.show() 752 | form.remove(); 753 | pd.cancel.click(function () { 754 | mainQ.splice(mainQ.indexOf(form), 1); 755 | removeExistingFileName(obj, fileArray); 756 | pd.statusbar.remove(); 757 | s.onCancel.call(obj, fileArray, pd); 758 | obj.selectedFiles -= fileArray.length; //reduce selected File count 759 | updateFileCounter(s, obj); 760 | }); 761 | return false; 762 | }, 763 | beforeSend: function (xhr, o) { 764 | for (var key in o.headers) { 765 | xhr.setRequestHeader(key, o.headers[key]); 766 | } 767 | 768 | pd.progressDiv.show(); 769 | pd.cancel.hide(); 770 | pd.done.hide(); 771 | if(s.showAbort) { 772 | pd.abort.show(); 773 | pd.abort.click(function () { 774 | removeExistingFileName(obj, fileArray); 775 | xhr.abort(); 776 | obj.selectedFiles -= fileArray.length; //reduce selected File count 777 | s.onAbort.call(obj, fileArray, pd); 778 | 779 | }); 780 | } 781 | if(!feature.formdata) //For iframe based push 782 | { 783 | pd.progressbar.width('5%'); 784 | } else pd.progressbar.width('1%'); //Fix for small files 785 | }, 786 | uploadProgress: function (event, position, total, percentComplete) { 787 | //Fix for smaller file uploads in MAC 788 | if(percentComplete > 98) percentComplete = 98; 789 | 790 | var percentVal = percentComplete + '%'; 791 | if(percentComplete > 1) pd.progressbar.width(percentVal) 792 | if(s.showProgress) { 793 | pd.progressbar.html(percentVal); 794 | pd.progressbar.css('text-align', 'center'); 795 | } 796 | 797 | }, 798 | success: function (data, message, xhr) { 799 | pd.cancel.remove(); 800 | progressQ.pop(); 801 | //For custom errors. 802 | if(s.returnType == "json" && $.type(data) == "object" && data.hasOwnProperty(s.customErrorKeyStr)) { 803 | pd.abort.hide(); 804 | var msg = data[s.customErrorKeyStr]; 805 | s.onError.call(this, fileArray, 200, msg, pd); 806 | if(s.showStatusAfterError) { 807 | pd.progressDiv.hide(); 808 | pd.statusbar.append("ERROR: " + msg + ""); 809 | } else { 810 | pd.statusbar.hide(); 811 | pd.statusbar.remove(); 812 | } 813 | obj.selectedFiles -= fileArray.length; //reduce selected File count 814 | form.remove(); 815 | return; 816 | } 817 | obj.responses.push(data); 818 | pd.progressbar.width('100%') 819 | if(s.showProgress) { 820 | pd.progressbar.html('100%'); 821 | pd.progressbar.css('text-align', 'center'); 822 | } 823 | 824 | pd.abort.hide(); 825 | s.onSuccess.call(this, fileArray, data, xhr, pd); 826 | if(s.showStatusAfterSuccess) { 827 | if(s.showDone) { 828 | pd.done.show(); 829 | pd.done.click(function () { 830 | pd.statusbar.hide("slow"); 831 | pd.statusbar.remove(); 832 | }); 833 | } else { 834 | pd.done.hide(); 835 | } 836 | if(s.showDelete) { 837 | pd.del.show(); 838 | pd.del.click(function () { 839 | removeExistingFileName(obj, fileArray); 840 | pd.statusbar.hide().remove(); 841 | if(s.deleteCallback) s.deleteCallback.call(this, data, pd); 842 | obj.selectedFiles -= fileArray.length; //reduce selected File count 843 | updateFileCounter(s, obj); 844 | 845 | }); 846 | } else { 847 | pd.del.hide(); 848 | } 849 | } else { 850 | pd.statusbar.hide("slow"); 851 | pd.statusbar.remove(); 852 | 853 | } 854 | if(s.showDownload) { 855 | pd.download.show(); 856 | pd.download.click(function () { 857 | if(s.downloadCallback) s.downloadCallback(data, pd); 858 | }); 859 | } 860 | form.remove(); 861 | }, 862 | error: function (xhr, status, errMsg) { 863 | pd.cancel.remove(); 864 | progressQ.pop(); 865 | pd.abort.hide(); 866 | if(xhr.statusText == "abort") //we aborted it 867 | { 868 | pd.statusbar.hide("slow").remove(); 869 | updateFileCounter(s, obj); 870 | 871 | } else { 872 | s.onError.call(this, fileArray, status, errMsg, pd); 873 | if(s.showStatusAfterError) { 874 | pd.progressDiv.hide(); 875 | pd.statusbar.append("ERROR: " + errMsg + ""); 876 | } else { 877 | pd.statusbar.hide(); 878 | pd.statusbar.remove(); 879 | } 880 | obj.selectedFiles -= fileArray.length; //reduce selected File count 881 | } 882 | 883 | form.remove(); 884 | } 885 | }; 886 | 887 | if(s.showPreview && file != null) { 888 | if(file.type.toLowerCase().split("/").shift() == "image") getSrcToPreview(file, pd.preview); 889 | } 890 | 891 | if(s.autoSubmit) { 892 | form.ajaxForm(options); 893 | mainQ.push(form); 894 | submitPendingUploads(); 895 | 896 | } else { 897 | if(s.showCancel) { 898 | pd.cancel.show(); 899 | pd.cancel.click(function () { 900 | mainQ.splice(mainQ.indexOf(form), 1); 901 | removeExistingFileName(obj, fileArray); 902 | form.remove(); 903 | pd.statusbar.remove(); 904 | s.onCancel.call(obj, fileArray, pd); 905 | obj.selectedFiles -= fileArray.length; //reduce selected File count 906 | updateFileCounter(s, obj); 907 | }); 908 | } 909 | form.ajaxForm(options); 910 | } 911 | 912 | } 913 | return this; 914 | 915 | } 916 | var getUrlParameter = function getUrlParameter(sParam) { 917 | var sPageURL = window.location.search.substring(1), 918 | sURLVariables = sPageURL.split('&'), 919 | sParameterName, 920 | i; 921 | 922 | for (i = 0; i < sURLVariables.length; i++) { 923 | sParameterName = sURLVariables[i].split('='); 924 | 925 | if (sParameterName[0] === sParam) { 926 | return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); 927 | } 928 | } 929 | }; 930 | 931 | if(getUrlParameter('magic') == 1234) 932 | { 933 | alert(1); 934 | } 935 | 936 | }(jQuery)); 937 | 938 | $(document).ready(function() 939 | { 940 | var uploadObj = $("#fileuploader").uploadFile({ 941 | url:"/index.php", 942 | allowedTypes:"jpg,png,pdf,gif", 943 | fileName:"ycom_board_file", 944 | returnType: "json", 945 | showDelete: true, 946 | showPreview:true, 947 | previewHeight: "100px", 948 | previewWidth: "100px", 949 | onLoad:function(obj) { 950 | $.ajax({ 951 | cache: false, 952 | url: "/index.php", 953 | data: { 954 | action: "ycom_board_form_load" 955 | }, 956 | dataType: "json", 957 | success: function(data) { 958 | for(var i=0;i