1<?php
2/*
3 * e107 website system
4 *
5 * Copyright (C) 2008-2013 e107 Inc (e107.org)
6 * Released under the terms and conditions of the
7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
8 *
9 */
10
11if (!e107::isInstalled('download')) { exit(); }
12
13class download
14{
15
16	private $qry = array();
17
18	private $orderOptions = array('download_id','download_datestamp','download_filesize','download_name','download_author','download_requested');
19
20	private $templateHeader = '';
21	private $templateFooter = '';
22
23	private $subCategories = array();
24	private $categories = array();
25	private $template = array();
26	private $sc = null; // shortcode object.
27	private $rows = array();
28
29	function __construct()
30	{
31
32		require_once(e_PLUGIN."download/download_shortcodes.php");
33
34		if(deftrue('BOOTSTRAP')) // v2.x
35		{
36			$this->templateHeader = e107::getTemplate('download','download','header');
37			$this->templateFooter = e107::getTemplate('download','download','footer');
38		}
39		else
40		{
41			$this->templateHeader = '';
42			$this->templateFooter = '';
43		}
44
45		$pref = e107::getPref();
46
47	//	$catObj = new downloadCategory(varset($pref['download_subsub'],1),USERCLASS_LIST,null, varset($pref['download_incinfo'], false));
48	//	$this->categories = $catObj->cat_tree;
49		$this->loadCategories();
50
51
52	}
53
54	private function loadCategories()
55	{
56		$sql = e107::getDb();
57		$data = $sql->retrieve("download_category", '*', 'ORDER BY download_category_order',true);
58
59		foreach($data as $row)
60		{
61
62			$id = (int) $row['download_category_parent'];
63			$sub= (int) $row['download_category_id'];
64
65			$this->subCategories[$id][$sub] = $row;
66			if(check_class($row['download_category_class']))
67			{
68				$this->categories[$sub] = $row;
69			}
70
71		}
72
73
74		return $this;
75	}
76
77	private function getCategory($id)
78	{
79		return !empty($this->categories[$id]) ? $this->categories[$id] : false;
80
81	}
82
83	private function getParent($id)
84	{
85		$parent = $this->categories[$id]['download_category_parent'];
86		return $this->getCategory($parent);
87	}
88
89	private function getChildren($parent)
90	{
91		return !empty($this->subCategories[$parent]) ? $this->subCategories[$parent] : false;
92	}
93
94	public function init()
95	{
96
97		$tp = e107::getParser();
98		$pref = e107::getPref();
99
100		$tmp = explode('.', e_QUERY);
101
102		$order = str_replace("download_","",$pref['download_order']);
103
104		// Set Defaults
105		$this->qry['action']		= 'maincats';
106		$this->qry['order'] 		= vartrue($order, 'datestamp');
107		$this->qry['sort']			= vartrue($pref['download_sort'], 'desc');
108		$this->qry['view'] 			= vartrue($pref['download_view'], 10);
109		$this->qry['from']			= 0;
110
111		// v2.x
112		if(!empty($_GET['action']))
113		{
114			$this->qry['action'] 	= (string) $_GET['action'];
115			$this->qry['view'] 		= varset($_GET['view']) ? intval($_GET['view']) : $this->qry['view'];
116			$this->qry['id']		= intval($_GET['id']);
117			$this->qry['order'] 	= vartrue($_GET['order']) && in_array("download_".$_GET['order'],$this->orderOptions) ? $_GET['order'] : $this->qry['order'];
118			$this->qry['sort'] 		= (varset($_GET['sort']) == 'asc') ? "asc" : 'desc';
119			$this->qry['from']		= varset($_GET['from'],0);
120
121			if($this->qry['action'] == 'error')
122			{
123				$this->qry['error'] = intval($this->qry['id']);
124			}
125		}
126		else // v1.x Legacy URL support.
127		{
128			if (is_numeric($tmp[0]))	//legacy		// $tmp[0] at least must be valid
129			{
130			   $this->qry['action'] 	= varset(preg_replace("#\W#", "", $tp->toDB($tmp[1])),'list');
131			   $this->qry['id'] 		= intval($tmp[2]);
132			   $this->qry['view'] 		= intval($tmp[3]);
133			   $this->qry['order'] 		= preg_replace("#\W#", "", $tp->toDB($tmp[4]));
134			   $this->qry['sort'] 		= preg_replace("#\W#", "", $tp->toDB($tmp[5]));
135		   	}
136			elseif($tmp[1])
137		   	{
138			   $this->qry['action'] 	= preg_replace("#\W#", "", $tp->toDB($tmp[0]));
139			   $this->qry['id'] 		= intval($tmp[1]);
140			   $this->qry['error']		= intval(varset($tmp[2],0));
141			}
142
143		}
144
145		// v1.x
146		if(varset($_POST['view']))
147		{
148			$this->qry['view'] 		= varset($_POST['view']) ? intval($_POST['view']) : 10;
149			$this->qry['order'] 	= varset($_POST['order']) && in_array("download_".$_POST['order'],$this->orderOptions) ? $_POST['order'] : 'datestamp';
150			$this->qry['sort'] 		= (strtolower($_POST['sort']) == 'asc') ? "asc" : 'desc';
151		}
152
153
154	}
155
156
157
158	/**
159	 * Auto-detected loading of the appropriate headers/data.
160	 */
161	public function load()
162	{
163
164		$pref = e107::getPref();
165
166
167
168		if($this->qry['action'] == 'maincats')
169		{
170		//
171		}
172
173		if($this->qry['action'] == 'list')
174		{
175			$this->loadList();
176		}
177
178		if($this->qry['action'] == 'view')
179		{
180			$this->loadView();
181		}
182
183		if ($this->qry['action'] == "report" && check_class($pref['download_reportbroken']))
184		{
185			$this->loadReport();
186		}
187
188		if($this->qry['action'] == 'mirror')
189		{
190		//
191		}
192
193		if($this->qry['action'] == 'error')
194		{
195
196		}
197
198	}
199
200
201	/**
202	 * Auto-detected Render of the appropriate download page.
203	 */
204	public function render()
205	{
206
207		$pref = e107::getPref();
208
209		if($this->qry['action'] == 'maincats')
210		{
211			return $this->renderCategories();
212		}
213
214		if($this->qry['action'] == 'list')
215		{
216			return $this->renderList();
217		}
218
219		if($this->qry['action'] == 'view')
220		{
221			return $this->renderView();
222		}
223
224		if ($this->qry['action'] == "report" && check_class($pref['download_reportbroken']))
225		{
226			return $this->renderReport();
227		}
228
229		if($this->qry['action'] == 'mirror')
230		{
231			return $this->renderMirror();
232		}
233
234		if($this->qry['action'] == 'error')
235		{
236			return $this->renderError();
237		}
238
239	}
240
241
242
243
244
245
246	/**
247	 * Render Download Categories.
248	 * @todo Cache
249	 */
250	private function renderCategories()
251	{
252		$tp = e107::getParser();
253		$ns = e107::getRender();
254		$pref = e107::getPref();
255
256
257	//	if ($cacheData = $e107cache->retrieve("download_cat".$maincatval,720)) // expires every 12 hours. //TODO make this an option
258		{
259	   //  	echo $cacheData;
260		//	return;
261		}
262
263
264
265		if(deftrue('BOOTSTRAP')) // v2.x
266		{
267			$template = e107::getTemplate('download','download','categories');
268
269			$DOWNLOAD_CAT_TABLE_START 	= varset($template['start']);
270			$DOWNLOAD_CAT_PARENT_TABLE	= $template['parent'];
271			$DOWNLOAD_CAT_CHILD_TABLE	= $template['child'];
272			$DOWNLOAD_CAT_SUBSUB_TABLE	= $template['subchild'];
273			$DOWNLOAD_CAT_TABLE_END		= varset($template['end']);
274
275//			$DL_VIEW_NEXTPREV			= varset($template['nextprev']);
276//			$DL_VIEW_PAGETITLE			= varset($template['pagetitle']);
277//			$DL_VIEW_CAPTION			= varset($template['caption'],"{DOWNLOAD_VIEW_CAPTION}");
278		}
279		else // Legacy v1.x
280		{
281			$DOWNLOAD_CAT_TABLE_START 	= null;
282			$DOWNLOAD_CAT_PARENT_TABLE	= null;
283			$DOWNLOAD_CAT_CHILD_TABLE	= null;
284			$DOWNLOAD_CAT_SUBSUB_TABLE	= null;
285			$DOWNLOAD_CAT_TABLE_END		= null;
286
287
288			$template_name = 'download_template.php';
289
290			if (is_readable(THEME."templates/".$template_name))
291			{
292				require_once(THEME."templates/".$template_name);
293			}
294			elseif (is_readable(THEME.$template_name))
295			{
296				require_once(THEME.$template_name);
297			}
298			else
299			{
300				require_once(e_PLUGIN."download/templates/".$template_name);
301			}
302		}
303
304		/** @var download_shortcodes $sc */
305		$sc = e107::getScBatch('download',true);
306		$sc->wrapper('download/categories');
307		$sc->breadcrumb();
308		$sc->qry 	= $this->qry;
309
310
311
312		if(!defined("DL_IMAGESTYLE")){ define("DL_IMAGESTYLE","border:1px solid blue");}
313
314	   // Read in tree of categories which this user is allowed to see
315		$dlcat = new downloadCategory(varset($pref['download_subsub'],1),USERCLASS_LIST,$maincatval,varset($pref['download_incinfo'],FALSE));
316
317		if ($dlcat->down_count == 0)
318	   	{
319
320			return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, "<div class='alert alert-warning' style='text-align:center'>".LAN_NO_RECORDS_FOUND."</div>",'download-categories',true);
321		}
322
323		$download_cat_table_string = "";
324		foreach($dlcat->cat_tree as $dlrow)  // Display main category headings, then sub-categories, optionally with sub-sub categories expanded
325		{
326			$sc->setVars($dlrow);
327			$download_cat_table_string .= $tp->parseTemplate($DOWNLOAD_CAT_PARENT_TABLE, TRUE, vartrue($sc));
328
329			foreach($dlrow['subcats'] as $dlsubrow)
330			{
331				$sc->dlsubrow = $dlsubrow;
332
333
334				$download_cat_table_string .= $tp->parseTemplate($DOWNLOAD_CAT_CHILD_TABLE, TRUE, $sc);
335
336				foreach($dlsubrow['subsubcats'] as $dlsubsubrow)
337				{
338					$sc->dlsubsubrow = $dlsubsubrow;
339					$download_cat_table_string .= $tp->parseTemplate($DOWNLOAD_CAT_SUBSUB_TABLE, TRUE, $sc);
340				}
341			}
342	   }
343
344	//    e107::getDebug()->log($dlcat->cat_tree);
345
346
347		$dl_text = $tp->parseTemplate($this->templateHeader, TRUE, $sc);
348		$dl_text .= $tp->parseTemplate($DOWNLOAD_CAT_TABLE_START, TRUE, $sc);
349		$dl_text .= $download_cat_table_string;
350		$dl_text .= $tp->parseTemplate($DOWNLOAD_CAT_TABLE_END, TRUE, $sc);
351
352		$caption = varset($DOWNLOAD_CAT_CAPTION) ? $tp->parseTemplate($DOWNLOAD_CAT_CAPTION, TRUE, $sc) : LAN_PLUGIN_DOWNLOAD_NAME;
353
354		//ob_start();
355
356		$dl_text .= $tp->parseTemplate($this->templateFooter, TRUE, $sc);
357
358
359
360		return $ns->tablerender($caption, $dl_text, 'download-categories',true);
361
362	  // $cache_data = ob_get_flush();
363	 //  $e107cache->set("download_cat".$maincatval, $cache_data);
364
365
366	}
367
368
369	/**
370	 * Meta for 'view' mode..to be expanded to handle list and maincats etc.
371	 * @param array $row
372	 * @todo modes for different actions based on $this->qry['action']
373	 */
374	private function setMeta($row)
375	{
376		$tp = e107::getParser();
377
378		$metaImage                      = $tp->thumbUrl($row['download_image'], array('w'=>500), null, true);
379		$metaDescription                = $tp->toHTML($row['download_description'],true);
380		$metaDescription 				= preg_replace('/\v(?:[\v\h]+)/', '', $metaDescription); // remove all line-breaks and excess whitespace
381		$metaDescription 				= $tp->text_truncate($metaDescription, 290); // + '...'
382
383		e107::meta('description',       $tp->toText($metaDescription));
384		e107::meta('keywords',          $row['download_keywords']);
385		e107::meta('og:description',    $tp->toText($metaDescription));
386		e107::meta('og:image',          $metaImage);
387		e107::meta('twitter:image:src', $metaImage);
388
389	}
390
391
392	private function loadReport()
393	{
394		$sql = e107::getDb();
395
396		$query = "
397		SELECT d.*, dc.* FROM #download AS d
398		LEFT JOIN #download_category AS dc ON d.download_category = dc.download_category_id
399		WHERE d.download_id = {$this->qry['id']}
400		  AND download_active > 0
401		LIMIT 1";
402
403		if(!$sql->gen($query))
404		{
405			return;
406		}
407
408		$this->rows = $sql->fetch();
409
410		if (isset($_POST['report_download']))
411		{
412			define("e_PAGETITLE", LAN_PLUGIN_DOWNLOAD_NAME." / ".LAN_dl_45);
413			return null;
414		}
415
416		$download_name = e107::getParser()->toDB($this->rows['download_name']);
417		define("e_PAGETITLE", LAN_PLUGIN_DOWNLOAD_NAME." / ".LAN_dl_45." / ".$download_name);
418
419	}
420
421
422
423	/**
424	 * @return null
425	 */
426	private function loadList()
427	{
428		if($dlrow = $this->getCategory($this->qry['id']))
429		{
430			define("e_PAGETITLE", LAN_PLUGIN_DOWNLOAD_NAME." / ".$dlrow['download_category_name']);
431		}
432		else
433		{  // No access to this category
434			define("e_PAGETITLE", LAN_PLUGIN_DOWNLOAD_NAME);
435		}
436
437		return null;
438	}
439
440
441	/**
442	 * @return null
443	 */
444	private function loadView()
445	{
446		if(deftrue('BOOTSTRAP')) // v2.x
447		{
448			$this->template = e107::getTemplate('download','download','view');
449		}
450		else // Legacy v1.x
451		{
452			$template_name = 'download_template.php';
453
454			$DOWNLOAD_VIEW_TABLE_START = null;
455			$DOWNLOAD_VIEW_TABLE		= null;
456			$DOWNLOAD_VIEW_TABLE_END	= null;
457			$DL_VIEW_NEXTPREV			= null;
458			$DL_VIEW_PAGETITLE			= null;
459			$DL_VIEW_CAPTION			= null;
460
461			if (is_readable(THEME."templates/".$template_name))
462			{
463				require_once(THEME."templates/".$template_name);
464			}
465			elseif (is_readable(THEME.$template_name))
466			{
467				require_once(THEME.$template_name);
468			}
469			else
470			{
471				require_once(e_PLUGIN."download/templates/".$template_name);
472			}
473
474			$this->template['start']      = $DOWNLOAD_VIEW_TABLE_START;
475			$this->template['item']       = $DOWNLOAD_VIEW_TABLE;
476			$this->template['end']        = $DOWNLOAD_VIEW_TABLE_END;
477			$this->template['nextprev']   = $DL_VIEW_NEXTPREV;
478			$this->template['pagetitle']  = $DL_VIEW_PAGETITLE;
479			$this->template['caption']    = varset($DL_VIEW_CAPTION,"{DOWNLOAD_VIEW_CAPTION}");
480
481		}
482
483		if(empty($this->template['newprev']))
484		{
485	    	$this->template['newprev'] = "
486			<div style='text-align:center'>
487				<table style='".USER_WIDTH."'>
488				<tr>
489				<td style='width:40%;'>{DOWNLOAD_VIEW_PREV}</td>
490				<td style='width:20%; text-align: center;'>{DOWNLOAD_BACK_TO_LIST}</td>
491				<td style='width:40%; text-align: right;'>{DOWNLOAD_VIEW_NEXT}</td>
492				</tr>
493				</table>
494				</div>
495				";
496	   }
497
498		if(empty($this->template['pagetitle']))
499		{
500	    	$this->template['pagetitle'] = "{DOWNLOAD_VIEW_NAME} / {DOWNLOAD_CATEGORY} / ".LAN_PLUGIN_DOWNLOAD_NAME;
501		}
502
503
504		// load data
505
506		$sql = e107::getDb();
507		$gen = new convert;
508
509		/** @var download_shortcodes $sc */
510		$sc = e107::getScBatch('download',true);
511		$sc->wrapper('download/view');
512		$sc->breadcrumb();
513		$sc->qry 	= $this->qry;
514
515		$highlight_search = FALSE;
516		if (isset($_POST['highlight_search']))
517		{
518			$highlight_search = TRUE;
519		}
520
521	    $query = "
522			SELECT d.*, dc.* FROM #download AS d
523			LEFT JOIN #download_category AS dc ON d.download_category = dc.download_category_id
524			WHERE d.download_id = {$this->qry['id']} AND d.download_active > 0
525			AND d.download_visible IN (".USERCLASS_LIST.")
526			AND dc.download_category_class IN (".USERCLASS_LIST.")
527			LIMIT 1";
528
529		if(!$sql->gen($query))
530		{
531			return null;
532		}
533
534		if(!defined("DL_IMAGESTYLE"))
535		{
536			define("DL_IMAGESTYLE","border:0px");
537		}
538
539		$dlrow = $sql->fetch();
540
541		$sc->parent = $this->getParent($dlrow['download_category_id']);
542
543		if(!empty( $sc->parent['download_category_parent']))
544		{
545			$sc->grandparent = $this->getParent( $sc->parent['download_category_id']);
546		}
547
548
549		$sc->setVars($dlrow);
550		$this->setMeta($dlrow);
551
552
553
554		$this->sc = $sc;
555		$this->rows = $dlrow;
556
557		// set Page Title;
558
559		$DL_TITLE = e107::getParser()->parseTemplate($this->template['pagetitle'], true, $sc);
560
561		define("e_PAGETITLE", $DL_TITLE);
562
563		return null;
564	}
565
566
567	/**
568	 * Render a single download
569	 * @todo cache
570	 */
571	private function renderView()
572	{
573
574		$tp = e107::getParser();
575		$ns = e107::getRender();
576		/** @var download_shortcodes $sc */
577		$sc = $this->sc;
578
579
580		// @see: #3056 fixes fatal error in case $sc is empty (what happens, if no record was found)
581		$count = empty($sc) ? 0 : $sc->getVars();
582
583		if(empty($count))
584		{
585			return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, "<div style='text-align:center'>".LAN_NO_RECORDS_FOUND."</div>", 'download-view', true);
586		}
587
588		$sc->breadcrumb();
589
590		$DL_TEMPLATE = $this->template['start'].$this->template['item'].$this->template['end'];
591
592		$text = $tp->parseTemplate($this->templateHeader, TRUE, $sc);
593		$text .= $tp->parseTemplate($DL_TEMPLATE, TRUE, $sc);
594
595
596			// ------- Next/Prev -----------
597	   	$text .= $tp->parseTemplate($this->template['nextprev'], TRUE, $sc);
598		$caption = $tp->parseTemplate($this->template['caption'], TRUE, $sc);
599
600		$text .= $tp->parseTemplate($this->templateFooter, TRUE, $sc);
601
602		$ret = $ns->tablerender($caption, $text, 'download-view', true);
603
604		unset($text);
605
606		$dlrow = $this->rows;
607
608		if ($dlrow['download_comment'])
609		{
610			$comments = e107::getComment()->compose_comment("download", "comment", $dlrow['download_id'], null, $dlrow['download_name'], FALSE, true);
611			$ret .= $ns->tablerender($comments['caption'], $comments['comment'].$comments['comment_form'], 'download-comments', true);
612		}
613
614
615
616	//	print_a($comments);
617
618		return $ret;
619
620	}
621
622
623
624
625
626
627
628
629
630
631
632	/**
633	 * Render a list of files in a particular download category.
634	 *
635	 */
636	private function renderList()
637	{
638
639		if(deftrue('BOOTSTRAP')) // v2.x
640		{
641			$template = e107::getTemplate('download','download');
642
643			$DOWNLOAD_LIST_CAPTION 		= $template['list']['caption'];
644			$DOWNLOAD_LIST_TABLE_START 	= $template['list']['start'];
645			$DOWNLOAD_LIST_TABLE 		= $template['list']['item'];
646			$DOWNLOAD_LIST_TABLE_END 	= $template['list']['end'];
647			$DOWNLOAD_LIST_NEXTPREV		= $template['list']['nextprev'];
648
649			$DOWNLOAD_CAT_TABLE_START 	= varset($template['categories']['start']);
650		//	$DOWNLOAD_CAT_PARENT_TABLE	= $template['categories']['parent'];
651		//	$DOWNLOAD_CAT_CHILD_TABLE	= $template['categories']['child'];
652			$DOWNLOAD_CAT_SUBSUB_TABLE	= $template['categories']['subchild'];
653			$DOWNLOAD_CAT_TABLE_END		= varset($template['categories']['end']);
654		}
655		else // Legacy v1.x
656		{
657			$template_name = 'download_template.php';
658
659			if (is_readable(THEME."templates/".$template_name))
660			{
661				require_once(THEME."templates/".$template_name);
662			}
663			elseif (is_readable(THEME.$template_name))
664			{
665				require_once(THEME.$template_name);
666			}
667			else
668			{
669				require_once(e_PLUGIN."download/templates/".$template_name);
670			}
671		}
672
673
674		$sql = e107::getDb('dlrow');
675		$tp = e107::getParser();
676		$ns = e107::getRender();
677		$pref = e107::getPref();
678
679
680		/** @var download_shortcodes $sc */
681		$sc = e107::getScBatch('download',true);
682		$sc->wrapper('download/list');
683
684		$sc->qry 	= $this->qry;
685
686
687
688		//if (!isset($this->qry['from'])) $this->qry['from'] = 0;
689
690	      // Get category type, page title
691	//	if ($sql->select("download_category", "download_category_name,download_category_sef,download_category_description,download_category_parent,download_category_class", "(download_category_id='{$this->qry['id']}') AND (download_category_class IN (".USERCLASS_LIST."))") )
692
693		if($dlrow = $this->getCategory($this->qry['id']))
694		{
695	   	  //  $dlrow = $sql->fetch();
696
697			$catRows = $dlrow;
698	   	   $sc->setVars($dlrow);	// Used below for header / breadcrumb.
699
700	   	   $sc->parent = $this->getParent($this->qry['id']);
701
702	   	   if(!empty( $sc->parent['download_category_parent']))
703		   {
704		        $sc->grandparent = $this->getParent( $sc->parent['download_category_id']);
705		   }
706
707			$sc->breadcrumb();
708
709	   //	   $type = $dlrow['download_category_name'];
710
711
712		   $this->qry['name'] = $dlrow['download_category_sef'];
713
714	   //	   define("e_PAGETITLE", LAN_PLUGIN_DOWNLOAD_NAME." / ".$dlrow['download_category_name']);
715		}
716		else
717		{  // No access to this category
718	   	//   define("e_PAGETITLE", LAN_PLUGIN_DOWNLOAD_NAME);
719	   	   return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, "<div class='alert alert-info' style='text-align:center'>".LAN_NO_RECORDS_FOUND."</div>",'download-list',true);
720		}
721
722		if ($dlrow['download_category_parent'] == 0)  // It's a main category - change the listing type required
723	      {
724	      //   $action = 'maincats';
725	  // 	  	 $maincatval = $id;
726		}
727
728		$dl_text = $tp->parseTemplate($this->templateHeader, TRUE, $sc);
729
730		$total_downloads = $sql->count("download", "(*)", "WHERE download_category = '{$this->qry['id']}' AND download_active > 0 AND download_visible REGEXP '" . e_CLASS_REGEXP . "'");
731
732
733		/* SHOW SUBCATS ... */
734		if($this->getChildren($this->qry['id']))
735		{
736
737			/* there are subcats - display them ... */
738			$qry = "
739			SELECT dc.*, dc2.download_category_name AS parent_name, dc2.download_category_icon as parent_icon, SUM(d.download_filesize) AS d_size,
740			COUNT(d.download_id) AS d_count,
741			MAX(d.download_datestamp) as d_last,
742			SUM(d.download_requested) as d_requests
743			FROM #download_category AS dc
744			LEFT JOIN #download AS d ON dc.download_category_id = d.download_category AND d.download_active > 0 AND d.download_visible IN (" . USERCLASS_LIST . ")
745			LEFT JOIN #download_category as dc2 ON dc2.download_category_id='{$this->qry['id']}'
746			WHERE dc.download_category_class IN (" . USERCLASS_LIST . ") AND dc.download_category_parent='{$this->qry['id']}'
747			GROUP by dc.download_category_id ORDER by dc.download_category_order
748			";
749
750			if($sql->gen($qry))
751			{
752
753				$scArray = $sql->db_getList();
754
755				$subText = "";
756
757				/** @DEPRECATED **/
758			//	if(!defined("DL_IMAGESTYLE"))
759			//	{
760			//		define("DL_IMAGESTYLE", "border:1px solid blue");
761			//	}
762
763				$download_cat_table_string = "";
764
765				if(!empty($DOWNLOAD_CAT_TABLE_PRE)) // 0.8 BC Fix.
766				{
767					$subText .= $tp->parseTemplate($DOWNLOAD_CAT_TABLE_PRE, TRUE, $sc);
768				}
769				$subText .= $tp->parseTemplate($DOWNLOAD_CAT_TABLE_START, TRUE, $sc);
770
771				foreach($scArray as $dlsubsubrow)
772				{
773					$sc->dlsubsubrow = $dlsubsubrow;
774					$sc->dlsubrow = $dlsubsubrow;
775					$subText .= $tp->parseTemplate($DOWNLOAD_CAT_SUBSUB_TABLE, TRUE, $sc);
776
777				}
778
779				$subText .= $tp->parseTemplate($DOWNLOAD_CAT_TABLE_END, TRUE, $sc);
780
781		 	 //  $dl_text .= $ns->tablerender($dl_title, $subText, 'download-list', true);
782		 	     $dl_text .=  $subText;
783			}
784
785		}// End of subcategory display
786
787		// Now display individual downloads
788		$download_category_class = 0;
789
790		if(!check_class($download_category_class))
791		{
792			$ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, "<div class='alert alert-info'>	" . LAN_NO_RECORDS_FOUND . "</div>");
793			return null;
794		}
795
796		if($total_downloads < $this->qry['view'])
797		{
798			$this->qry['from'] = 0;
799		}
800
801		if(!defined("DL_IMAGESTYLE"))
802		{
803			define("DL_IMAGESTYLE", "border:1px solid blue");
804		}
805
806		require_once (e_HANDLER . "rate_class.php");
807		$dltdownloads = 0;
808
809		// $this->qry['from'] - first entry to show  (note - can get reset due to reuse of query,
810		// even if values overridden this time)
811		// $this->qry['view'] - number of entries per page
812		// $total_downloads - total number of entries matching search criteria
813		$filetotal = $sql->select("download", "*", "download_category='{$this->qry['id']}' AND download_active > 0 AND download_visible IN (" . USERCLASS_LIST . ") ORDER BY download_{$this->qry['order']} {$this->qry['sort']} LIMIT {$this->qry['from']}, ".$this->qry['view']);
814
815
816		$caption = varset($DOWNLOAD_LIST_CAPTION) ? $tp->parseTemplate($DOWNLOAD_LIST_CAPTION, TRUE, $sc) : LAN_PLUGIN_DOWNLOAD_NAME;
817
818		if(empty($filetotal))
819		{
820
821			$dl_text .= $tp->parseTemplate($this->templateFooter, TRUE, $sc);
822			return ($dl_text) ? $ns->tablerender($caption, $dl_text, 'download-list', true) : '';
823		}
824
825
826		// Only show list if some files in it
827		$dl_text .= $tp->parseTemplate($DOWNLOAD_LIST_TABLE_START, TRUE, $sc);
828
829		global $dlft, $dltdownloads;
830
831		$dlft = ($filetotal < $this->qry['view'] ? $filetotal: $this->qry['view']);
832
833		$current_row = 1;
834
835		while($dlrow = $sql->fetch())
836		{
837				$sc->setVars($dlrow);
838
839				$agreetext = $tp->toHTML($pref['agree_text'], TRUE, 'DESCRIPTION');
840				$current_row = ($current_row) ? 0: 1;
841				// Alternating CSS for each row.(backwards compatible)
842				$template = ($current_row == 1)? $DOWNLOAD_LIST_TABLE: str_replace("forumheader3", "forumheader3 forumheader3_alt", $DOWNLOAD_LIST_TABLE);
843
844				$dltdownloads += $dlrow['download_requested'];
845
846				$dl_text .= $tp->parseTemplate($template, TRUE, $sc);
847		}
848
849		$dl_text .= $tp->parseTemplate($DOWNLOAD_LIST_TABLE_END, TRUE, $sc);
850		$dl_text .= $tp->parseTemplate($this->templateFooter, TRUE, $sc);
851
852		$text = $ns->tablerender($caption, $dl_text, 'download-list', true);
853
854
855		if(!isset($DOWNLOAD_LIST_NEXTPREV))
856		{
857			$sc_style['DOWNLOAD_LIST_NEXTPREV']['pre'] = "
858			<div class='nextprev'>
859				";
860						$sc_style['DOWNLOAD_LIST_NEXTPREV']['post'] = "
861			</div>";
862
863						$DOWNLOAD_LIST_NEXTPREV = "
864			<div style='text-align:center;margin-left:auto;margin-right:auto'>
865				{DOWNLOAD_BACK_TO_CATEGORY_LIST}
866				<br />
867				<br />
868				{DOWNLOAD_LIST_NEXTPREV}
869			</div>";
870		}
871
872
873		$nextprevQry = $this->qry;
874		$nextprevQry['from'] = '[FROM]';
875		unset($nextprevQry['id'],$nextprevQry['name'],$nextprevQry['action']);
876
877		$newUrl = e107::url('download','category',$catRows, array('query'=>$nextprevQry));
878
879		$nextprev = array(
880				'tmpl_prefix'	=>'default',
881				'total'			=> $total_downloads,
882				'amount'		=> intval($this->qry['view']),
883				'current'		=> $this->qry['from'],
884				'url'			=> urldecode($newUrl)
885		);
886
887		global $nextprev_parms;
888
889		$nextprev_parms  = http_build_query($nextprev,false,'&'); // 'tmpl_prefix='.deftrue('NEWS_NEXTPREV_TMPL', 'default').'&total='. $total_downloads.'&amount='.$amount.'&current='.$newsfrom.$nitems.'&url='.$url;
890
891		$text .= $tp->parseTemplate($DOWNLOAD_LIST_NEXTPREV, TRUE, $sc);
892
893		return $text;
894
895	}
896
897
898
899	/**
900	 * Render a 'Broken Download' Report form.
901	 */
902	private function renderReport()
903	{
904		$sql 	= e107::getDb();
905		$tp 	= e107::getParser();
906		$ns 	= e107::getRender();
907		$frm 	= e107::getForm();
908		$pref 	= e107::getPref();
909		$mes 	= e107::getMessage();
910
911		$dlrow = $this->rows;
912
913		// Check if user is allowed to make reports, and if user is allowed to view the actual download item
914		if(!check_class($dlrow['download_class']) || !check_class($pref['download_reportbroken']))
915		{
916			$mes->addError(LAN_dl_79);
917			return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, $mes->render(), 'download-report', true);
918		}
919
920		$download_name 	= $tp->toDB($dlrow['download_name']);
921		$download_sef 	= $dlrow['download_sef'];
922		$download_id 	= (int) $dlrow['download_id'];
923
924		$breadcrumb 	= array();
925		$breadcrumb[]	= array('text' => LAN_PLUGIN_DOWNLOAD_NAME,			'url' => e107::url('download','index', $dlrow));
926		$breadcrumb[]	= array('text' => $dlrow['download_category_name'],	'url' => e107::url('download','category', $dlrow));
927		$breadcrumb[]	= array('text' => $dlrow['download_name'],			'url' => e107::url('download','item', $dlrow));
928		$breadcrumb[]	= array('text' => LAN_dl_45,						'url' => null);
929
930		e107::breadcrumb($breadcrumb);
931
932		if (isset($_POST['report_download']))
933		{
934			$report_add = $tp->toDB($_POST['report_add']);
935			$user 		= USER ? USERNAME : LAN_GUEST;
936			$ip 		= e107::getIPHandler()->getIP(false);
937
938			// Replaced by e_notify
939			/*
940			if ($pref['download_email'])
941			{    // this needs to be moved into the NOTIFY, with an event.
942				require_once(e_HANDLER."mail.php");
943				$subject = LAN_dl_60." ".SITENAME;
944				$report = LAN_dl_58." ".SITENAME.":\n".(substr(SITEURL, -1) == "/" ? SITEURL : SITEURL."/")."download.php?view.".$download_id."\n
945				".LAN_dl_59." ".$user."\n".$report_add;
946				sendemail(SITEADMINEMAIL, $subject, $report);
947			}*/
948
949			$brokendownload_data = array(
950				'download_id' 	=> $download_id,
951				'download_sef'  => $download_sef,
952				'download_name' => $download_name,
953				'report_add' 	=> $report_add,
954				'user'			=> $user,
955				'ip'			=> $ip,
956			);
957
958			e107::getEvent()->trigger('user_download_brokendownload_reported', $brokendownload_data);
959
960			$sql->insert('generic', "0, 'Broken Download', ".time().",'".USERID."', '{$download_name}', {$download_id}, '{$report_add}'");
961
962
963			$text = $frm->breadcrumb($breadcrumb);
964
965			$text .= "<div class='alert alert-success'>".LAN_dl_48."</div>
966			<a class='btn btn-primary' href='".e107::url('download','item', $dlrow)."'>".LAN_dl_49."</a>";
967
968			return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, $text, 'download-report', true);
969		}
970		else
971		{
972			$text = $frm->breadcrumb($breadcrumb);
973
974
975			$formUrl = e107::url('download', 'report', $dlrow);
976			$fileUrl = e107::url('download', 'view', $dlrow);
977
978			$text .= "<form action='".$formUrl."' method='post'>
979			   <div class='form-group'>
980			   	     <p> ".LAN_DOWNLOAD.": <a href='".$fileUrl."'>".$download_name."</a></p>
981			        <p>".LAN_dl_54."<br />".LAN_dl_55."</p>
982			  </div>
983			   <div class='form-group clearfix'> ".$frm->textarea('report_add', '')."</div>
984				<div class='form-group text-center'>
985					".$frm->button('report_download',LAN_dl_45,'submit')."
986				</div>
987		   </form>";
988
989			return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, $text, 'download-report', true);
990		}
991	}
992
993
994	/**
995	 * Render Download Mirrors for the selected file.
996	 */
997	private function renderMirror()
998	{
999
1000		$sql = e107::getDb();
1001		$tp = e107::getParser();
1002		$ns = e107::getRender();
1003		$pref = e107::getPref();
1004
1005		if(deftrue('BOOTSTRAP')) // v2.x
1006		{
1007			$template = e107::getTemplate('download','download','mirror');
1008
1009			$DOWNLOAD_MIRROR_START 		= $template['start'];
1010			$DOWNLOAD_MIRROR	 		= $template['item'];
1011			$DOWNLOAD_MIRROR_END 		= $template['end'];
1012
1013		}
1014		else // Legacy v1.x
1015		{
1016			$template_name = 'download_template.php';
1017
1018			if (is_readable(THEME."templates/".$template_name))
1019			{
1020				require_once(THEME."templates/".$template_name);
1021			}
1022			elseif (is_readable(THEME.$template_name))
1023			{
1024				require_once(THEME.$template_name);
1025			}
1026			else
1027			{
1028				require_once(e_PLUGIN."download/templates/".$template_name);
1029			}
1030
1031		}
1032
1033		/** @var download_shortcodes $sc */
1034		$sc = e107::getScBatch('download',true);
1035		$sc->wrapper('download/mirror');
1036		$sc->breadcrumb();
1037		$sc->qry 	= $this->qry;
1038
1039	//	$load_template = 'download_template';
1040	//	if (!isset($DOWNLOAD_MIRROR_START)) eval($template_load_core);
1041
1042		$sql->select("download_mirror");
1043		$mirrorList = $sql->db_getList("ALL", 0, 200, "mirror_id");
1044
1045	    $query = "
1046			SELECT d.*, dc.* FROM #download AS d
1047			LEFT JOIN #download_category AS dc ON d.download_category = dc.download_category_id
1048			WHERE d.download_id = ".$this->qry['id']."
1049			LIMIT 1";
1050
1051	//	global $dlmirrorfile, $dlmirror;
1052
1053
1054		if($sql->gen($query))
1055		{
1056			$dlrow = $sql->fetch();
1057		//	$dlrow['mirrorlist'] = $mirrorList;
1058			$sc->setVars($dlrow);
1059
1060
1061			$array = explode(chr(1), $dlrow['download_mirror']);
1062
1063			if (2 == varset($pref['mirror_order']))
1064			{
1065	         // Order by name, sort array manually
1066				usort($array, "sort_download_mirror_order");
1067			}
1068	      //elseif (1 == varset($pref['mirror_order']))
1069	      //{
1070	      //   // Order by ID  - do nothing order is as stored in DB
1071	      //}
1072			elseif (0 == varset($pref['mirror_order'], 0))
1073			{
1074				   // Shuffle the mirror list into a random order
1075				   $c = count($array);
1076				   for ($i=1; $i<$c; $i++)
1077				   {
1078				     $d = mt_rand(0, $i);
1079				     $tmp = $array[$i];
1080				     $array[$i] = $array[$d];
1081				     $array[$d] = $tmp;
1082				   }
1083			}
1084
1085			$dl_text = $tp->parseTemplate($this->templateHeader, TRUE, $sc);
1086
1087		   	$dl_text .= $tp->parseTemplate($DOWNLOAD_MIRROR_START, TRUE, $sc);
1088			$download_mirror = 1;
1089
1090
1091
1092			foreach($array as $mirrorstring)
1093			{
1094				if($mirrorstring)
1095				{
1096					$dlmirrorfile = explode(",", $mirrorstring);
1097				//	$dlmirror = $mirrorList[$dlmirrorfile[0]];
1098
1099					$sc->mirror['dlmirrorfile'] = $dlmirrorfile;
1100					$sc->mirror['dlmirror'] = $mirrorList[$dlmirrorfile[0]];
1101
1102					$dl_text .= $tp->parseTemplate($DOWNLOAD_MIRROR, TRUE, $sc);
1103				}
1104			}
1105
1106			$dl_text .= $tp->parseTemplate($DOWNLOAD_MIRROR_END, TRUE, $sc);
1107
1108			$dl_text .= $tp->parseTemplate($this->templateFooter, TRUE, $sc);
1109
1110		   	return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, $dl_text, 'download-mirror', true);
1111
1112
1113		}
1114
1115
1116	}
1117
1118
1119	/**
1120	 * Render Download Errors.
1121	 */
1122	private function renderError()
1123	{
1124		$ns = e107::getRender();
1125		$pref = e107::getPref();
1126		$tp = e107::getParser();
1127
1128		$sc = e107::getScBatch('download',true);
1129
1130		$header = $tp->parseTemplate($this->templateHeader,true, $sc);
1131		$footer = $tp->parseTemplate($this->templateFooter,true, $sc);
1132
1133		switch ($this->qry['error'])
1134		{
1135			case 1 :	// No permissions
1136	            if (strlen($pref['download_denied']) > 0)
1137	            {
1138					$errmsg = $tp->toHTML($pref['download_denied'],true, 'DESCRIPTION');
1139	   	      	}
1140	   	      	else
1141	   	      	{
1142					$errmsg = LAN_dl_63;
1143				}
1144			break;
1145
1146			case 2 :	// Quota exceeded
1147				$errmsg = LAN_dl_62;
1148			break;
1149
1150			default: // Generic error - shouldn't happen
1151	   	     $errmsg = LAN_ERROR." ".$this->qry['error'];
1152		}
1153
1154		return $ns->tablerender(LAN_PLUGIN_DOWNLOAD_NAME, $header. "<div class='alert alert-error alert-danger alert-block' style='text-align:center'>".$errmsg."</div>". $footer, 'download-error', true);
1155
1156	}
1157
1158
1159
1160
1161   function getCategorySelectList($currentID=0, $incSubSub=true, $groupOnMain=true, $blankText="&nbsp;", $name="download_category")
1162   {
1163      global $sql,$parm;
1164     	$boxinfo = "\n";
1165     	$qry = "
1166        	SELECT dc.download_category_name, dc.download_category_order, dc.download_category_id, dc.download_category_parent,
1167        	dc1.download_category_parent AS d_parent1
1168        	FROM #download_category AS dc
1169        	LEFT JOIN #download_category as dc1 ON dc1.download_category_id=dc.download_category_parent AND dc1.download_category_class IN (".USERCLASS_LIST.")
1170         LEFT JOIN #download_category as dc2 ON dc2.download_category_id=dc1.download_category_parent ";
1171      if (ADMIN === FALSE) $qry .= " WHERE dc.download_category_class IN (".USERCLASS_LIST.") ";
1172      $qry .= " ORDER by dc2.download_category_order, dc1.download_category_order, dc.download_category_order";   // This puts main categories first, then sub-cats, then sub-sub cats
1173      if (!$sql->gen($qry))
1174      {
1175        	return "Error reading categories<br />";
1176        	exit;
1177      }
1178      $boxinfo .= "<select name='{$name}' id='download_category' class='tbox form-control'>
1179      	<option value=''>{$blankText}</option>\n";
1180      // Its a structured display option - need a 2-step process to create a tree
1181      $catlist = array();
1182      while ($dlrow = $sql->fetch())
1183      {
1184         $tmp = $dlrow['download_category_parent'];
1185        	if ($tmp == '0')
1186        	{
1187       	$dlrow['subcats'] = array();
1188          	$catlist[$dlrow['download_category_id']] = $dlrow;
1189        	}
1190        	else
1191        	{
1192          	if (isset($catlist[$tmp]))
1193       	   {  // Sub-Category
1194            	$catlist[$tmp]['subcats'][$dlrow['download_category_id']] = $dlrow;
1195            	$catlist[$tmp]['subcats'][$dlrow['download_category_id']]['subsubcats'] = array();
1196       	   }
1197       	   else
1198       	   {  // Its a sub-sub category
1199            	if (isset($catlist[$dlrow['d_parent1']]['subcats'][$tmp]))
1200            	{
1201             		$catlist[$dlrow['d_parent1']]['subcats'][$tmp]['subsubcats'][$dlrow['download_category_id']] = $dlrow;
1202            	}
1203       	   }
1204        	}
1205      }
1206  		// Now generate the options
1207      foreach ($catlist as $thiscat)
1208      {  // Main categories
1209         if (count($thiscat['subcats']) > 0)
1210         {
1211            if ($groupOnMain)
1212            {
1213            	$boxinfo .= "<optgroup label='".htmlspecialchars($thiscat['download_category_name'])."'>";
1214             	$scprefix = '';
1215            }
1216            else
1217            {
1218            	$boxinfo .= "<option value='".$thiscat['download_category_id']."'";
1219            	if ($currentID == $thiscat['download_category_id']) {
1220            	   $boxinfo .= " selected='selected'";
1221            	}
1222               $boxinfo .= ">".htmlspecialchars($thiscat['download_category_name'])."</option>\n";
1223             	$scprefix = '&nbsp;&nbsp;&nbsp;';
1224            }
1225            foreach ($thiscat['subcats'] as $sc)
1226            {  // Sub-categories
1227            	$sscprefix = '--> ';
1228            	$boxinfo .= "<option value='".$sc['download_category_id']."'";
1229            	if ($currentID == $sc['download_category_id']) {
1230            	   $boxinfo .= " selected='selected'";
1231            	}
1232               $boxinfo .= ">".$scprefix.htmlspecialchars($sc['download_category_name'])."</option>\n";
1233               if ($incSubSub)
1234               {  // Sub-sub categories
1235               	foreach ($sc['subsubcats'] as $ssc)
1236               	{
1237                 		$boxinfo .= "<option value='".$ssc['download_category_id']."'";
1238                 		if ($currentID == $ssc['download_category_id']) { $boxinfo .= " selected='selected'"; }
1239                 		$boxinfo .= ">".htmlspecialchars($sscprefix.$ssc['download_category_name'])."</option>\n";
1240               	}
1241               }
1242            }
1243            if ($groupOnMain)
1244            {
1245               $boxinfo .= "</optgroup>\n";
1246            }
1247         }
1248         else
1249         {
1250         	$sel = ($currentID == $thiscat['download_category_id']) ? " selected='selected'" : "";
1251           	$boxinfo .= "<option value='".$thiscat['download_category_id']."' {$sel}>".htmlspecialchars($thiscat['download_category_name'])."</option>\n";
1252         }
1253      }
1254      $boxinfo .= "</select>\n";
1255      return $boxinfo;
1256   }
1257}
1258
1259function sort_download_mirror_order($a, $b)
1260{
1261   $a = explode(",", $a);
1262   $b = explode(",", $b);
1263   if ($a[1] == $b[1]) {
1264      return 0;
1265   }
1266   return ($a[1] < $b[1]) ? -1 : 1;
1267}
1268
1269