Browse Source

Code cleanup

Alan Hardman 5 years ago
parent
commit
9e7fbf47d2

+ 0 - 4
.gitignore

@@ -1,5 +1 @@
-.idea/
 config.ini
-Thumbs.db
-lib/api/
-nbproject/

+ 0 - 1
app/controller/api/issues.php

@@ -96,7 +96,6 @@ class Issues extends \Controller\Api\Base {
 		if($_REQUEST) {
 			// By default, use standard HTTP POST fields
 			$post = $_REQUEST;
-			//$logger->write($_POST);
 		} else {
 
 

+ 13 - 27
app/controller/api/user.php

@@ -14,17 +14,15 @@ class User extends \Controller\Api\Base {
 
 		$group_id = $user->id;
 
-		 if($user->role == 'group') {
-		 	$group = new \Model\Custom("user_group");
-		 	$man = $group->find(array("group_id = ? AND manager = 1", $user->id));
-		 	$man = array_filter($man);
-
-		 	if(!empty($man) && $man[0]->user_id > 0) {
-		 		// echo $man[0]->manager;
-		 		$group_id = $man[0]->user_id;
-		 	}
-
-		 }
+		if($user->role == 'group') {
+			$group = new \Model\Custom("user_group");
+			$man = $group->find(array("group_id = ? AND manager = 1", $user->id));
+			$man = array_filter($man);
+
+			if(!empty($man) && $man[0]->user_id > 0) {
+				$group_id = $man[0]->user_id;
+			}
+		}
 
 		$result = array(
 				"id" =>$group_id,
@@ -37,11 +35,8 @@ class User extends \Controller\Api\Base {
 	}
 
 	public function single_get($f3, $params) {
-
 		$user = new \Model\User();
-		// echo $params["username"];
 		$user->load($params["username"]);
-		// echo $user->username;
 		if($user->id) {
 			print_json($this->user_array($user));
 		} else {
@@ -50,20 +45,18 @@ class User extends \Controller\Api\Base {
 	}
 
 	public function single_email($f3, $params) {
-
 		$user = new \Model\User();
 		$user->load(array("email = ? AND deleted_date IS NULL", $params["email"]));
 		if($user->id) {
- 			print_json($this->user_array($user));
- 		} else {
- 			$f3->error(404);
- 		}
+			print_json($this->user_array($user));
+		} else {
+			$f3->error(404);
+		}
 	}
 
 
 	// Gets a List of uers
 	public function get($f3, $params) {
-
 		$pagLimit = $f3->get("GET.limit") ?: 30;
 		if($pagLimit == -1) {
 			$pagLimit = 100000;
@@ -80,9 +73,7 @@ class User extends \Controller\Api\Base {
 
 		$users = array();
 		foreach ($result["subset"] as $user) {
-		 	// echo "hello";
 		 	$users[] = $this->user_array($user);
-			// 	# code...
 		}
 
 		print_json(array(
@@ -114,12 +105,9 @@ class User extends \Controller\Api\Base {
 
 		$groups = array();
 		foreach ($result["subset"] as $user) {
-		 	// echo "hello";
 		 	$groups[] = $this->user_array($user);
-			// # code...
 		}
 
-
 		print_json(array(
 				"total_count" => $result["total"],
 				"limit" => $result["limit"],
@@ -130,5 +118,3 @@ class User extends \Controller\Api\Base {
 	}
 
 }
-
-

+ 1 - 1
app/controller/files.php

@@ -120,7 +120,7 @@ class Files extends \Controller {
 
 			// Render and output image
 			header("Content-type: image/" . $params["format"]);
-			$data = $img->render($params["format"]);
+			$img->render($params["format"]);
 
 		} else {
 

File diff suppressed because it is too large
+ 833 - 859
app/controller/issues.php


+ 1 - 3
app/controller/user.php

@@ -160,7 +160,6 @@ class User extends \Controller {
 
 	public function avatar($f3, $params) {
 		$f3 = \Base::instance();
-		$post = array_map("trim", $f3->get("POST"));
 
 		$user = new \Model\User();
 		$user->load($this->_userId);
@@ -183,7 +182,7 @@ class User extends \Controller {
 		$_FILES['avatar']['name'] = $user->id . "-" . substr(sha1($user->id), 0, 4)  . "." . $parts["extension"];
 		$f3->set("avatar_filename", $_FILES['avatar']['name']);
 
-		$files = $web->receive(
+		$web->receive(
 			function($file) use($f3, $user) {
 				if($file['size'] > $f3->get("files.maxsize")) {
 					return false;
@@ -203,7 +202,6 @@ class User extends \Controller {
 		$cache->clear($f3->hash("GET /avatar/96/{$user->id}.png") . ".url");
 		$cache->clear($f3->hash("GET /avatar/128/{$user->id}.png") . ".url");
 
-
 		$f3->reroute("/user");
 	}
 

+ 288 - 291
app/functions.php

@@ -1,291 +1,288 @@
-<?php
-/**
- * Global core functions
- */
-
-/**
- * Get a Gravatar URL from email address and size, uses global Gravatar configuration
- * @param  string  $email
- * @param  integer $size
- * @return string
- */
-function gravatar($email, $size = 80) {
-	$f3 = Base::instance();
-	$rating = $f3->get("gravatar.rating") ? $f3->get("gravatar.rating") : "pg";
-	$default = $f3->get("gravatar.default") ? $f3->get("gravatar.default") : "mm";
-	return "//gravatar.com/avatar/" . md5(strtolower($email)) .
-			"?s=" . intval($size) .
-			"&d=" . urlencode($default) .
-			"&r=" . urlencode($rating);
-}
-
-/**
- * HTML escape shortcode
- * @param  string $str
- * @return string
- */
-function h($str) {
-	return htmlspecialchars($str);
-}
-
-/**
- * Get current time and date in a MySQL NOW() format
- * @param  boolean $time  Determines whether to include the time in the string
- * @param  boolean $utc   Whether to use UTC or local time
- * @return string
- */
-function now($time = true, $utc = true) {
-	$now = $utc ? time() : utc2local();
-	return $time ? date("Y-m-d H:i:s", $now) : date("Y-m-d", $now);
-}
-
-/**
- * Output object as JSON and set appropriate headers
- * @param mixed $object
- */
-function print_json($object) {
-	if(!headers_sent()) {
-		header("Content-type: application/json");
-	}
-	echo json_encode($object);
-}
-
-/**
- * Clean a string for encoding in JSON
- * Collapses whitespace, then trims
- * @param  string $string
- * @return string
- */
-function clean_json($string) {
-	return trim(preg_replace('/\s+/', ' ', $string));
-}
-
-/**
- * Internal function used by make_clickable
- * @param  array  $matches
- * @return string
- */
-function _make_url_clickable_cb($matches) {
-	$ret = '';
-	$url = $matches[2];
-
-	if(empty($url))
-		return $matches[0];
-	// removed trailing [.,;:] from URL
-	if(in_array(substr($url,-1),array('.',',',';',':')) === true) {
-		$ret = substr($url,-1);
-		$url = substr($url,0,strlen($url)-1);
-	}
-	return $matches[1] . "<a href=\"$url\" rel=\"nofollow\" target=\"_blank\">$url</a>".$ret;
-}
-
-/**
- * Internal function used by make_clickable
- * @param  array $m
- * @return string
- */
-function _make_web_ftp_clickable_cb($m) {
-	$s = '';
-	$d = $m[2];
-
-	if (empty($d))
-		return $m[0];
-
-	// removed trailing [,;:] from URL
-	if(in_array(substr($d,-1),array('.',',',';',':')) === true) {
-		$s = substr($d,-1);
-		$d = substr($d,0,strlen($d)-1);
-	}
-	return $m[1] . "<a href=\"http://$d\" rel=\"nofollow\" target=\"_blank\">$d</a>".$s;
-}
-
-/**
- * Internal function used by make_clickable
- * @param  array $m
- * @return string
- */
-function _make_email_clickable_cb($m) {
-	$email = $m[2].'@'.$m[3];
-	return $m[1]."<a href=\"mailto:$email\">$email</a>";
-}
-
-/**
- * Converts recognized URLs and email addresses into HTML hyperlinks
- * @param  string $s
- * @return string
- */
-function make_clickable($s) {
-	$s = ' '.$s;
-	// in testing, using arrays here was found to be faster
-	$s = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#!$%&~/.\-;:=,?@\[\]+]*)#is','_make_url_clickable_cb',$s);
-	$s = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#!$%&~/.\-;:=,?@\[\]+]*)#is','_make_web_ftp_clickable_cb',$s);
-	$s = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i','_make_email_clickable_cb',$s);
-
-	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
-	$s = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>",$s);
-	$s = trim($s);
-	return $s;
-}
-
-/**
- * Send an email with the UTF-8 character set
- * @param  string $to
- * @param  string $subject
- * @param  string $body
- * @return bool
- */
-function utf8mail($to, $subject, $body) {
-	$f3 = \Base::instance();
-
-	// Set content-type with UTF charset
-	$headers  = 'MIME-Version: 1.0' . "\r\n";
-	$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
-
-	// Add sender and recipient information
-	$headers .= 'To: '. $to . "\r\n";
-	$headers .= 'From: '. $f3->get("mail.from") . "\r\n";
-
-	return mail($to, $subject, $body, $headers);
-}
-
-/**
- * Takes two dates formatted as YYYY-MM-DD and creates an
- * inclusive array of the dates between the from and to dates.
- * @param  string $strDateFrom
- * @param  string $strDateTo
- * @return array
- */
-function createDateRangeArray($strDateFrom, $strDateTo) {
-	$aryRange = array();
-
-	$iDateFrom = mktime(1,0,0,substr($strDateFrom,5,2),substr($strDateFrom,8,2),substr($strDateFrom,0,4));
-	$iDateTo = mktime(1,0,0,substr($strDateTo,5,2),substr($strDateTo,8,2),substr($strDateTo,0,4));
-
-	if ($iDateTo >= $iDateFrom) {
-		$aryRange[] = date('Y-m-d', $iDateFrom); // first entry
-		while ($iDateFrom < $iDateTo) {
-			$iDateFrom += 86400; // add 24 hours
-			$aryRange[] = date('Y-m-d', $iDateFrom);
-		}
-	}
-
-	return $aryRange;
-}
-
-/**
- * Passes a string through the Textile parser,
- * also converts issue IDs and usernames to links
- * @param  string   $str
- * @param  int|bool $ttl
- * @return string
- */
-function parseTextile($str, $ttl=false) {
-	if($ttl !== false) {
-		$cache = \Cache::instance();
-		$hash = sha1($str);
-
-		// Return value if cached
-		if(($val = $cache->get("$hash.tex")) !== false) {
-			return $val;
-		}
-	}
-
-	// Value wasn't cached, run the parser
-	$tex = new \Helper\Textile\Parser();
-	$tex->setDocumentType('html5')
-		->setDimensionlessImages(true);
-	$val = $tex->parse($str);
-
-	// Find issue IDs and convert to links
-	$val = preg_replace("/(?<=[\s,\(^])#([0-9]+)(?=[\s,\)\.,$])/", "<a href=\"/issues/$1\">#$1</a>", $val);
-
-	// Find usernames and replace with links
-	// $val = preg_replace("/(?<=\s)@([a-z0-9_-]+)(?=\s)/i", " <a href=\"/user/$1\">@$1</a> ", $val);
-
-	// Convert URLs to links
-	$val = make_clickable($val);
-
-	// Cache the value if $ttl was given
-	if($ttl !== false) {
-		$cache->set("$hash.tex", $val, $ttl);
-	}
-
-	// Return the parsed value
-	return $val;
-}
-
-/**
- * Get a human-readable file size
- * @param  int $filesize
- * @return string
- */
-function format_filesize($filesize) {
-	if($filesize > 1073741824) {
-		return round($filesize / 1073741824, 2) . " GB";
-	} elseif($filesize > 1048576) {
-		return round($filesize / 1048576, 2) . " MB";
-	} elseif($filesize > 1024) {
-		return round($filesize / 1024, 2) . " KB";
-	} else {
-		return $filesize . " bytes";
-	}
-}
-
-/**
- * Convert a UTC timestamp to local time
- * @param  int $timestamp
- * @return int
- */
-function utc2local($timestamp = null) {
-	if(!$timestamp) {
-		$timestamp = time();
-	}
-
-	$f3 = Base::instance();
-
-	if($f3->exists("site.timeoffset")) {
-		$offset = $f3->get("site.timeoffset");
-	} else {
-		$tz = $f3->get("site.timezone");
-		$dtzLocal = new DateTimeZone($tz);
-		$dtLocal = new DateTime("now", $dtzLocal);
-		$offset = $dtzLocal->getOffset($dtLocal);
-	}
-
-	return $timestamp + $offset;
-}
-
-/**
- * Send a file to the browser
- * @param  string $file
- * @param  string $mime
- * @param  string $filename
- * @param  bool   $force
- * @return int|bool
- */
-function sendfile($file, $mime = "", $filename = "", $force = true) {
-	if (!is_file($file)) {
-		return FALSE;
-	}
-
-	$size = filesize($file);
-
-	if(!$mime) {
-		$mime = \Web::instance()->mime($file);
-	}
-	header("Content-Type: $mime");
-
-	if ($force) {
-		if(!$filename) {
-			$filename = basename($file);
-		}
-		header("Content-Disposition: attachment; filename=$filename");
-	}
-
-	header("Accept-Ranges: bytes");
-	header("Content-Length: $size");
-	header("X-Powered-By: " . \Base::instance()->get("PACKAGE"));
-
-	readfile($file);
-	return $size;
-}
+<?php
+/**
+ * Global core functions
+ */
+
+/**
+ * Get a Gravatar URL from email address and size, uses global Gravatar configuration
+ * @param  string  $email
+ * @param  integer $size
+ * @return string
+ */
+function gravatar($email, $size = 80) {
+	$f3 = Base::instance();
+	$rating = $f3->get("gravatar.rating") ? $f3->get("gravatar.rating") : "pg";
+	$default = $f3->get("gravatar.default") ? $f3->get("gravatar.default") : "mm";
+	return "//gravatar.com/avatar/" . md5(strtolower($email)) .
+			"?s=" . intval($size) .
+			"&d=" . urlencode($default) .
+			"&r=" . urlencode($rating);
+}
+
+/**
+ * HTML escape shortcode
+ * @param  string $str
+ * @return string
+ */
+function h($str) {
+	return htmlspecialchars($str);
+}
+
+/**
+ * Get current time and date in a MySQL NOW() format
+ * @param  boolean $time  Determines whether to include the time in the string
+ * @param  boolean $utc   Whether to use UTC or local time
+ * @return string
+ */
+function now($time = true, $utc = true) {
+	$now = $utc ? time() : utc2local();
+	return $time ? date("Y-m-d H:i:s", $now) : date("Y-m-d", $now);
+}
+
+/**
+ * Output object as JSON and set appropriate headers
+ * @param mixed $object
+ */
+function print_json($object) {
+	if(!headers_sent()) {
+		header("Content-type: application/json");
+	}
+	echo json_encode($object);
+}
+
+/**
+ * Clean a string for encoding in JSON
+ * Collapses whitespace, then trims
+ * @param  string $string
+ * @return string
+ */
+function clean_json($string) {
+	return trim(preg_replace('/\s+/', ' ', $string));
+}
+
+/**
+ * Internal function used by make_clickable
+ * @param  array  $matches
+ * @return string
+ */
+function _make_url_clickable_cb($matches) {
+	$ret = '';
+	$url = $matches[2];
+
+	if(empty($url))
+		return $matches[0];
+	// removed trailing [.,;:] from URL
+	if(in_array(substr($url,-1),array('.',',',';',':')) === true) {
+		$ret = substr($url,-1);
+		$url = substr($url,0,strlen($url)-1);
+	}
+	return $matches[1] . "<a href=\"$url\" rel=\"nofollow\" target=\"_blank\">$url</a>".$ret;
+}
+
+/**
+ * Internal function used by make_clickable
+ * @param  array $m
+ * @return string
+ */
+function _make_web_ftp_clickable_cb($m) {
+	$s = '';
+	$d = $m[2];
+
+	if (empty($d))
+		return $m[0];
+
+	// removed trailing [,;:] from URL
+	if(in_array(substr($d,-1),array('.',',',';',':')) === true) {
+		$s = substr($d,-1);
+		$d = substr($d,0,strlen($d)-1);
+	}
+	return $m[1] . "<a href=\"http://$d\" rel=\"nofollow\" target=\"_blank\">$d</a>".$s;
+}
+
+/**
+ * Internal function used by make_clickable
+ * @param  array $m
+ * @return string
+ */
+function _make_email_clickable_cb($m) {
+	$email = $m[2].'@'.$m[3];
+	return $m[1]."<a href=\"mailto:$email\">$email</a>";
+}
+
+/**
+ * Converts recognized URLs and email addresses into HTML hyperlinks
+ * @param  string $s
+ * @return string
+ */
+function make_clickable($s) {
+	$s = ' '.$s;
+	// in testing, using arrays here was found to be faster
+	$s = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#!$%&~/.\-;:=,?@\[\]+]*)#is','_make_url_clickable_cb',$s);
+	$s = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#!$%&~/.\-;:=,?@\[\]+]*)#is','_make_web_ftp_clickable_cb',$s);
+	$s = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i','_make_email_clickable_cb',$s);
+
+	// this one is not in an array because we need it to run last, for cleanup of accidental links within links
+	$s = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>",$s);
+	$s = trim($s);
+	return $s;
+}
+
+/**
+ * Send an email with the UTF-8 character set
+ * @param  string $to
+ * @param  string $subject
+ * @param  string $body
+ * @return bool
+ */
+function utf8mail($to, $subject, $body) {
+	$f3 = \Base::instance();
+
+	// Set content-type with UTF charset
+	$headers  = 'MIME-Version: 1.0' . "\r\n";
+	$headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
+
+	// Add sender and recipient information
+	$headers .= 'To: '. $to . "\r\n";
+	$headers .= 'From: '. $f3->get("mail.from") . "\r\n";
+
+	return mail($to, $subject, $body, $headers);
+}
+
+/**
+ * Takes two dates formatted as YYYY-MM-DD and creates an
+ * inclusive array of the dates between the from and to dates.
+ * @param  string $strDateFrom
+ * @param  string $strDateTo
+ * @return array
+ */
+function createDateRangeArray($strDateFrom, $strDateTo) {
+	$aryRange = array();
+
+	$iDateFrom = mktime(1,0,0,substr($strDateFrom,5,2),substr($strDateFrom,8,2),substr($strDateFrom,0,4));
+	$iDateTo = mktime(1,0,0,substr($strDateTo,5,2),substr($strDateTo,8,2),substr($strDateTo,0,4));
+
+	if ($iDateTo >= $iDateFrom) {
+		$aryRange[] = date('Y-m-d', $iDateFrom); // first entry
+		while ($iDateFrom < $iDateTo) {
+			$iDateFrom += 86400; // add 24 hours
+			$aryRange[] = date('Y-m-d', $iDateFrom);
+		}
+	}
+
+	return $aryRange;
+}
+
+/**
+ * Passes a string through the Textile parser,
+ * also converts issue IDs and usernames to links
+ * @param  string   $str
+ * @param  int|bool $ttl
+ * @return string
+ */
+function parseTextile($str, $ttl=false) {
+	if($ttl !== false) {
+		$cache = \Cache::instance();
+		$hash = sha1($str);
+
+		// Return value if cached
+		if(($val = $cache->get("$hash.tex")) !== false) {
+			return $val;
+		}
+	}
+
+	// Value wasn't cached, run the parser
+	$tex = new \Helper\Textile\Parser();
+	$tex->setDocumentType('html5')
+		->setDimensionlessImages(true);
+	$val = $tex->parse($str);
+
+	// Find issue IDs and convert to links
+	$val = preg_replace("/(?<=[\s,\(^])#([0-9]+)(?=[\s,\)\.,$])/", "<a href=\"/issues/$1\">#$1</a>", $val);
+
+	// Convert URLs to links
+	$val = make_clickable($val);
+
+	// Cache the value if $ttl was given
+	if($ttl !== false) {
+		$cache->set("$hash.tex", $val, $ttl);
+	}
+
+	// Return the parsed value
+	return $val;
+}
+
+/**
+ * Get a human-readable file size
+ * @param  int $filesize
+ * @return string
+ */
+function format_filesize($filesize) {
+	if($filesize > 1073741824) {
+		return round($filesize / 1073741824, 2) . " GB";
+	} elseif($filesize > 1048576) {
+		return round($filesize / 1048576, 2) . " MB";
+	} elseif($filesize > 1024) {
+		return round($filesize / 1024, 2) . " KB";
+	} else {
+		return $filesize . " bytes";
+	}
+}
+
+/**
+ * Convert a UTC timestamp to local time
+ * @param  int $timestamp
+ * @return int
+ */
+function utc2local($timestamp = null) {
+	if(!$timestamp) {
+		$timestamp = time();
+	}
+
+	$f3 = Base::instance();
+
+	if($f3->exists("site.timeoffset")) {
+		$offset = $f3->get("site.timeoffset");
+	} else {
+		$tz = $f3->get("site.timezone");
+		$dtzLocal = new DateTimeZone($tz);
+		$dtLocal = new DateTime("now", $dtzLocal);
+		$offset = $dtzLocal->getOffset($dtLocal);
+	}
+
+	return $timestamp + $offset;
+}
+
+/**
+ * Send a file to the browser
+ * @param  string $file
+ * @param  string $mime
+ * @param  string $filename
+ * @param  bool   $force
+ * @return int|bool
+ */
+function sendfile($file, $mime = "", $filename = "", $force = true) {
+	if (!is_file($file)) {
+		return FALSE;
+	}
+
+	$size = filesize($file);
+
+	if(!$mime) {
+		$mime = \Web::instance()->mime($file);
+	}
+	header("Content-Type: $mime");
+
+	if ($force) {
+		if(!$filename) {
+			$filename = basename($file);
+		}
+		header("Content-Disposition: attachment; filename=$filename");
+	}
+
+	header("Accept-Ranges: bytes");
+	header("Content-Length: $size");
+	header("X-Powered-By: " . \Base::instance()->get("PACKAGE"));
+
+	readfile($file);
+	return $size;
+}

+ 0 - 1
app/helper/diff.php

@@ -173,7 +173,6 @@ class Diff
 			return $this->groupedCodes;
 		}
 
-		// require_once dirname(__FILE__).'/Diff/SequenceMatcher.php';
 		$sequenceMatcher = new \Helper\Diff\Sequencematcher($this->a, $this->b, null, $this->options);
 		$this->groupedCodes = $sequenceMatcher->getGroupedOpcodes($this->options['context']);
 		return $this->groupedCodes;

+ 0 - 45
app/helper/image.php

@@ -76,51 +76,6 @@ class Image extends \Image {
 	}
 
 	/**
-	 * Render fully justified and wrapped text
-	 * @param  string  $text
-	 * @param  float   $size
-	 * @param  integer $left
-	 * @param  integer $top
-	 * @param  hex     $color
-	 * @param  string  $font
-	 * @param  integer $max_width
-	 * @return Image
-	 */
-	function textwrap($text, $size = 9.0, $left = 0, $top = 0, $color = 0x000000, $font = "opensans-regular.ttf", $max_width = 0) {
-		$f3 = \Base::instance();
-
-		$color = $this->rgb($color);
-		$color_id = imagecolorallocate($this->data, $color[0], $color[1], $color[2]);
-
-		if(!$max_width) {
-			$max_width = $this->width();
-		}
-
-		$font = "fonts/" . $font;
-		if(!is_file($font)) {
-			$f3->error(500, "Font file {$font} not found");
-			return false;
-		}
-
-		$words = explode(" ", $text);
-		$wnum = count($words);
-		$text = "";
-		foreach($words as $w) {
-			$line_width = 0;
-			$bbox = imagettfbbox($size, 0, $font, $line);
-			$word_width = $bbox[2] - $bbox[0];
-			if($line_width < $max_width) {
-				$text .= $w . " ";
-			} else {
-				$text .= PHP_EOL . $w . " ";
-			}
-		}
-
-		$this->last_data = imagettftext($this->data, $size, 0, $x, $y, $color_id, $font, $text);
-		return $this->save();
-	}
-
-	/**
 	 * Fill image with a solid color
 	 * @param  hex $color
 	 * @return Image

+ 1 - 3
app/helper/notification.php

@@ -233,9 +233,7 @@ class Notification extends \Prefab {
 	 * @return array
 	 */
 	protected function _issue_watchers($issue_id) {
-		$f3 = \Base::instance();
-		$log = new \Log("mail.log");
-		$db = $f3->get("db.instance");
+		$db = \Base::instance()->get("db.instance");
 		$recipients = array();
 
 		// Add issue author and owner

+ 3 - 27
app/model/issue.php

@@ -90,8 +90,6 @@ class Issue extends \Model {
 			}
 			$update->save();
 
-			$updated = 0;
-
 			// Set hours_total to the hours_remaining value if it's 0 or null
 			if($this->get("hours_remaining") && !$this->get("hours_total")) {
 				$this->set("hours_total", $this->get("hours_remaining"));
@@ -121,14 +119,10 @@ class Issue extends \Model {
 						$repeat_issue->due_date = date("Y-m-d", strtotime("tomorrow"));
 						break;
 					case 'weekly':
-						$dow = date("l", strtotime($this->get("due_date")));
-						$repeat_issue->due_date = date("Y-m-d", strtotime($this->get("due_date") . " +1 week" ));
+						$repeat_issue->due_date = date("Y-m-d", strtotime($this->get("due_date") . " +1 week"));
 						break;
 					case 'monthly':
-						$day = date("d", strtotime($this->get("due_date")));
-						$month = date("m");
-						$year = date("Y");
-						$repeat_issue->due_date = date("Y-m-d", mktime(0, 0, 0, $month + 1, $day, $year));
+						$repeat_issue->due_date = date("Y-m-d", strtotime($this->get("due_date") . " +1 month"));
 						break;
 					case 'sprint':
 						$sprint = new \Model\Sprint();
@@ -156,6 +150,7 @@ class Issue extends \Model {
 			$this->resetChildren();
 
 			// Log updated fields
+			$updated = 0;
 			foreach ($this->fields as $key=>$field) {
 				if ($field["changed"] && $field["value"] != $this->get_prev($key)) {
 					$update_field = new \Model\Issue\Update\Field();
@@ -204,25 +199,6 @@ class Issue extends \Model {
 	}
 
 	/**
-	 * Preload custom attributes
-	 * @param  string|array $filter
-	 * @param  array        $options
-	 * @param  integer      $ttl
-	 * @return array|FALSE
-	 */
-	function load($filter=NULL, array $options=NULL, $ttl=0) {
-		// Load issue from
-		$return = parent::load($filter, $options, $ttl);
-
-		if($this->get("id")) {
-			$attr = new \Model\Custom("attribute_value_detail");
-			$attrs = $attr->find(array("issue_id = ?", $this->get("id")));
-		}
-
-		return $return;
-	}
-
-	/**
 	 * Duplicate issue and all sub-issues
 	 * @return Issue
 	 */

+ 0 - 1
app/model/user.php

@@ -28,7 +28,6 @@ class User extends \Model {
 	 * @return string|bool
 	 */
 	public function avatar($size = 80) {
-		$f3 = \Base::instance();
 		if(!$this->get("id")) {
 			return false;
 		}

+ 6 - 4
cron/checkmail.php

@@ -6,13 +6,14 @@ $hostname = $f3->get("imap.hostname");
 $username = $f3->get("imap.username");
 $password = $f3->get("imap.password");
 
-$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to IMAP: ' . imap_last_error());
+$inbox = imap_open($hostname,$username,$password);
+if($inbox === false) {
+	die('Cannot connect to IMAP: ' . imap_last_error());
+}
 
 $emails = imap_search($inbox,'ALL UNSEEN');
 
 if($emails) {
-	// put the newest emails on top
-	// rsort($emails);
 
 	// for every email...
 	$reg_email = "/([_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))/i";
@@ -132,7 +133,8 @@ if($emails) {
 
 				/* if any attachments found... */
 				if(isset($structure->parts) && count($structure->parts)) {
-					for($i = 0; $i < count($structure->parts); $i++) {
+					$count = count($structure->parts);
+					for($i = 0; $i < $count; $i++) {
 						$attachments[$i] = array(
 							'is_attachment' => false,
 							'filename' => '',

+ 93 - 93
index.php

@@ -1,93 +1,93 @@
-<?php
-
-// Initialize core
-$f3=require("lib/base.php");
-$f3->mset(array(
-	"UI" => "app/view/",
-	"LOGS" => "log/",
-	"TEMP" => "tmp/",
-	"LOCALES" => "app/dict/",
-	"FALLBACK" => "en",
-	"CACHE" => true,
-	"AUTOLOAD" => "app/",
-	"PACKAGE" => "Phproject",
-	"microtime" => microtime(true),
-	"site.url" => $f3->get("SCHEME") . "://" . $f3->get("HOST") . $f3->get("BASE") . "/"
-));
-
-// Redirect to installer if no config file is found
-if(!is_file("config.ini")) {
-	header("Location: install.php");
-	exit();
-}
-
-// Get current Git revision
-if(is_file(".git/refs/heads/master")) {
-	$f3->set("revision", @file_get_contents(".git/refs/heads/master"));
-} else {
-	$f3->set("revision", "");
-}
-
-// Load configuration
-$f3->config("config-base.ini");
-$f3->config("config.ini");
-
-// Load routes
-$f3->config("app/routes.ini");
-
-// Set up error handling
-$f3->set("ONERROR", function($f3) {
-	switch($f3->get("ERROR.code")) {
-		case 404:
-			$f3->set("title", "Not Found");
-			$f3->set("ESCAPE", false);
-			echo Template::instance()->render("error/404.html");
-			break;
-		case 403:
-			echo "You do not have access to this page.";
-			break;
-		default:
-			if(ob_get_level()) {
-				include "app/view/error/inline.html";
-			} else {
-				include "app/view/error/500.html";
-			}
-	}
-});
-
-// Connect to database
-$f3->set("db.instance", new DB\SQL(
-	"mysql:host=" . $f3->get("db.host") . ";port=" . $f3->get("db.port") . ";dbname=" . $f3->get("db.name"),
-	$f3->get("db.user"),
-	$f3->get("db.pass")
-));
-
-// Define global core classes and functions
-require_once "app/core.php";
-require_once "app/functions.php";
-
-// Minify static resources
-// Cache for 1 week
-$f3->route("GET /minify/@type/@files", function($f3, $args) {
-	$f3->set("UI", $args["type"] . "/");
-	echo Web::instance()->minify($args["files"]);
-}, $f3->get("cache_expire.minify"));
-
-// Set up session handler
-if($f3->get("site.db_sessions")) {
-	new \DB\SQL\Session($f3->get("db.instance"), "session", false);
-}
-
-// Load user if session exists
-$user = new Model\User();
-$user->loadCurrent();
-
-// Load issue types if user is logged in
-if($f3->get("user")) {
-	$types = new \Model\Issue\Type();
-	$f3->set("issue_types", $types->find(null, null, $f3->get("cache_expire.db")));
-}
-
-// Run the application
-$f3->set("menuitem", false);
-$f3->run();
+<?php
+
+// Initialize core
+$f3=require("lib/base.php");
+$f3->mset(array(
+	"UI" => "app/view/",
+	"LOGS" => "log/",
+	"TEMP" => "tmp/",
+	"LOCALES" => "app/dict/",
+	"FALLBACK" => "en",
+	"CACHE" => true,
+	"AUTOLOAD" => "app/",
+	"PACKAGE" => "Phproject",
+	"microtime" => microtime(true),
+	"site.url" => $f3->get("SCHEME") . "://" . $f3->get("HOST") . $f3->get("BASE") . "/"
+));
+
+// Redirect to installer if no config file is found
+if(!is_file("config.ini")) {
+	header("Location: install.php");
+	exit();
+}
+
+// Get current Git revision
+if(is_file(".git/refs/heads/master")) {
+	$f3->set("revision", file_get_contents(".git/refs/heads/master"));
+} else {
+	$f3->set("revision", "");
+}
+
+// Load configuration
+$f3->config("config-base.ini");
+$f3->config("config.ini");
+
+// Load routes
+$f3->config("app/routes.ini");
+
+// Set up error handling
+$f3->set("ONERROR", function(Base $f3) {
+	switch($f3->get("ERROR.code")) {
+		case 404:
+			$f3->set("title", "Not Found");
+			$f3->set("ESCAPE", false);
+			echo Template::instance()->render("error/404.html");
+			break;
+		case 403:
+			echo "You do not have access to this page.";
+			break;
+		default:
+			if(ob_get_level()) {
+				include "app/view/error/inline.html";
+			} else {
+				include "app/view/error/500.html";
+			}
+	}
+});
+
+// Connect to database
+$f3->set("db.instance", new DB\SQL(
+	"mysql:host=" . $f3->get("db.host") . ";port=" . $f3->get("db.port") . ";dbname=" . $f3->get("db.name"),
+	$f3->get("db.user"),
+	$f3->get("db.pass")
+));
+
+// Define global core classes and functions
+require_once "app/core.php";
+require_once "app/functions.php";
+
+// Minify static resources
+// Cache for 1 week
+$f3->route("GET /minify/@type/@files", function(Base $f3, $args) {
+	$f3->set("UI", $args["type"] . "/");
+	echo Web::instance()->minify($args["files"]);
+}, $f3->get("cache_expire.minify"));
+
+// Set up session handler
+if($f3->get("site.db_sessions")) {
+	new \DB\SQL\Session($f3->get("db.instance"), "session", false);
+}
+
+// Load user if session exists
+$user = new Model\User();
+$user->loadCurrent();
+
+// Load issue types if user is logged in
+if($f3->get("user")) {
+	$types = new \Model\Issue\Type();
+	$f3->set("issue_types", $types->find(null, null, $f3->get("cache_expire.db")));
+}
+
+// Run the application
+$f3->set("menuitem", false);
+$f3->run();

+ 1 - 1
log/.gitignore

@@ -1 +1 @@
-*
+*

+ 1 - 1
tmp/.gitignore

@@ -1 +1 @@
-*
+*

+ 1 - 1
tmp/cache/.gitignore

@@ -1 +1 @@
-*
+*

+ 0 - 2
uploads/.gitignore

@@ -1,3 +1 @@
 *
-
-!.gitignore