data.func.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. <?php
  2. /* REQUEST HANDLING */
  3. // Handle navigation request & update session.
  4. if(isset($_POST['set-navigation'])) {
  5. $_SESSION[_sid]['view'] = $_POST['set-navigation'];
  6. echo $_SESSION[_sid]['view'];
  7. }
  8. // Get item data with quick search.
  9. if(isset($_POST['quick-item-search'])) {
  10. echo json_encode(quick_item_search($_POST['quick-item-search']));
  11. }
  12. // Get item data with quick search.
  13. if(isset($_POST['edit-item'])) {
  14. echo json_encode(edit_item($_POST['data']));
  15. }
  16. // Get item to be edited.
  17. if(isset($_POST['get-edit-item'])) {
  18. $item = get_item_data($_POST['get-edit-item']);
  19. include('inc/forms/form.edit.item.php');
  20. echo '
  21. <div class="row"><div class="col-lg-12"><h1>&nbsp;<hr></hr></h1></div></div>
  22. <div class="row">
  23. '.get_item_edit_form($item).'
  24. </div>
  25. <p class="display-4 animated flipInX" style="font-size:22pt!important;"><i class="fad fa-debug text-danger"></i> Debug Output</p>
  26. <pre class="text-left panel-tag">'.print_r($item,1).'</pre>
  27. <script>
  28. $(\'#item-editor-header-label\').empty().append(\'<span class="inline animated bounceIn"><i class="fad fa-caret-right"></i> '.$item['name'].'</span>\');
  29. $(\'#item-editor-header-label\').switchClass("btn-info","btn-primary");
  30. </script>';
  31. }
  32. // Get item icons by selected category.
  33. if(isset($_POST['get-item-icons'])) {
  34. require('inc/data.item.icons.php');
  35. echo get_icon_picker($itemIcons, 'icons', $_POST['get-item-icons'], (isset($_POST['page']) ? $_POST['page']:1));
  36. }
  37. /* GET FUNCTIONS */
  38. /* Edit Item Function */
  39. function edit_item($data, $return = ['status'=>true, 'msg'=>'', 'rows'=>0]) {
  40. global $world;
  41. foreach($data as $table => $o) {
  42. $query = '
  43. UPDATE `'.addslashes($table).'`
  44. SET';
  45. $pass = 0;
  46. foreach($o['fields'] as $field => $value) {
  47. $query .= ($pass > 0 ? ',':NULL).'
  48. `'.addslashes($field).'` = "'.addslashes($value).'"';
  49. $pass++;
  50. }
  51. $query .= '
  52. WHERE `'.addslashes($o['key']).'` = '.addslashes($o['id']);
  53. $return['query'] = $query;
  54. try {
  55. $stmt = $world->prepare($query);
  56. $stmt->execute();
  57. $return['rows'] = $stmt->rowCount();
  58. $return['status'] = true;
  59. } catch(PDOException $e) {
  60. $return['status'] = false;
  61. $return['msg'] = $e->getMessage();
  62. }
  63. }
  64. return $return;
  65. }
  66. function get_icon_picker($icons, $type = 'icons', $category = 'Adornment', $page = 1, $limit = 133, $return = NULL) {
  67. $pass = 0;
  68. if($type == 'categories') {
  69. $return .= '
  70. <button class="icopicker-category btn btn-sm btn-block btn-default" data-category="all">All</button>';
  71. foreach($icons as $c => $i) {
  72. $return .= '
  73. <button class="icopicker-category btn btn-sm btn-block btn-default" data-category="'.$c.'">
  74. '.$c.'
  75. </button>';
  76. $pass++;
  77. }
  78. $return .= '<script>setTimeout(function() { $(\'.icopicker-category[data-category="Adornment"]\').trigger(\'click\'); },500); </script>';
  79. } else {
  80. $from = ($limit*$page)-$limit;
  81. $to = ($limit*$page);
  82. $pass++;
  83. if($category == 'all') {
  84. $ico = [];
  85. foreach($icons as $c => $v) {
  86. foreach($v['icons'] as $i) {
  87. if(!in_array($i, $ico)) {
  88. $ico[] = $i;
  89. }
  90. }
  91. }
  92. } else {
  93. $ico = $icons[$category]['icons'];
  94. }
  95. $pass = 0;
  96. foreach($ico as $k => $i) {
  97. if(($pass >= $from) && ($pass+1 <= $to)) {
  98. $return .= '<div class="ico-picker-i ico-unloaded" data-icon-id="'.$i.'"><span class="ico-picker-loader"><i class="fal fa-circle-notch color-info-400 fa-spin fast-spin opacity-50"></i></div>';
  99. }
  100. $pass++;
  101. }
  102. }
  103. $pagination = ($type == 'icons' ? '<div class="ico-picker-pagination">'.ico_pagination($category, $page, $limit, count($ico)).'</div>':NULL);
  104. return $pagination.$return;
  105. }
  106. //Generates pagination for icons.
  107. function ico_pagination($category, $p, $limit, $count, $return = NULL) {
  108. $return .= '<button class="btn btn-xs btn-default '.($p == 1 ? 'hidden':NULL).'" data-category="'.$category.'"><strong class="color-info-400">1</strong> <i class="fad fa-arrow-from-right"></i></button>';
  109. $page_count = ceil($count/$limit);
  110. $showEndButton = false;
  111. if($page_count > 1) {
  112. if(($p-5) > 1) {
  113. $return .= '<span class="ico-picker-ellipsis"><i class="fas fa-ellipsis-h-alt"></i></span>';
  114. }
  115. for ($k = 1 ; $k <= $page_count; $k++){
  116. if(($k >= ($p-5)) && ($k <= ($p+5))) {
  117. $return .= '
  118. <button class="btn btn-xs ico-picker-page '.($p == $k ? 'btn-success animated jello':'btn-default').'" '.($p == $k ? 'disabled="disabled"':NULL).' data-page="'.$k.'" data-category="'.$category.'">
  119. '.$k.'
  120. </button>';
  121. }
  122. }
  123. if(($p+5) < $page_count) {
  124. $return .= '<span class="ico-picker-ellipsis"><i class="fas fa-ellipsis-h-alt"></i></span>';
  125. $showEndButton = true;
  126. } else { $showEndButton = false; }
  127. } else {
  128. $return .= '
  129. <button class="btn btn-xs ico-picker-page btn-success" data-page="'.$p.'" data-category="'.$category.'" disabled="disabled">
  130. '.$p.'
  131. </button>';
  132. }
  133. if($showEndButton && $p != $page_count) {
  134. $return .= '
  135. <button class="btn btn-xs btn-default ico-picker-page" data-page="'.$page_count.'" data-category="'.$category.'">
  136. <i class="fad fa-arrow-from-left"></i> <strong class="color-info-400">'.$page_count.'</strong>
  137. </button>';
  138. }
  139. return $return;
  140. }
  141. //Global function to build editable inputs. (WIP)
  142. function build_edit_input($e, $return = NULL) {
  143. if(!isset($e['type'])) { $e['type'] = 'text'; }
  144. if(!isset($e['table'])) { $table = 'data-table=""'; } else { $table = 'data-table="'.$e['table'].'"'; }
  145. if(!isset($e['field_type'])) {
  146. $return = '
  147. <div class="form-group mb-2">
  148. <label class="form-label '.($e['show-label'] ? NULL:'hidden').'" for="basic-addon1">'.$e['title'].'</label>
  149. <div class="input-group">
  150. <div class="input-group-prepend">
  151. <span class="input-group-text strong">'.($e['icon'] ? '<i class="'.$e['icon'].'"></i>':NULL).'&nbsp;'.$e['title'].'</span>
  152. </div>
  153. <input type="'.$e['type'].'" class="form-control '.$e['class'].'" '.$table.' data-key="'.$e['key'].'" data-id="'.$e['id'].'" data-field="'.$e['field'].'" value="'.$e['value'].'" placeholder="'.($e['placeholder'] ? $e['placeholder']:NULL).'" aria-label="'.($e['aria'] ? $e['aria']:NULL).'" aria-describedby="'.$e['field'].'"/>
  154. </div>'.($e['desc'] ? '<span class="help-block">'.$e['desc'].'</span>':NULL).'
  155. </div>';
  156. } else {
  157. if($e['field_type'] == 'textarea') {
  158. $return = '
  159. <div class="form-group mb-2">
  160. <label class="form-label '.($e['show-label'] ? NULL:'hidden').'" for="basic-addon1">'.$e['title'].'</label>
  161. <div class="input-group">
  162. <div class="input-group-prepend">
  163. <span class="input-group-text strong">'.($e['icon'] ? '<i class="'.$e['icon'].'"></i>':NULL).'&nbsp;'.$e['title'].'</span>
  164. </div>
  165. <textarea class="form-control '.$e['class'].'" '.$table.' data-key="'.$e['key'].'" data-id="'.$e['id'].'" data-field="'.$e['field'].'" placeholder="'.($e['placeholder'] ? $e['placeholder']:NULL).'" aria-label="'.($e['aria'] ? $e['aria']:NULL).'" aria-describedby="'.$e['field'].'">'
  166. .$e['value'].
  167. '</textarea>
  168. </div>'.($e['desc'] ? '<span class="help-block">'.$e['desc'].'</span>':NULL).'
  169. </div>';
  170. } else if($e['field_type'] == 'select') {
  171. $return = '
  172. <div class="form-group mb-2">
  173. <label class="form-label '.($e['show-label'] ? NULL:'hidden').'" for="basic-addon1">'.$e['title'].'</label>
  174. <div class="input-group">
  175. <div class="input-group-prepend">
  176. <span class="input-group-text strong">'.($e['icon'] ? '<i class="'.$e['icon'].'"></i>':NULL).'&nbsp;'.$e['title'].'</span>
  177. </div>
  178. <select class="custom-select form-control '.$e['class'].'" '.$table.' data-key="'.$e['key'].'" data-id="'.$e['id'].'" data-field="'.$e['field'].'">
  179. '.(array_to_options($e['options'], $e['value'])).'
  180. </select>
  181. </div>'.($e['desc'] ? '<span class="help-block">'.$e['desc'].'</span>':NULL).'
  182. </div>';
  183. } else if($e['field_type'] == 'switch') {
  184. $return = '
  185. <div class="custom-control custom-switch">
  186. <input type="checkbox" class="custom-control-input '.$e['class'].'" '.($e['value'] == 1 ? 'checked="checked"':NULL).' id="ies_'.$e['field'].'" name="ie_'.$e['field'].'_'.$e['id'].'" '.$table.' data-key="'.$e['key'].'" data-id="'.$e['id'].'" data-field="'.$e['field'].'">
  187. <label class="custom-control-label '.($e['show-label'] ? NULL:'hidden').'" for="ies_'.$e['field'].'">'.(strlen($e['icon']) > 0 ? '<i class="'.$e['icon'].'"></i> ':NULL).$e['title'].'</label>
  188. </div>'.($e['desc'] ? '<span class="help-block">'.$e['desc'].'</span>':NULL);
  189. }
  190. }
  191. return $return;
  192. }
  193. $exclude_debug_fieldlist = [
  194. 'icon','id','name','item_type','lore','temporary','artifact','notrade','nodestroy','show_name',
  195. 'crafted'
  196. ];
  197. //Convert array to select option values with option to exclude a pre-selected value.
  198. function array_to_options($a, $preselected = NULL, $return = NULL) {
  199. foreach($a as $k => $v) {
  200. if(isset($v['id'])) {
  201. //Template Array: ['id'=>$row['id'], 'short'=>$row['short_name'], 'name'=>$row['name'], 'desc'=>$row['description']];
  202. $return .= '
  203. <option value="'.$v['id'].'" data-desc="'.$v['desc'].'" '.($preselected == $v['id'] ? 'selected="selected"':NULL).'>'.$v['name'].' ('.$v['id'].')</option>';
  204. } else { //For 2d arrays
  205. $return .= '
  206. <option value="'.$v.'" '.($preselected == $v ? 'selected="selected"':NULL).'>'.$v.'</option>';
  207. }
  208. }
  209. return $return;
  210. }
  211. // Builds list of item skills in option format
  212. function get_skills($skill_ids = [], $get_array = false, $return = NULL) {
  213. global $world;
  214. $query = '
  215. SELECT
  216. s.`id`,
  217. s.`short_name`,
  218. s.`name`,
  219. s.`description`,
  220. s.`skill_type`,
  221. s.`display`
  222. FROM skills AS s
  223. '.(count($skill_ids) > 0 ? 'WHERE s.`id` IN('.implode(', ',$skill_ids).')':NULL).'
  224. ORDER BY s.`skill_type`, s.`name`';
  225. //The listed ID's appeared in no original items that were listed as skill requirements.
  226. $stmt = $world->prepare($query);
  227. $stmt->execute();
  228. if($get_array) {
  229. $return = [['id'=>0, 'short'=>'none', 'name'=>'None', 'desc'=>NULL]];
  230. } else {
  231. $return .= '<option value="0" data-shortname="none" data-desc="">None</option>';
  232. }
  233. while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  234. if($get_array) {
  235. $return[] = ['id'=>$row['id'], 'short'=>$row['short_name'], 'name'=>$row['name'], 'desc'=>$row['description']];
  236. } else {
  237. $return .= '<option value="'.$row['id'].'" data-shortname="'.$row['short_name'].'" data-desc="'.$row['description'].'">'.$row['name'].'('.$row['id'].')</option>';
  238. }
  239. }
  240. return $return;
  241. }
  242. // Builds item edit form inputs & form. - Deprecated! Only for debugging.
  243. function get_item_edit_form($item, $return = NULL) {
  244. global $exclude_debug_fieldlist;
  245. $pass = 0;
  246. foreach($item as $k => $v) {
  247. if(!in_array($k,$exclude_debug_fieldlist)) {
  248. $return .= '
  249. <div class="col-'.($k == 'id' ? '2':'4').'">
  250. <div class="form-group">
  251. <label class="form-label hidden" for="basic-addon1">'.$k.'</label>
  252. <div class="input-group">
  253. <div class="input-group-prepend">
  254. <span class="input-group-text strong">'.$k.'</span>
  255. </div>
  256. <input type="text" class="form-control item-edit-input" value="'.$v.'" placeholder="'.$k.'" aria-label="'.$k.'" aria-describedby="'.$k.'">
  257. </div>
  258. <span class="help-block">&nbsp;</span>
  259. </div>
  260. </div>';
  261. }
  262. }
  263. return $return;
  264. }
  265. // Get Item Data
  266. function get_item_data($id, $return = []) {
  267. global $world;
  268. $query = '
  269. SELECT
  270. i.`id`,
  271. i.`name`,
  272. i.`item_type`,
  273. i.`icon`,
  274. i.`count`,
  275. i.`tier`,
  276. i.`skill_id_req`,
  277. i.`skill_id_req2`,
  278. i.`skill_min`,
  279. i.`weight`,
  280. i.`description`,
  281. i.`show_name`,
  282. i.`attuneable`,
  283. i.`artifact`,
  284. i.`lore`,
  285. i.`temporary`,
  286. i.`notrade`,
  287. i.`novalue`,
  288. i.`nozone`,
  289. i.`nodestroy`,
  290. i.`crafted`,
  291. i.`good_only`,
  292. i.`evil_only`,
  293. i.`stacklore`,
  294. i.`lore_equip`,
  295. i.`flags_16384`,
  296. i.`flags_32768`,
  297. i.`ornate`,
  298. i.`heirloom`,
  299. i.`appearance_only`,
  300. i.`unlocked`,
  301. i.`reforged`,
  302. i.`norepair`,
  303. i.`etheral`,
  304. i.`refined`,
  305. i.`flags2_256`,
  306. i.`usable`,
  307. i.`slots`,
  308. i.`set_name`,
  309. i.`sell_price`,
  310. i.`sell_status_amount`,
  311. i.`stack_count`,
  312. i.`collectable`,
  313. i.`adornment_slot1`,
  314. i.`adornment_slot2`,
  315. i.`adornment_slot3`,
  316. i.`adornment_slot4`,
  317. i.`adornment_slot5`,
  318. i.`adornment_slot6`,
  319. i.`adornment_description`,
  320. i.`offers_quest_id`,
  321. i.`soe_autoquest_id`,
  322. i.`part_of_quest_id`,
  323. i.`quest_unknown`,
  324. i.`max_charges`,
  325. i.`display_charges`,
  326. i.`recommended_level`,
  327. i.`adventure_default_level`,
  328. i.`tradeskill_default_level`,
  329. i.`adventure_classes`,
  330. i.`tradeskill_classes`,
  331. i.`soe_item_id`,
  332. i.`soe_item_crc`,
  333. i.`lua_script`,
  334. i.`harvest`
  335. FROM `items` as `i`
  336. WHERE `i`.`id` = '.addslashes($id);
  337. $stmt = $world->prepare($query);
  338. $stmt->execute();
  339. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  340. $return = $row;
  341. return $return;
  342. }
  343. // Quick Item Search
  344. function quick_item_search($s, $limit = 100, $page = 0, $return = []) {
  345. global $world;
  346. $return = [
  347. 'found' => 0,
  348. 'count' => 0,
  349. 'rows' => [],
  350. 'limit' => $limit,
  351. 'page' => $page
  352. ];
  353. $query = '
  354. SELECT
  355. SQL_CALC_FOUND_ROWS
  356. i.`id`,
  357. i.`name`,
  358. i.`item_type`,
  359. i.`icon`
  360. FROM `items` as `i`
  361. WHERE i.`id` = \''.addslashes($s).'\'
  362. OR i.`name` LIKE \'%'.addslashes(str_replace(' ', '%%',$s)).'%\'
  363. OR LOWER(i.`item_type`) = LOWER(\''.addslashes($s).'\')
  364. LIMIT '.$limit;
  365. //error_log($query,1);
  366. $stmt = $world->prepare($query);
  367. $stmt->execute();
  368. $rc = $stmt->rowCount();
  369. if($rc > 0) {
  370. $return['found'] = get_found_count();
  371. $return['count'] = $rc;
  372. while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  373. $return['rows'][] = $row;
  374. }
  375. }
  376. return $return;
  377. }
  378. //Returns count of rows found (if LIMIT had not been used).
  379. //Note: Requires SQL_CALC_FOUND_ROWS after SELECT.
  380. function get_found_count() {
  381. global $world;
  382. $query = 'SELECT FOUND_ROWS() as `found`;';
  383. $stmt = $world->prepare($query);
  384. $stmt->execute();
  385. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  386. return $row['found'];
  387. }
  388. //Returns count of characters.
  389. function get_character_count($return = 0) {
  390. global $world;
  391. $query = 'SELECT count(DISTINCT `id`) as `count` FROM `characters`';
  392. $stmt = $world->prepare($query);
  393. $stmt->execute();
  394. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  395. $return = $row['count'];
  396. return $return;
  397. }
  398. //Get World Information.
  399. function get_world_info($world_name = NULL, $return = []) {
  400. global $_db, $login;
  401. $world_name = ($world_name == NULL ? _world:$world_name);
  402. $query = '
  403. SELECT
  404. w.id,
  405. w.name,
  406. w.disabled,
  407. w.account,
  408. w.description,
  409. w.password,
  410. w.serverop,
  411. w.greenname,
  412. w.note,
  413. w.ip_address,
  414. w.login_version,
  415. DATE_FORMAT(FROM_UNIXTIME(w.lastseen), "%m/%d/%y %h:%i %p") AS `lastseen`
  416. FROM login_worldservers AS w
  417. WHERE w.name = \''.$world_name.'\'';
  418. $stmt = $login->prepare($query);
  419. $stmt->execute();
  420. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  421. $return = $row;
  422. return $return;
  423. }
  424. //Pulls variable data from world db.
  425. function get_world_variables($return = []) {
  426. global $world;
  427. $query = '
  428. SELECT
  429. v.variable_name,
  430. v.variable_value,
  431. v.comment
  432. FROM variables as v';
  433. $stmt = $world->prepare($query);
  434. $stmt->execute();
  435. while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  436. $return[$row['variable_name']] = [
  437. 'value' => $row['variable_value'],
  438. 'desc' => $row['comment']
  439. ];
  440. }
  441. return $return;
  442. }
  443. /* UTILITY FUNCTIONS */
  444. // Loads HTML output for left navigation menu.
  445. function get_nav_menu($return = NULL) {
  446. global $_modules, $_SESSION;
  447. $active = $_SESSION[_sid]['view'];
  448. foreach($_modules as $k => $m) {
  449. $access = !empty(array_intersect($_SESSION[_sid]['user']['access'], $m['access']));
  450. if($access) {
  451. if($m['type'] == 'module') {
  452. $return .= '
  453. <li class="'.($active == $k ? 'active':NULL).' eq-nav-link" data-module="'.$k.'">
  454. <a class="waves-effect waves-themed" href="#" title="'.$m['desc'].'">
  455. '.($m['icon'] ? '<i class="'.$m['icon'].'"></i>':NULL).'
  456. <span class="nav-link-text" data-il8n="nav.ui_components">'.$m['title'].'</span>
  457. </a>
  458. </li>';
  459. } else if($m['type'] == 'category') {
  460. $return .= '
  461. <li class="nav-title">
  462. '.($m['icon'] ? '<i class="'.$m['icon'].'"></i>':NULL).' '.$m['title'].'
  463. </li>';
  464. }
  465. }
  466. }
  467. return $return;
  468. }
  469. ?>