Просмотр исходного кода

Merge pull request #747 from causefx/develop

Develop
causefx 8 лет назад
Родитель
Сommit
b39d8e7fb1
40 измененных файлов с 2209 добавлено и 391 удалено
  1. 1 0
      .gitignore
  2. 8 3
      ajax.php
  3. 1 1
      api.php
  4. 22 81
      check.php
  5. 9 6
      composer.lock
  6. 38 0
      config/configDefaults.php
  7. 1223 0
      email.php
  8. 1 1
      error.php
  9. 272 47
      functions.php
  10. 6 5
      homepage.php
  11. BIN
      images/flood.png
  12. BIN
      images/layercake.png
  13. BIN
      images/logarr.png
  14. BIN
      images/medusa.png
  15. 12 12
      index.php
  16. 2 1
      lang/en.ini
  17. 1 1
      lang/es.ini
  18. 1 1
      lang/fr.ini
  19. 1 1
      lang/it.ini
  20. 1 1
      lang/nl.ini
  21. 257 31
      settings.php
  22. 40 45
      user.php
  23. 67 64
      vendor/composer/installed.json
  24. 0 41
      vendor/guzzlehttp/guzzle/.travis.yml
  25. 21 0
      vendor/guzzlehttp/guzzle/CHANGELOG.md
  26. 10 11
      vendor/guzzlehttp/guzzle/README.md
  27. 4 1
      vendor/guzzlehttp/guzzle/composer.json
  28. 7 1
      vendor/guzzlehttp/guzzle/src/Client.php
  29. 49 0
      vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php
  30. 21 1
      vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php
  31. 13 6
      vendor/guzzlehttp/guzzle/src/Exception/RequestException.php
  32. 28 5
      vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php
  33. 17 4
      vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php
  34. 47 4
      vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php
  35. 1 1
      vendor/guzzlehttp/guzzle/src/Middleware.php
  36. 2 8
      vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php
  37. 12 6
      vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php
  38. 11 0
      vendor/guzzlehttp/guzzle/src/RequestOptions.php
  39. 1 1
      vendor/guzzlehttp/guzzle/src/RetryMiddleware.php
  40. 2 0
      vendor/guzzlehttp/guzzle/src/functions.php

+ 1 - 0
.gitignore

@@ -79,3 +79,4 @@ test*.php
 tracy/
 logs/
 debug.php
+OrganizrV2/*

+ 8 - 3
ajax.php

@@ -89,6 +89,11 @@ switch ($_SERVER['REQUEST_METHOD']) {
 				echo nzbgetConnect($_GET['list'] ? $_GET['list'] : die('Error!'));
 				die();
 				break;
+			case 'transmission-update':
+				qualifyUser(TRANSMISSIONHOMEAUTH, true);
+				echo transmissionConnect($_GET['list'] ? $_GET['list'] : die('Error!'));
+				die();
+				break;
 			case 'show-image':
 				qualifyUser(NZBGETHOMEAUTH, true);
 				header('Content-type: image/jpeg');
@@ -113,17 +118,17 @@ switch ($_SERVER['REQUEST_METHOD']) {
 			 	break;
 			case 'validate-invite':
 				$response = inviteCodes("check", $_POST['invitecode']);
-				$response['notify'] = sendResult($response, "check", $_POST['checkurl'], "CODE_SUCCESS", "CODE_ERROR");
+				$response['notify'] = sendResult($response, "check", 'Invite System', "CODE_SUCCESS", "CODE_ERROR");
 				break;
 			case 'use-invite':
 				if(inviteCodes("check", $_POST['invitecode'])){
 					$response = inviteCodes("use", $_POST['invitecode'], $_POST['inviteuser']);
-					$response['notify'] = sendResult(plexUserShare($_POST['inviteuser']), "check", $_POST['checkurl'], "INVITE_SUCCESS", "INVITE_ERROR");
+					$response['notify'] = sendResult(plexUserShare($_POST['inviteuser']), "check", 'Invite System', "INVITE_SUCCESS", "INVITE_ERROR");
 				}
 				break;
 			case 'join-plex':
 				$response = plexJoin($_POST['joinuser'], $_POST['joinemail'], $_POST['joinpassword']);
-				$response['notify'] = sendResult($response, "check", $_POST['checkurl'], "JOIN_SUCCESS", "JOIN_ERROR");
+				$response['notify'] = sendResult($response, "check", 'Invite System', "JOIN_SUCCESS", "JOIN_ERROR");
 				break;
             default: // Stuff that you need admin for
                 qualifyUser('admin', true);

+ 1 - 1
api.php

@@ -14,7 +14,7 @@ if (isset($_GET['v'])) {
 unset($_POST['a']);
 unset($_POST['k']);
 unset($_POST['v']);
-
+$result = array();
 //Check Key
 if (!isset($key)) {
     $result['error'] = "No API Key Set";

+ 22 - 81
check.php

@@ -8,95 +8,58 @@ if (file_exists('config/config.php')) {
 }
 
 function check($extension) {
-
-    if (extension_loaded($extension)) :
-        echo '<div class="col-lg-3">';
+    if (extension_loaded($extension)) {
+        echo '<div class="col-lg-2">';
         echo '<div class="panel panel-success">';
         echo '<div class="panel-heading">';
         echo '<h3 class="panel-title">'. $extension . '</h3>';
         echo '</div>';
         echo '<div style="color: gray" class="panel-body">';
-        echo $extension . ' is installed!';
+        echo 'Installed';
         echo '</div></div></div>';
-
-    else :
-        echo '<div class="col-lg-3">';
+    }else{
+        echo '<div class="col-lg-2">';
         echo '<div class="panel panel-danger">';
         echo '<div class="panel-heading">';
         echo '<h3 class="panel-title">'. $extension . '</h3>';
         echo '</div>';
         echo '<div style="color: gray" class="panel-body">';
-        echo $extension . ' is NOT loaded!  Please install it before proceeding';
-
-        if($extension == "PDO_SQLITE") :
-
-            echo '<br/> If you are on Windows, please uncomment this line in php.ini: ;extension=php_pdo_sqlite.dll<br/>If you are on Ununtu, please install php5.3-sqlite or php7-sqlite depending on your version of PHP, then restart PHP service';
-
-        endif;
-
+        echo 'Missing';
         echo '</div></div></div>';
-
-    endif;
-
+    }
 }
 
 function checkFunction($function) {
-
-    if (function_exists($function)) :
-        echo '<div class="col-lg-3">';
+    if (function_exists($function)) {
+        echo '<div class="col-lg-2">';
         echo '<div class="panel panel-success">';
         echo '<div class="panel-heading">';
         echo '<h3 class="panel-title">'. $function . '</h3>';
         echo '</div>';
         echo '<div style="color: gray" class="panel-body">';
-        echo $function . ' is installed!';
-
-        if($function == "MAIL") :
-
-            echo '<br/> **Please make sure you can send email prior to installing as this is needed for password resets**';
-
-        endif;
-
+        echo 'Installed';
         echo '</div></div></div>';
-
-    else :
-        echo '<div class="col-lg-3">';
+    }else{
+        echo '<div class="col-lg-2">';
         echo '<div class="panel panel-danger">';
         echo '<div class="panel-heading">';
         echo '<h3 class="panel-title">'. $function . '</h3>';
         echo '</div>';
         echo '<div style="color: gray" class="panel-body">';
-        echo $function . ' is NOT loaded!  Please install it before proceeding';
-
-        if($function == "MAIL") :
-
-            echo '<br/> **If you do not want to use password resets, this is okay not being installed**  EDIT LINE 31 on user.php to "false" [const use_mail = false]';
-
-        endif;
-
+        echo 'Missing';
         echo '</div></div></div>';
-
-    endif;
-
+    }
 }
 
 function getFilePermission($file) {
-
-    if (file_exists($file)) :
-
+    if (file_exists($file)) {
         $length = strlen(decoct(fileperms($file)))-3;
-
-        if($file{strlen($file)-1}=='/') :
-
+        if($file{strlen($file)-1}=='/') {
             $name = "Folder";
-
-        else :
-
+        }else{
             $name = "File";
-
-        endif;
-
-        if (is_writable($file)) :
+        }
+        if (is_writable($file)) {
             echo '<div class="col-lg-6">';
             echo '<div class="panel panel-success">';
             echo '<div class="panel-heading">';
@@ -105,7 +68,7 @@ function getFilePermission($file) {
             echo '<div style="color: gray" class="panel-body">';
             echo $file . ' is writable!';
             echo '</div></div></div>';
-        else :
+        }else{
             echo '<div class="col-lg-6">';
             echo '<div class="panel panel-danger">';
             echo '<div class="panel-heading">';
@@ -114,48 +77,32 @@ function getFilePermission($file) {
             echo '<div style="color: gray" class="panel-body">';
             echo $file . ' is NOT writable!  Please change the permissions to make it writtable by the PHP User.';
             echo '</div></div></div>';
-
-        endif;
-
-    endif;
+        }
+    }
 }
-
 ?>
 
 <!DOCTYPE html>
-
 <html lang="en" class="no-js">
-
     <head>
-
         <meta charset="UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1.0">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
         <meta name="msapplication-tap-highlight" content="no" />
-
         <title>Requirement Checker</title>
-
         <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
         <link rel="stylesheet" href="css/style.css">
         <script src="bower_components/jquery/dist/jquery.min.js"></script>
         <script src="bower_components/jquery.nicescroll/jquery.nicescroll.min.js"></script>
 		<script src="bower_components/slimScroll/jquery.slimscroll.min.js"></script>
-
     </head>
-
     <body id="body-check" class="gray-bg" style="padding: 0;">
-
         <div id="main-wrapper" class="main-wrapper">
-
             <!--Content-->
             <div id="content"  style="margin:0 20px; overflow:hidden">
-
                 <h1><center>Check Requirements & Permissions</center></h1>
-
                 <div class="row">
-
                 <?php
-
                 check("PDO_SQLITE");
                 check("PDO");
                 check("SQLITE3");
@@ -178,7 +125,6 @@ function getFilePermission($file) {
                 </div>
                 <div class="row">
                 <?php
-
                 @getFilePermission($db);
                 @getFilePermission($folder);
                 getFilePermission((__DIR__));
@@ -192,11 +138,8 @@ function getFilePermission($file) {
                 echo '<div style="color: black" class="panel-body">';
                 echo phpinfo();
                 echo '</div></div>';
-
                 ?>
-
             </div>
-
         </div>
         <script>
         $("body").niceScroll({
@@ -205,7 +148,5 @@ function getFilePermission($file) {
             mousescrollstep: 60
         });
         </script>
-
     </body>
-
 </html>

+ 9 - 6
composer.lock

@@ -57,16 +57,16 @@
         },
         {
             "name": "guzzlehttp/guzzle",
-            "version": "6.2.3",
+            "version": "6.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/guzzle/guzzle.git",
-                "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006"
+                "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006",
-                "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699",
+                "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699",
                 "shasum": ""
             },
             "require": {
@@ -76,9 +76,12 @@
             },
             "require-dev": {
                 "ext-curl": "*",
-                "phpunit/phpunit": "^4.0",
+                "phpunit/phpunit": "^4.0 || ^5.0",
                 "psr/log": "^1.0"
             },
+            "suggest": {
+                "psr/log": "Required for using the Log middleware"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -115,7 +118,7 @@
                 "rest",
                 "web service"
             ],
-            "time": "2017-02-28T22:50:30+00:00"
+            "time": "2017-06-22T18:50:49+00:00"
         },
         {
             "name": "guzzlehttp/promises",

+ 38 - 0
config/configDefaults.php

@@ -45,6 +45,10 @@ return array(
 	"nzbgetUsername" => "",
 	"nzbgetPassword" => "",
 	"nzbgetHomeAuth" => false,
+	"transmissionURL" => "",
+	"transmissionUsername" => "",
+	"transmissionPassword" => "",
+	"transmissionHomeAuth" => false,
 	"sabnzbdURL" => "",
 	"sabnzbdKey" => "",
 	"sabnzbdHomeAuth" => false,
@@ -105,6 +109,7 @@ return array(
 	"downloadRefresh" => "30000",
 	"organizrAPI" => "",
 	"splash" => "false",
+	"splashAuth" => false,
 	"chat" => "false",
 	"chatAuth" => "false",
 	"installedTheme" => "",
@@ -137,5 +142,38 @@ return array(
 	"homepageOrderombi" => '12',
 	"homepageOrdercalendar" => '13',
 	"homepageOrdernoticeguest" => '14',
+	"homepageOrdertransmisson" => '15',
 	'requestedUserOnly' => 'true',
+	'emailTemplateCSS' => '',
+	'emailTempateLogo' => 'https://raw.githubusercontent.com/causefx/Organizr/master/images/organizr-logo-h.png',
+	'emailTemplateResetPassword' => '
+	<h2>Hey there {user}!</h2><br />
+	Looks like you forgot your password.  Well, I got you...  Here is your new password: {password}<br />
+	If you want to change it once you log in, you can.  Head over to my website: {domain}<br />
+	',
+	'emailTemplateResetPasswordSubject' => 'Password Reset',
+	'emailTemplateInviteUser' => '
+	<h2>Hey there {user}!</h2><br />
+	Here is the invite code to join my cool media server: {inviteCode}<br/>
+	Head over to my website and enter the code to join: {domain}<br />
+	',
+	'emailTemplateInviteUserSubject' => 'You have been invited to join my server',
+	'emailTemplateRegisterUser' => '
+	<h2>Hey there {user}!</h2><br />
+	Welcome to me site.<br/>
+	If you need anything, please let me know.<br />
+	',
+	'emailTemplateRegisterUserSubject' => 'Thank you For Registering',
+	'emailTemplateCustomOne' => '',
+	'emailTemplateCustomOneName' => 'Template #1',
+	'emailTemplateCustomOneSubject' => '',
+	'emailTemplateCustomTwo' => '',
+	'emailTemplateCustomTwoName' => 'Template #2',
+	'emailTemplateCustomTwoSubject' => '',
+	'emailTemplateCustomThree' => '',
+	'emailTemplateCustomThreeName' => 'Template #3',
+	'emailTemplateCustomThreeSubject' => '',
+	'emailTemplateCustomFour' => '',
+	'emailTemplateCustomFourName' => 'Template #4',
+	'emailTemplateCustomFourSubject' => '',
 );

+ 1223 - 0
email.php

@@ -0,0 +1,1223 @@
+<?php
+switch ($extra) {
+    case 'invite':
+        $button = '
+        <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnButtonBlock" style="min-width:100%;">
+            <tbody class="mcnButtonBlockOuter">
+                <tr>
+                    <td style="padding-top:0; padding-right:18px; padding-bottom:18px; padding-left:18px;" valign="top" align="center" class="mcnButtonBlockInner">
+                        <table border="0" cellpadding="0" cellspacing="0" class="mcnButtonContentContainer" style="border-collapse: separate !important;border-radius: 10px;background-color: #AD80FD;">
+                            <tbody>
+                                <tr>
+                                    <td align="center" valign="middle" class="mcnButtonContent" style="font-family: Helvetica; font-size: 18px; padding: 18px;">
+                                        <a class="mcnButton " title="Button Text" href="'.getServerPath().'?inviteCode='.$email['inviteCode'].'" target="_self" style="font-weight: bold;letter-spacing: -0.5px;line-height: 100%;text-align: center;text-decoration: none;color: #FFFFFF;">Use Invite Code</a>
+                                    </td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+        ';
+        break;
+    case 'reset':
+        $button = '
+        <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnButtonBlock" style="min-width:100%;">
+            <tbody class="mcnButtonBlockOuter">
+                <tr>
+                    <td style="padding-top:0; padding-right:18px; padding-bottom:18px; padding-left:18px;" valign="top" align="center" class="mcnButtonBlockInner">
+                        <table border="0" cellpadding="0" cellspacing="0" class="mcnButtonContentContainer" style="border-collapse: separate !important;border-radius: 10px;background-color: #AD80FD;">
+                            <tbody>
+                                <tr>
+                                    <td align="center" valign="middle" class="mcnButtonContent" style="font-family: Helvetica; font-size: 18px; padding: 18px;">
+                                        <a class="mcnButton " title="Reset Password" href="'.getServerPath().'" target="_self" style="font-weight: bold;letter-spacing: -0.5px;line-height: 100%;text-align: center;text-decoration: none;color: #FFFFFF;">Goto My Site</a>
+                                    </td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+        ';
+        break;
+    default:
+        $button = null;
+        break;
+}
+
+$info = '
+<table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnBoxedTextBlock" style="min-width:100%;">
+    <!--[if gte mso 9]>
+<table align="center" border="0" cellspacing="0" cellpadding="0" width="100%">
+<![endif]-->
+    <tbody class="mcnBoxedTextBlockOuter">
+        <tr>
+            <td valign="top" class="mcnBoxedTextBlockInner">
+
+                <!--[if gte mso 9]>
+<td align="center" valign="top" ">
+<![endif]-->
+                <table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="min-width:100%;" class="mcnBoxedTextContentContainer">
+                    <tbody>
+                        <tr>
+
+                            <td style="padding-top:9px; padding-left:18px; padding-bottom:9px; padding-right:18px;">
+
+                                <table border="0" cellspacing="0" class="mcnTextContentContainer" width="100%" style="min-width: 100% !important;background-color: #F7F7F7;border: 1px none;">
+                                    <tbody>
+                                        <tr>
+                                            <td valign="top" class="mcnTextContent" style="padding: 18px;">
+                                                <h3 style="text-align:center;">'.getServerPath().'</h3>
+
+                                                <p><b>Email Sent at:</b> '.date("Y-m-d h:i").'</p>
+
+                                            </td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </td>
+                        </tr>
+                    </tbody>
+                </table>
+                <!--[if gte mso 9]>
+</td>
+<![endif]-->
+
+                <!--[if gte mso 9]>
+</tr>
+</table>
+<![endif]-->
+            </td>
+        </tr>
+    </tbody>
+</table>
+';
+
+ $email = '
+<!doctype html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
+
+<head>
+    <!-- NAME: EDUCATE -->
+    <!--[if gte mso 15]>
+		<xml>
+			<o:OfficeDocumentSettings>
+			<o:AllowPNG/>
+			<o:PixelsPerInch>96</o:PixelsPerInch>
+			</o:OfficeDocumentSettings>
+		</xml>
+		<![endif]-->
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>*EMAIL*</title>
+
+    <style type="text/css">
+        p {
+            margin: 10px 0;
+            padding: 0;
+        }
+
+        table {
+            border-collapse: collapse;
+        }
+
+        h1,
+        h2,
+        h3,
+        h4,
+        h5,
+        h6 {
+            display: block;
+            margin: 0;
+            padding: 0;
+        }
+
+        img,
+        a img {
+            border: 0;
+            height: auto;
+            outline: none;
+            text-decoration: none;
+        }
+
+        body,
+        #bodyTable,
+        #bodyCell {
+            height: 100%;
+            margin: 0;
+            padding: 0;
+            width: 100%;
+        }
+
+        .mcnPreviewText {
+            display: none !important;
+        }
+
+        #outlook a {
+            padding: 0;
+        }
+
+        img {
+            -ms-interpolation-mode: bicubic;
+        }
+
+        table {
+            mso-table-lspace: 0pt;
+            mso-table-rspace: 0pt;
+        }
+
+        .ReadMsgBody {
+            width: 100%;
+        }
+
+        .ExternalClass {
+            width: 100%;
+        }
+
+        p,
+        a,
+        li,
+        td,
+        blockquote {
+            mso-line-height-rule: exactly;
+        }
+
+        a[href^=tel],
+        a[href^=sms] {
+            color: inherit;
+            cursor: default;
+            text-decoration: none;
+        }
+
+        p,
+        a,
+        li,
+        td,
+        body,
+        table,
+        blockquote {
+            -ms-text-size-adjust: 100%;
+            -webkit-text-size-adjust: 100%;
+        }
+
+        .ExternalClass,
+        .ExternalClass p,
+        .ExternalClass td,
+        .ExternalClass div,
+        .ExternalClass span,
+        .ExternalClass font {
+            line-height: 100%;
+        }
+
+        a[x-apple-data-detectors] {
+            color: inherit !important;
+            text-decoration: none !important;
+            font-size: inherit !important;
+            font-family: inherit !important;
+            font-weight: inherit !important;
+            line-height: inherit !important;
+        }
+
+        .templateContainer {
+            max-width: 600px !important;
+        }
+
+        a.mcnButton {
+            display: block;
+        }
+
+        .mcnImage {
+            vertical-align: bottom;
+        }
+
+        .mcnTextContent {
+            word-break: break-word;
+        }
+
+        .mcnTextContent img {
+            height: auto !important;
+        }
+
+        .mcnDividerBlock {
+            table-layout: fixed !important;
+        }
+        /*
+	@tab Page
+	@section Heading 1
+	@style heading 1
+	*/
+
+        h1 {
+            /*@editable*/
+            color: #222222;
+            /*@editable*/
+            font-family: Helvetica;
+            /*@editable*/
+            font-size: 40px;
+            /*@editable*/
+            font-style: normal;
+            /*@editable*/
+            font-weight: bold;
+            /*@editable*/
+            line-height: 150%;
+            /*@editable*/
+            letter-spacing: normal;
+            /*@editable*/
+            text-align: left;
+        }
+        /*
+	@tab Page
+	@section Heading 2
+	@style heading 2
+	*/
+
+        h2 {
+            /*@editable*/
+            color: #222222;
+            /*@editable*/
+            font-family: Helvetica;
+            /*@editable*/
+            font-size: 28px;
+            /*@editable*/
+            font-style: normal;
+            /*@editable*/
+            font-weight: bold;
+            /*@editable*/
+            line-height: 150%;
+            /*@editable*/
+            letter-spacing: normal;
+            /*@editable*/
+            text-align: left;
+        }
+        /*
+	@tab Page
+	@section Heading 3
+	@style heading 3
+	*/
+
+        h3 {
+            /*@editable*/
+            color: #444444;
+            /*@editable*/
+            font-family: Helvetica;
+            /*@editable*/
+            font-size: 22px;
+            /*@editable*/
+            font-style: normal;
+            /*@editable*/
+            font-weight: bold;
+            /*@editable*/
+            line-height: 150%;
+            /*@editable*/
+            letter-spacing: normal;
+            /*@editable*/
+            text-align: left;
+        }
+        /*
+	@tab Page
+	@section Heading 4
+	@style heading 4
+	*/
+
+        h4 {
+            /*@editable*/
+            color: #999999;
+            /*@editable*/
+            font-family: Georgia;
+            /*@editable*/
+            font-size: 20px;
+            /*@editable*/
+            font-style: italic;
+            /*@editable*/
+            font-weight: normal;
+            /*@editable*/
+            line-height: 125%;
+            /*@editable*/
+            letter-spacing: normal;
+            /*@editable*/
+            text-align: left;
+        }
+        /*
+	@tab Header
+	@section Header Container Style
+	*/
+
+        #templateHeader {
+            /*@editable*/
+            background-color: #333333;
+            /*@editable*/
+            background-image: none;
+            /*@editable*/
+            background-repeat: no-repeat;
+            /*@editable*/
+            background-position: center;
+            /*@editable*/
+            background-size: cover;
+            /*@editable*/
+            border-top: 0;
+            /*@editable*/
+            border-bottom: 0;
+            /*@editable*/
+            padding-top: 10px;
+            /*@editable*/
+            padding-bottom: 10px;
+        }
+        /*
+	@tab Header
+	@section Header Interior Style
+	*/
+
+        .headerContainer {
+            /*@editable*/
+            background-color: #transparent;
+            /*@editable*/
+            background-image: none;
+            /*@editable*/
+            background-repeat: no-repeat;
+            /*@editable*/
+            background-position: center;
+            /*@editable*/
+            background-size: cover;
+            /*@editable*/
+            border-top: 0;
+            /*@editable*/
+            border-bottom: 0;
+            /*@editable*/
+            padding-top: 0;
+            /*@editable*/
+            padding-bottom: 0;
+        }
+        /*
+	@tab Header
+	@section Header Text
+	*/
+
+        .headerContainer .mcnTextContent,
+        .headerContainer .mcnTextContent p {
+            /*@editable*/
+            color: #808080;
+            /*@editable*/
+            font-family: Helvetica;
+            /*@editable*/
+            font-size: 16px;
+            /*@editable*/
+            line-height: 150%;
+            /*@editable*/
+            text-align: left;
+        }
+        /*
+	@tab Header
+	@section Header Link
+	*/
+
+        .headerContainer .mcnTextContent a,
+        .headerContainer .mcnTextContent p a {
+            /*@editable*/
+            color: #00ADD8;
+            /*@editable*/
+            font-weight: normal;
+            /*@editable*/
+            text-decoration: underline;
+        }
+        /*
+	@tab Body
+	@section Body Container Style
+	*/
+
+        #templateBody {
+            /*@editable*/
+            background-color: #ffffff;
+            /*@editable*/
+            background-image: none;
+            /*@editable*/
+            background-repeat: no-repeat;
+            /*@editable*/
+            background-position: center;
+            /*@editable*/
+            background-size: cover;
+            /*@editable*/
+            border-top: 0;
+            /*@editable*/
+            border-bottom: 0;
+            /*@editable*/
+            padding-top: 27px;
+            /*@editable*/
+            padding-bottom: 63px;
+        }
+        /*
+	@tab Body
+	@section Body Interior Style
+	*/
+
+        .bodyContainer {
+            /*@editable*/
+            background-color: #transparent;
+            /*@editable*/
+            background-image: none;
+            /*@editable*/
+            background-repeat: no-repeat;
+            /*@editable*/
+            background-position: center;
+            /*@editable*/
+            background-size: cover;
+            /*@editable*/
+            border-top: 0;
+            /*@editable*/
+            border-bottom: 0;
+            /*@editable*/
+            padding-top: 0;
+            /*@editable*/
+            padding-bottom: 0;
+        }
+        /*
+	@tab Body
+	@section Body Text
+	*/
+
+        .bodyContainer .mcnTextContent,
+        .bodyContainer .mcnTextContent p {
+            /*@editable*/
+            color: #808080;
+            /*@editable*/
+            font-family: Helvetica;
+            /*@editable*/
+            font-size: 16px;
+            /*@editable*/
+            line-height: 150%;
+            /*@editable*/
+            text-align: left;
+        }
+        /*
+	@tab Body
+	@section Body Link
+	*/
+
+        .bodyContainer .mcnTextContent a,
+        .bodyContainer .mcnTextContent p a {
+            /*@editable*/
+            color: #00ADD8;
+            /*@editable*/
+            font-weight: normal;
+            /*@editable*/
+            text-decoration: underline;
+        }
+        /*
+	@tab Footer
+	@section Footer Style
+	*/
+
+        #templateFooter {
+            /*@editable*/
+            background-color: #333333;
+            /*@editable*/
+            background-image: none;
+            /*@editable*/
+            background-repeat: no-repeat;
+            /*@editable*/
+            background-position: center;
+            /*@editable*/
+            background-size: cover;
+            /*@editable*/
+            border-top: 0;
+            /*@editable*/
+            border-bottom: 0;
+            /*@editable*/
+            padding-top: 0px;
+            /*@editable*/
+            padding-bottom: 0px;
+        }
+        /*
+	@tab Footer
+	@section Footer Interior Style
+	*/
+
+        .footerContainer {
+            /*@editable*/
+            background-color: #transparent;
+            /*@editable*/
+            background-image: none;
+            /*@editable*/
+            background-repeat: no-repeat;
+            /*@editable*/
+            background-position: center;
+            /*@editable*/
+            background-size: cover;
+            /*@editable*/
+            border-top: 0;
+            /*@editable*/
+            border-bottom: 0;
+            /*@editable*/
+            padding-top: 0;
+            /*@editable*/
+            padding-bottom: 0;
+        }
+        /*
+	@tab Footer
+	@section Footer Text
+	*/
+
+        .footerContainer .mcnTextContent,
+        .footerContainer .mcnTextContent p {
+            /*@editable*/
+            color: #FFFFFF;
+            /*@editable*/
+            font-family: Helvetica;
+            /*@editable*/
+            font-size: 12px;
+            /*@editable*/
+            line-height: 150%;
+            /*@editable*/
+            text-align: center;
+        }
+        /*
+	@tab Footer
+	@section Footer Link
+	*/
+
+        .footerContainer .mcnTextContent a,
+        .footerContainer .mcnTextContent p a {
+            /*@editable*/
+            color: #FFFFFF;
+            /*@editable*/
+            font-weight: normal;
+            /*@editable*/
+            text-decoration: underline;
+        }
+
+        @media only screen and (min-width:768px) {
+            .templateContainer {
+                width: 600px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            body,
+            table,
+            td,
+            p,
+            a,
+            li,
+            blockquote {
+                -webkit-text-size-adjust: none !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            body {
+                width: 100% !important;
+                min-width: 100% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImage {
+                width: 100% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnCartContainer,
+            .mcnCaptionTopContent,
+            .mcnRecContentContainer,
+            .mcnCaptionBottomContent,
+            .mcnTextContentContainer,
+            .mcnBoxedTextContentContainer,
+            .mcnImageGroupContentContainer,
+            .mcnCaptionLeftTextContentContainer,
+            .mcnCaptionRightTextContentContainer,
+            .mcnCaptionLeftImageContentContainer,
+            .mcnCaptionRightImageContentContainer,
+            .mcnImageCardLeftTextContentContainer,
+            .mcnImageCardRightTextContentContainer {
+                max-width: 100% !important;
+                width: 100% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnBoxedTextContentContainer {
+                min-width: 100% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImageGroupContent {
+                padding: 9px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnCaptionLeftContentOuter .mcnTextContent,
+            .mcnCaptionRightContentOuter .mcnTextContent {
+                padding-top: 9px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImageCardTopImageContent,
+            .mcnCaptionBlockInner .mcnCaptionTopContent:last-child .mcnTextContent {
+                padding-top: 18px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImageCardBottomImageContent {
+                padding-bottom: 9px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImageGroupBlockInner {
+                padding-top: 0 !important;
+                padding-bottom: 0 !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImageGroupBlockOuter {
+                padding-top: 9px !important;
+                padding-bottom: 9px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnTextContent,
+            .mcnBoxedTextContentColumn {
+                padding-right: 18px !important;
+                padding-left: 18px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcnImageCardLeftImageContent,
+            .mcnImageCardRightImageContent {
+                padding-right: 18px !important;
+                padding-bottom: 0 !important;
+                padding-left: 18px !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            .mcpreview-image-uploader {
+                display: none !important;
+                width: 100% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Heading 1
+	@tip Make the first-level headings larger in size for better readability on small screens.
+	*/
+            h1 {
+                /*@editable*/
+                font-size: 30px !important;
+                /*@editable*/
+                line-height: 125% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Heading 2
+	@tip Make the second-level headings larger in size for better readability on small screens.
+	*/
+            h2 {
+                /*@editable*/
+                font-size: 26px !important;
+                /*@editable*/
+                line-height: 125% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Heading 3
+	@tip Make the third-level headings larger in size for better readability on small screens.
+	*/
+            h3 {
+                /*@editable*/
+                font-size: 20px !important;
+                /*@editable*/
+                line-height: 150% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Heading 4
+	@tip Make the fourth-level headings larger in size for better readability on small screens.
+	*/
+            h4 {
+                /*@editable*/
+                font-size: 18px !important;
+                /*@editable*/
+                line-height: 150% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Boxed Text
+	@tip Make the boxed text larger in size for better readability on small screens. We recommend a font size of at least 16px.
+	*/
+            .mcnBoxedTextContentContainer .mcnTextContent,
+            .mcnBoxedTextContentContainer .mcnTextContent p {
+                /*@editable*/
+                font-size: 14px !important;
+                /*@editable*/
+                line-height: 150% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Header Text
+	@tip Make the header text larger in size for better readability on small screens.
+	*/
+            .headerContainer .mcnTextContent,
+            .headerContainer .mcnTextContent p {
+                /*@editable*/
+                font-size: 16px !important;
+                /*@editable*/
+                line-height: 150% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Body Text
+	@tip Make the body text larger in size for better readability on small screens. We recommend a font size of at least 16px.
+	*/
+            .bodyContainer .mcnTextContent,
+            .bodyContainer .mcnTextContent p {
+                /*@editable*/
+                font-size: 16px !important;
+                /*@editable*/
+                line-height: 150% !important;
+            }
+        }
+
+        @media only screen and (max-width: 480px) {
+            /*
+	@tab Mobile Styles
+	@section Footer Text
+	@tip Make the footer content text larger in size for better readability on small screens.
+	*/
+            .footerContainer .mcnTextContent,
+            .footerContainer .mcnTextContent p {
+                /*@editable*/
+                font-size: 14px !important;
+                /*@editable*/
+                line-height: 150% !important;
+            }
+        }
+    </style>
+</head>
+
+<body>
+    <!--*|IF:MC_PREVIEW_TEXT|*-->
+    <!--[if !gte mso 9]><!----><span class="mcnPreviewText" style="display:none; font-size:0px; line-height:0px; max-height:0px; max-width:0px; opacity:0; overflow:hidden; visibility:hidden; mso-hide:all;">*|MC_PREVIEW_TEXT|*</span>
+    <!--<![endif]-->
+    <!--*|END:IF|*-->
+    <center>
+        <table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">
+            <tr>
+                <td align="center" valign="top" id="bodyCell">
+                    <!-- BEGIN TEMPLATE // -->
+                    <table border="0" cellpadding="0" cellspacing="0" width="100%">
+                        <tr>
+                            <td align="center" valign="top" id="templateHeader" data-template-container>
+                                <!--[if (gte mso 9)|(IE)]>
+									<table align="center" border="0" cellspacing="0" cellpadding="0" width="600" style="width:600px;">
+									<tr>
+									<td align="center" valign="top" width="600" style="width:600px;">
+									<![endif]-->
+                                <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="templateContainer">
+                                    <tr>
+                                        <td valign="top" class="headerContainer">
+                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnImageBlock" style="min-width:100%;">
+                                                <tbody class="mcnImageBlockOuter">
+                                                    <tr>
+                                                        <td valign="top" style="padding:9px" class="mcnImageBlockInner">
+                                                            <table align="left" width="100%" border="0" cellpadding="0" cellspacing="0" class="mcnImageContentContainer" style="min-width:100%;">
+                                                                <tbody>
+                                                                    <tr>
+                                                                        <td class="mcnImageContent" valign="top" style="padding-right: 9px; padding-left: 9px; padding-top: 0; padding-bottom: 0; text-align:center;">
+
+                                                                            <img align="center" alt="" src="'.emailTempateLogo.'" width="564" style="max-width:700px; padding-bottom: 0; display: inline !important; vertical-align: bottom;" class="mcnImage">
+
+                                                                        </td>
+                                                                    </tr>
+                                                                </tbody>
+                                                            </table>
+                                                        </td>
+                                                    </tr>
+                                                </tbody>
+                                            </table>
+                                        </td>
+                                    </tr>
+                                </table>
+                                <!--[if (gte mso 9)|(IE)]>
+									</td>
+									</tr>
+									</table>
+									<![endif]-->
+                            </td>
+                        </tr>
+                        <tr>
+                            <td align="center" valign="top" id="templateBody" data-template-container>
+                                <!--[if (gte mso 9)|(IE)]>
+									<table align="center" border="0" cellspacing="0" cellpadding="0" width="600" style="width:600px;">
+									<tr>
+									<td align="center" valign="top" width="600" style="width:600px;">
+									<![endif]-->
+                                <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="templateContainer">
+                                    <tr>
+                                        <td valign="top" class="bodyContainer">
+                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnTextBlock" style="min-width:100%;">
+                                                <tbody class="mcnTextBlockOuter">
+                                                    <tr>
+                                                        <td valign="top" class="mcnTextBlockInner" style="padding-top:9px;">
+                                                            <!--[if mso]>
+				<table align="left" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100%;">
+				<tr>
+				<![endif]-->
+
+                                                            <!--[if mso]>
+				<td valign="top" width="600" style="width:600px;">
+				<![endif]-->
+                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" style="max-width:100%; min-width:100%;" width="100%" class="mcnTextContentContainer">
+                                                                <tbody>
+                                                                    <tr>
+
+                                                                        <td valign="top" class="mcnTextContent" style="padding-top:0; padding-right:18px; padding-bottom:9px; padding-left:18px;">
+
+                                                                            '.$body.'
+
+                                                                        </td>
+                                                                    </tr>
+                                                                </tbody>
+                                                            </table>
+                                                            <!--[if mso]>
+				</td>
+				<![endif]-->
+
+                                                            <!--[if mso]>
+				</tr>
+				</table>
+				<![endif]-->
+                                                        </td>
+                                                    </tr>
+                                                </tbody>
+                                            </table>
+
+                                            '.$button.$info.'
+                                        </td>
+                                    </tr>
+                                </table>
+                                <!--[if (gte mso 9)|(IE)]>
+									</td>
+									</tr>
+									</table>
+									<![endif]-->
+                            </td>
+                        </tr>
+                        <tr>
+                            <td align="center" valign="top" id="templateFooter" data-template-container>
+                                <!--[if (gte mso 9)|(IE)]>
+									<table align="center" border="0" cellspacing="0" cellpadding="0" width="600" style="width:600px;">
+									<tr>
+									<td align="center" valign="top" width="600" style="width:600px;">
+									<![endif]-->
+                                <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="templateContainer">
+                                    <tr>
+                                        <td valign="top" class="footerContainer">
+                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnFollowBlock" style="min-width:100%;">
+                                                <tbody class="mcnFollowBlockOuter">
+                                                    <tr>
+                                                        <td align="center" valign="top" style="padding:9px" class="mcnFollowBlockInner">
+                                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnFollowContentContainer" style="min-width:100%;">
+                                                                <tbody>
+                                                                    <tr>
+                                                                        <td align="center" style="padding-left:9px;padding-right:9px;">
+                                                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" style="min-width: 100%; border: 1px none;" class="mcnFollowContent">
+                                                                                <tbody>
+                                                                                    <tr>
+                                                                                        <td align="center" valign="top" style="padding-top:9px; padding-right:9px; padding-left:9px;">
+                                                                                            <table align="center" border="0" cellpadding="0" cellspacing="0">
+                                                                                                <tbody>
+                                                                                                    <tr>
+                                                                                                        <td align="center" valign="top">
+                                                                                                            <!--[if mso]>
+                                    <table align="center" border="0" cellspacing="0" cellpadding="0">
+                                    <tr>
+                                    <![endif]-->
+
+                                                                                                            <!--[if mso]>
+                                        <td align="center" valign="top">
+                                        <![endif]-->
+
+                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" style="display:inline;">
+                                                                                                                <tbody>
+                                                                                                                    <tr>
+                                                                                                                        <td valign="top" style="padding-right:10px; padding-bottom:9px;" class="mcnFollowContentItemContainer">
+                                                                                                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnFollowContentItem">
+                                                                                                                                <tbody>
+                                                                                                                                    <tr>
+                                                                                                                                        <td align="left" valign="middle" style="padding-top:5px; padding-right:10px; padding-bottom:5px; padding-left:9px;">
+                                                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" width="">
+                                                                                                                                                <tbody>
+                                                                                                                                                    <tr>
+
+                                                                                                                                                        <td align="center" valign="middle" width="24" class="mcnFollowIconContent">
+                                                                                                                                                            <a href="https://github.com/causefx/organizr" target="_blank"><img src="https://cdn-images.mailchimp.com/icons/social-block-v2/color-github-48.png" style="display:block;" height="24" width="24" class=""></a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                        <td align="left" valign="middle" class="mcnFollowTextContent" style="padding-left:5px;">
+                                                                                                                                                            <a href="https://github.com/causefx/organizr" target="" style="font-family: Helvetica;font-size: 12px;text-decoration: none;color: #FFFFFF;font-weight: bold;">GitHub</a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                    </tr>
+                                                                                                                                                </tbody>
+                                                                                                                                            </table>
+                                                                                                                                        </td>
+                                                                                                                                    </tr>
+                                                                                                                                </tbody>
+                                                                                                                            </table>
+                                                                                                                        </td>
+                                                                                                                    </tr>
+                                                                                                                </tbody>
+                                                                                                            </table>
+
+                                                                                                            <!--[if mso]>
+                                        </td>
+                                        <![endif]-->
+
+                                                                                                            <!--[if mso]>
+                                        <td align="center" valign="top">
+                                        <![endif]-->
+
+                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" style="display:inline;">
+                                                                                                                <tbody>
+                                                                                                                    <tr>
+                                                                                                                        <td valign="top" style="padding-right:10px; padding-bottom:9px;" class="mcnFollowContentItemContainer">
+                                                                                                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnFollowContentItem">
+                                                                                                                                <tbody>
+                                                                                                                                    <tr>
+                                                                                                                                        <td align="left" valign="middle" style="padding-top:5px; padding-right:10px; padding-bottom:5px; padding-left:9px;">
+                                                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" width="">
+                                                                                                                                                <tbody>
+                                                                                                                                                    <tr>
+
+                                                                                                                                                        <td align="center" valign="middle" width="24" class="mcnFollowIconContent">
+                                                                                                                                                            <a href="https://www.reddit.com/r/organizr" target="_blank"><img src="https://cdn-images.mailchimp.com/icons/social-block-v2/color-reddit-48.png" style="display:block;" height="24" width="24" class=""></a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                        <td align="left" valign="middle" class="mcnFollowTextContent" style="padding-left:5px;">
+                                                                                                                                                            <a href="https://www.reddit.com/r/organizr" target="" style="font-family: Helvetica;font-size: 12px;text-decoration: none;color: #FFFFFF;font-weight: bold;">Reddit</a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                    </tr>
+                                                                                                                                                </tbody>
+                                                                                                                                            </table>
+                                                                                                                                        </td>
+                                                                                                                                    </tr>
+                                                                                                                                </tbody>
+                                                                                                                            </table>
+                                                                                                                        </td>
+                                                                                                                    </tr>
+                                                                                                                </tbody>
+                                                                                                            </table>
+
+                                                                                                            <!--[if mso]>
+                                        </td>
+                                        <![endif]-->
+
+                                                                                                            <!--[if mso]>
+                                        <td align="center" valign="top">
+                                        <![endif]-->
+
+                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" style="display:inline;">
+                                                                                                                <tbody>
+                                                                                                                    <tr>
+                                                                                                                        <td valign="top" style="padding-right:10px; padding-bottom:9px;" class="mcnFollowContentItemContainer">
+                                                                                                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnFollowContentItem">
+                                                                                                                                <tbody>
+                                                                                                                                    <tr>
+                                                                                                                                        <td align="left" valign="middle" style="padding-top:5px; padding-right:10px; padding-bottom:5px; padding-left:9px;">
+                                                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" width="">
+                                                                                                                                                <tbody>
+                                                                                                                                                    <tr>
+
+                                                                                                                                                        <td align="center" valign="middle" width="24" class="mcnFollowIconContent">
+                                                                                                                                                            <a href="https://organizr.us" target="_blank"><img src="https://cdn-images.mailchimp.com/icons/social-block-v2/color-link-48.png" style="display:block;" height="24" width="24" class=""></a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                        <td align="left" valign="middle" class="mcnFollowTextContent" style="padding-left:5px;">
+                                                                                                                                                            <a href="https://organizr.us" target="" style="font-family: Helvetica;font-size: 12px;text-decoration: none;color: #FFFFFF;font-weight: bold;">Website</a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                    </tr>
+                                                                                                                                                </tbody>
+                                                                                                                                            </table>
+                                                                                                                                        </td>
+                                                                                                                                    </tr>
+                                                                                                                                </tbody>
+                                                                                                                            </table>
+                                                                                                                        </td>
+                                                                                                                    </tr>
+                                                                                                                </tbody>
+                                                                                                            </table>
+
+                                                                                                            <!--[if mso]>
+                                        </td>
+                                        <![endif]-->
+
+                                                                                                            <!--[if mso]>
+                                        <td align="center" valign="top">
+                                        <![endif]-->
+
+                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" style="display:inline;">
+                                                                                                                <tbody>
+                                                                                                                    <tr>
+                                                                                                                        <td valign="top" style="padding-right:0; padding-bottom:9px;" class="mcnFollowContentItemContainer">
+                                                                                                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnFollowContentItem">
+                                                                                                                                <tbody>
+                                                                                                                                    <tr>
+                                                                                                                                        <td align="left" valign="middle" style="padding-top:5px; padding-right:10px; padding-bottom:5px; padding-left:9px;">
+                                                                                                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" width="">
+                                                                                                                                                <tbody>
+                                                                                                                                                    <tr>
+
+                                                                                                                                                        <td align="center" valign="middle" width="24" class="mcnFollowIconContent">
+                                                                                                                                                            <a href="https://discord.gg/TrNtY7N" target="_blank"><img src="https://cdn-images.mailchimp.com/icons/social-block-v2/color-link-48.png" style="display:block;" height="24" width="24" class=""></a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                        <td align="left" valign="middle" class="mcnFollowTextContent" style="padding-left:5px;">
+                                                                                                                                                            <a href="https://discord.gg/TrNtY7N" target="" style="font-family: Helvetica;font-size: 12px;text-decoration: none;color: #FFFFFF;font-weight: bold;">Discord</a>
+                                                                                                                                                        </td>
+
+                                                                                                                                                    </tr>
+                                                                                                                                                </tbody>
+                                                                                                                                            </table>
+                                                                                                                                        </td>
+                                                                                                                                    </tr>
+                                                                                                                                </tbody>
+                                                                                                                            </table>
+                                                                                                                        </td>
+                                                                                                                    </tr>
+                                                                                                                </tbody>
+                                                                                                            </table>
+
+                                                                                                            <!--[if mso]>
+                                        </td>
+                                        <![endif]-->
+
+                                                                                                            <!--[if mso]>
+                                    </tr>
+                                    </table>
+                                    <![endif]-->
+                                                                                                        </td>
+                                                                                                    </tr>
+                                                                                                </tbody>
+                                                                                            </table>
+                                                                                        </td>
+                                                                                    </tr>
+                                                                                </tbody>
+                                                                            </table>
+                                                                        </td>
+                                                                    </tr>
+                                                                </tbody>
+                                                            </table>
+
+                                                        </td>
+                                                    </tr>
+                                                </tbody>
+                                            </table>
+                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnDividerBlock" style="min-width:100%;">
+                                                <tbody class="mcnDividerBlockOuter">
+                                                    <tr>
+                                                        <td class="mcnDividerBlockInner" style="min-width: 100%; padding: 0px 18px;">
+                                                            <table class="mcnDividerContent" border="0" cellpadding="0" cellspacing="0" width="100%" style="min-width: 100%;border-top: 2px solid #505050;">
+                                                                <tbody>
+                                                                    <tr>
+                                                                        <td>
+                                                                            <span></span>
+                                                                        </td>
+                                                                    </tr>
+                                                                </tbody>
+                                                            </table>
+                                                            <!--
+                <td class="mcnDividerBlockInner" style="padding: 18px;">
+                <hr class="mcnDividerContent" style="border-bottom-color:none; border-left-color:none; border-right-color:none; border-bottom-width:0; border-left-width:0; border-right-width:0; margin-top:0; margin-right:0; margin-bottom:0; margin-left:0;" />
+-->
+                                                        </td>
+                                                    </tr>
+                                                </tbody>
+                                            </table>
+                                            <table border="0" cellpadding="0" cellspacing="0" width="100%" class="mcnTextBlock" style="min-width:100%;">
+                                                <tbody class="mcnTextBlockOuter">
+                                                    <tr>
+                                                        <td valign="top" class="mcnTextBlockInner" style="padding-top:9px;">
+                                                            <!--[if mso]>
+				<table align="left" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100%;">
+				<tr>
+				<![endif]-->
+
+                                                            <!--[if mso]>
+				<td valign="top" width="600" style="width:600px;">
+				<![endif]-->
+                                                            <table align="left" border="0" cellpadding="0" cellspacing="0" style="max-width:100%; min-width:100%;" width="100%" class="mcnTextContentContainer">
+                                                                <tbody>
+                                                                    <tr>
+
+                                                                        <td valign="top" class="mcnTextContent" style="padding-top:0; padding-right:18px; padding-bottom:9px; padding-left:18px;">
+
+                                                                            <em>Powered By: Organizr</em>
+                                                                        </td>
+                                                                    </tr>
+                                                                </tbody>
+                                                            </table>
+                                                            <!--[if mso]>
+				</td>
+				<![endif]-->
+
+                                                            <!--[if mso]>
+				</tr>
+				</table>
+				<![endif]-->
+                                                        </td>
+                                                    </tr>
+                                                </tbody>
+                                            </table>
+                                        </td>
+                                    </tr>
+                                </table>
+                                <!--[if (gte mso 9)|(IE)]>
+									</td>
+									</tr>
+									</table>
+									<![endif]-->
+                            </td>
+                        </tr>
+                    </table>
+                    <!-- // END TEMPLATE -->
+                </td>
+            </tr>
+        </table>
+    </center>
+</body>
+
+</html>
+';

+ 1 - 1
error.php

@@ -10,7 +10,7 @@ require_once("user.php");
 $USER = new User("registration_callback");
 if(isset($_GET['error']) && $_GET['error'] !== '404'){
     $status = (isset($_GET['error'])?$_GET['error']:404);
-    setcookie('lec', $status, time() + (5), "/", DOMAIN);
+	coookie('set','lec',$status,0.00006);
     http_response_code($status);
     //get file name
     if(!empty($_SERVER['PHP_SELF'])){

+ 272 - 47
functions.php

@@ -2,7 +2,7 @@
 
 // ===================================
 // Define Version
- define('INSTALLEDVERSION', '1.61');
+ define('INSTALLEDVERSION', '1.7');
 // ===================================
 $debugOrganizr = true;
 if($debugOrganizr == true && file_exists('debug.php')){ require_once('debug.php'); }
@@ -25,6 +25,7 @@ function homepageOrder(){
 		"homepageOrderombi" => homepageOrderombi,
 		"homepageOrdercalendar" => homepageOrdercalendar,
 		"homepageOrdernoticeguest" => homepageOrdernoticeguest,
+		"homepageOrdertransmisson" => homepageOrdertransmisson,
 	);
 	asort($homepageOrder);
 	return $homepageOrder;
@@ -268,8 +269,7 @@ if (function_exists('curl_version')) :
 		// Quick out
 		$isAdmin = false;
 		if ((strtolower(PLEXUSERNAME) == strtolower($username)) && $password == PLEXPASSWORD) {
-   			writeLog("success", "Admin: ".$username." authenticated by plex");
-			//return true;
+   			writeLog("success", "Admin: ".$username." authenticated as plex Admin");
 			$isAdmin = true;
 		}
 
@@ -285,7 +285,7 @@ if (function_exists('curl_version')) :
 			$isUser = false;
 			$usernameLower = strtolower($username);
 			foreach($userXML AS $child) {
-				if(isset($child['username']) && strtolower($child['username']) == $usernameLower) {
+				if(isset($child['username']) && strtolower($child['username']) == $usernameLower || isset($child['email']) && strtolower($child['email']) == $usernameLower) {
 					$isUser = true;
      				writeLog("success", $usernameLower." was found in plex friends list");
 					break;
@@ -309,14 +309,17 @@ if (function_exists('curl_version')) :
 				$result = curl_post($connectURL, $body, $headers);
 				if (isset($result['content'])) {
 					$json = json_decode($result['content'], true);
-					if (is_array($json) && isset($json['user']) && isset($json['user']['username']) && strtolower($json['user']['username']) == $usernameLower) {
+					if ((is_array($json) && isset($json['user']) && isset($json['user']['username'])) && strtolower($json['user']['username']) == $usernameLower || strtolower($json['user']['email']) == $usernameLower) {
 						writeLog("success", $json['user']['username']." was logged into organizr using plex credentials");
                         return array(
 							'email' => $json['user']['email'],
 							'image' => $json['user']['thumb'],
-							'token' => $json['user']['authToken']
+							'token' => $json['user']['authToken'],
+							'type' => $isAdmin ? 'admin' : 'user',
 						);
 					}
+				}else{
+					writeLog("error", "error occured while trying to sign $username into plex");
 				}
 			}else{
 				writeLog("error", "$username is not an authorized PLEX user or entered invalid password");
@@ -939,8 +942,8 @@ function resolvePlexItem($server, $token, $item, $nowPlaying = false, $showNames
             }else {
                 $height = 281;
                 $width = 500;
-				$thumb = ($item['art']) ? $item['art'] :  $item['parentThumb'];
-				$widthOverride = ($item['art']) ? 100 :  56;
+				$thumb = ($item['parentThumb']) ? $item['parentThumb'] :  $item['art'];
+				$widthOverride = ($item['parentThumb']) ? 56 :  100;
                 $key = $item['ratingKey'] . "-np";
                 $elapsed = $item['viewOffset'];
                 $duration = ($item['duration']) ? $item['duration'] : $item->Media['duration'];
@@ -1018,7 +1021,9 @@ function resolvePlexItem($server, $token, $item, $nowPlaying = false, $showNames
 	$openTab = (PLEXTABNAME) ? "true" : "false";
     // Assemble Item And Cache Into Array
     if($nowPlaying){
-        return '<div class="col-sm-6 col-md-3"><div class="thumbnail ultra-widget"><div style="display: none;" np="'.$id.'" class="overlay content-box small-box gray-bg">'.$streamInfo.'</div><span class="refreshNP w-refresh w-p-icon gray" link="'.$id.'"><span class="fa-stack fa-lg" style="font-size: .5em"><i class="fa fa-square fa-stack-2x"></i><i class="fa fa-info-circle fa-stack-1x fa-inverse"></i></span></span><div class="ultra-widget refreshImage"><span class="w-refresh w-p-icon gray"><span class="fa-stack fa-lg" style="font-size: .4em"><i class="fa fa-square fa-stack-2x"></i><i class="fa fa-refresh fa-stack-1x fa-inverse"></i></span></span></div><a class="openTab" extraTitle="'.$title.'" extraType="'.$item['type'].'" openTab="'.$openTab.'" href="'.$address.'" target="_blank"><img class="refreshImageSource" style="width: '.$widthOverride.'%; display:block;" src="'.$image_url.'" original-image="'.$original_image_url.'" alt="'.$item['Name'].'"></a><div class="progress progress-bar-sm zero-m"><div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="'.$watched.'" aria-valuemin="0" aria-valuemax="100" style="width: '.$watched.'%"></div><div class="progress-bar palette-Grey-500 bg" style="width: '.$transcoded.'%"></div></div><div class="caption"><i style="float:left" class="fa fa-'.$state.'"></i>'.$topTitle.''.$bottomTitle.'</div></div></div>';
+		$musicOverlay = ($widthOverride == 56) ? '<img class="" style="width: 55%;display:block;position: absolute;top: 4px;left:5px;overflow: hidden;filter: blur(0px) grayscale(1);" src="'.$image_url.'">
+		<img class="" style="width: 55%;display:block;position: absolute;top: 4px;right:5px;overflow: hidden;filter: blur(0px) grayscale(1);" src="'.$image_url.'">' : '';
+        return '<div class="col-sm-6 col-md-3"><div class="thumbnail ultra-widget"><div style="display: none;" np="'.$id.'" class="overlay content-box small-box gray-bg">'.$streamInfo.'</div><span class="refreshNP w-refresh w-p-icon gray" link="'.$id.'"><span class="fa-stack fa-lg" style="font-size: .5em"><i class="fa fa-square fa-stack-2x"></i><i class="fa fa-info-circle fa-stack-1x fa-inverse"></i></span></span><div class="ultra-widget refreshImage"><span class="w-refresh w-p-icon gray"><span class="fa-stack fa-lg" style="font-size: .4em"><i class="fa fa-square fa-stack-2x"></i><i class="fa fa-refresh fa-stack-1x fa-inverse"></i></span></span></div><a class="openTab" extraTitle="'.$title.'" extraType="'.$item['type'].'" openTab="'.$openTab.'" href="'.$address.'" target="_blank">'.$musicOverlay.'<img class="refreshImageSource" style="width: '.$widthOverride.'%; display:block; position: relative" src="'.$image_url.'" original-image="'.$original_image_url.'" alt="'.$item['Name'].'"></a><div class="progress progress-bar-sm zero-m"><div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="'.$watched.'" aria-valuemin="0" aria-valuemax="100" style="width: '.$watched.'%"></div><div class="progress-bar palette-Grey-500 bg" style="width: '.$transcoded.'%"></div></div><div class="caption"><i style="float:left" class="fa fa-'.$state.'"></i>'.$topTitle.''.$bottomTitle.'</div></div></div>';
     }else{
         return '<div class="item-'.$item['type'].$playlist.'"><div style="" class="ultra-widget refreshImage"><span class="w-refresh w-p-icon gray"><span class="fa-stack fa-lg" style="font-size: .4em"><i class="fa fa-square fa-stack-2x"></i><i class="fa fa-refresh fa-stack-1x fa-inverse"></i></span></span></div><a class="openTab" extraTitle="'.$title.'" extraType="'.$item['type'].'" openTab="'.$openTab.'" href="'.$address.'" target="_blank"><img alt="'.$item['Name'].'" class="'.$image.' refreshImageSource" data-lazy="'.$image_url.'" original-image="'.$original_image_url.'"></a><small class="elip slick-bottom-title">'.$title.'</small></div>';
     }
@@ -1043,7 +1048,7 @@ function outputRecentAdded($header, $items, $script = false, $array, $type) {
         return '<div id="recentMedia'.$type.'" class="content-box box-shadow big-box"><h5 class="text-center">'.$header.'</h5><p class="text-center">No Media Found</p></div>';
     }else{
 		$className = str_replace(' ', '', $header.' on '.$type);
-        return '<div id="recentMedia'.$type.'" class="content-box box-shadow big-box"><h5 id="recentContent-title-'.$type.'" style="margin-bottom: -20px" class="text-center">'.$header.'</h5><div class="recentHeader inbox-pagination '.$className.'">'.$hideMenu.'</div><br/><br/><div class="recentItems-recent-'.$type.'" data-name="'.$className.'">'.implode('',$items).'</div></div>'.($script?'<script>'.$script.'</script>':'');
+        return '<div id="recentMedia'.$type.'" class="content-box box-shadow big-box"><h5 id="recentContent-title-'.$type.'" style="margin-bottom: -20px" class="text-center"><span>'.$header.'</span></h5><div class="recentHeader inbox-pagination '.$className.'">'.$hideMenu.'</div><br/><br/><div class="recentItems-recent-'.$type.'" data-name="'.$className.'">'.implode('',$items).'</div></div>'.($script?'<script>'.$script.'</script>':'');
     }
 
 }
@@ -1974,7 +1979,7 @@ function buildField($params, $sizeSm = 12, $sizeMd = 12, $sizeLg = 12) {
 
 	// Tags
 	$tags = array();
-	foreach(array('placeholder','style','disabled','readonly','pattern','min','max','required','onkeypress','onchange','onfocus','onleave','href','onclick') as $value) {
+	foreach(array('placeholder','style','disabled','readonly','pattern','min','max','required','onkeypress','onchange','onfocus','onleave','href','onclick','autocomplete') as $value) {
 		if (isset($params[$value])) {
 			if (is_string($params[$value])) { $tags[] = $value.'="'.$params[$value].'"';
 			} else if ($params[$value] === true) { $tags[] = $value; }
@@ -2625,6 +2630,92 @@ function upgradeInstall($branch = 'master') {
 	writeLog("success", "organizr has been updated");
 	return true;
 }
+// Transmission Items
+function transmissionConnect($list = 'listgroups') {
+    $url = qualifyURL(TRANSMISSIONURL);
+	$digest = parse_url($url);
+	$scheme = (isset($digest['scheme'])) ? $digest['scheme'].'://' : 'http://';
+	$host = (isset($digest['host'])) ? $digest['host'] : '';
+	$port = (isset($digest['port'])) ? ':'.$digest['port'] : '';
+	$path = (isset($digest['path'])) ? $digest['path'] : '';
+	$passwordInclude = (TRANSMISSIONUSERNAME != '' && TRANSMISSIONPASSWORD != '') ? TRANSMISSIONUSERNAME.':'.TRANSMISSIONPASSWORD."@" : '';
+	$url = $scheme.$passwordInclude.$host.$port.$path.'/rpc';
+	$contextopts = array(
+		'http' => array(
+			'user_agent'  => 'HTTP_UA',
+			'ignore_errors' => true,
+		)
+	);
+	$context  = stream_context_create( $contextopts );
+	$fp = @fopen( $url, 'r', false, $context );
+	$stream_meta = stream_get_meta_data( $fp );
+    fclose( $fp );
+	foreach( $stream_meta['wrapper_data'] as $header ){
+		if( strpos( $header, 'X-Transmission-Session-Id: ' ) === 0 ){
+			$session_id = trim( substr( $header, 27 ) );
+			break;
+		}
+	}
+
+	$headers = array(
+		'X-Transmission-Session-Id' => $session_id,
+		'Content-Type' => 'application/json'
+	);
+	$data = array(
+		'method' => 'torrent-get',
+		'arguments' => array(
+			'fields' => array(
+				"id", "name", "totalSize", "eta", "isFinished", "isStalled", "percentDone", "rateDownload", "status", "downloadDir"
+			),
+		),
+		'tags' => ''
+	);
+    $api = curl_post($url, $data, $headers);
+    $api = json_decode($api['content'], true);
+    $gotTorrent = array();
+    if (is_array($api) || is_object($api)){
+		foreach ($api['arguments']['torrents'] AS $child) {
+			$downloadName = htmlentities($child['name'], ENT_QUOTES);
+			$downloadDirectory = $child['downloadDir'];
+			$downloadPercent = $child['percentDone'] * 100;
+			$progressBar = "progress-bar-striped active";
+			if($child['status'] == "6"){
+				$downloadStatus = "Seeding";
+				$downloadHealth = "success";
+			}elseif($child['status'] == "4"){
+				$downloadStatus = "Downloading";
+				$downloadHealth = "danger";
+			}elseif($child['status'] == "3"){
+				$downloadStatus = "Queued";
+				$downloadHealth = "warning";
+			}elseif($child['status'] == "0"){
+				$downloadStatus = "Complete";
+				$downloadHealth = "success";
+			}
+			$gotTorrent[] = '<tr>
+							<td class="col-xs-6 nzbtable-file-row">'.$downloadName.'</td>
+							<td class="col-xs-2 nzbtable nzbtable-row">'.$downloadStatus.'</td>
+							<td class="col-xs-1 nzbtable nzbtable-row">'.$downloadDirectory.'</td>
+							<td class="col-xs-1 nzbtable nzbtable-row">'.realSize($child['totalSize']).'</td>
+							<td class="col-xs-2 nzbtable nzbtable-row">
+								<div class="progress">
+									<div class="progress-bar progress-bar-'.$downloadHealth.' '.$progressBar.'" role="progressbar" aria-valuenow="'.$downloadPercent.'" aria-valuemin="0" aria-valuemax="100" style="width: '.$downloadPercent.'%">
+										<p class="text-center">'.round($downloadPercent).'%</p>
+										<span class="sr-only">'.$downloadPercent.'% Complete</span>
+									</div>
+								</div>
+							</td>
+						</tr>';
+		}
+		if ($gotTorrent) {
+			return implode('',$gotTorrent);
+		} else {
+			return '<tr><td colspan="5"><p class="text-center">No Results</p></td></tr>';
+		}
+	}else{
+		writeLog("error", "TRANSMISSION ERROR: could not connect - check URL and/or check token and/or Username and Password - if HTTPS, is cert valid");
+	}
+}
 
 // NzbGET Items
 function nzbgetConnect($list = 'listgroups') {
@@ -3393,11 +3484,9 @@ function getServer(){
     return $server;
 }
 
-function prettyPrint($array) {
-    echo "<pre>";
-    print_r($array);
-    echo "</pre>";
-    echo "<br/>";
+function prettyPrint($v) {
+	$trace = debug_backtrace()[0];
+	echo '<pre style="white-space: pre; text-overflow: ellipsis; overflow: hidden; background-color: #f2f2f2; border: 2px solid black; border-radius: 5px; padding: 5px; margin: 5px;">'.$trace['file'].':'.$trace['line'].' '.gettype($v)."\n\n".print_r($v, 1).'</pre><br/>';
 }
 
 function checkFrame($array, $url){
@@ -3915,7 +4004,18 @@ function inviteCodes($action, $code = null, $usedBy = null) {
 					require_once("user.php");
 					$GLOBALS['USER'] = new User('registration_callback');
 				}
-				sendEmail($GLOBALS['USER']->adminEmail, "Admin", "Plex Invite Used", orgEmail("PLEX Invite Used", "Look who joined the cool club", "Admin", "Hey, The User: $usedBy has redeemd their invite code: [$code], their IP Address was: $currentIP", null, null, "What Next?", "Well, That is up to you.  You can go check on them if you like."));
+				$emailTemplate = array(
+					'type' => 'mass',
+					'body' => 'The user: {user} has reddemed the code: {inviteCode} his IP Address was '.$currentIP,
+					'subject' => 'Invite Code '.$code.' Has Been Used',
+					'user' => $usedBy,
+					'password' => null,
+					'inviteCode' => $code,
+				);
+				$emailTemplate = emailTemplate($emailTemplate);
+				$subject = $emailTemplate['subject'];
+				$body = buildEmail($emailTemplate);
+				sendEmail($GLOBALS['USER']->adminEmail, "Admin", $subject, $body);
 			}
 			return (!empty($invites) ? true : false );
 			break;
@@ -4742,8 +4842,7 @@ function buildMenu($array){
 }
 
 function requestInvite($email, $username){
-	//sendEmail($email, $username = "Organizr User", $subject, $body, $cc = null){
-	//orgEmail($header = "Message From Admin", $title = "Important Message", $user = "Organizr User", $mainMessage = "", $button = null, $buttonURL = null, $subTitle = "", $subMessage = ""){
+	//sendEmail($email, $username = "Organizr User", $subject, $body, $cc = null, $bcc = null)
 	sendEmail($GLOBALS['USER']->adminEmail, "Admin", "Plex Invite Request", orgEmail("PLEX Invite Request", "Look who wants to join the cool club", "Admin", "Hey, The User: $user has requested access to your Plex Library.", "Generate Invite", null, "What Next?", "Well, That is up to you.  You can go check on them if you like."));
 
 }
@@ -4765,9 +4864,13 @@ function ajaxLoop($ajaxFunction, $refresh, $extraFunction = ''){
 				var getDiv = response;
 				var loadedID = 	$(getDiv).attr('id');
 				if (typeof loadedID !== 'undefined') {
-					$('#'+loadedID).replaceWith($(getDiv).prop('outerHTML'));
-					".$extraFunction."
-					console.log('".$ajaxFunction." has been updated');
+					var oldElement = $('#'+loadedID).prop('outerHTML');
+					var newElement = $(getDiv).prop('outerHTML');
+					if(oldElement !== newElement){
+						$('#'+loadedID).replaceWith($(getDiv).prop('outerHTML'));
+						".$extraFunction."
+						console.log('".$ajaxFunction." has been updated');
+					}
 				}else{
 					console.log('".$ajaxFunction." data was not sufficent or is offline');
 				}
@@ -4818,7 +4921,18 @@ function massEmail($to, $subject, $message){
 		$GLOBALS['file_db'] = new PDO('sqlite:'.DATABASE_LOCATION.'users.db');
 		$GLOBALS['file_db']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 	}
-	sendEmail(null, null, $subject, orgEmail("Message From Admin", "Important Information", "There", $message, null, null, "Thank You!", "Thanks for taking the time to read this message from me."),$GLOBALS['USER']->adminEmail,$to);
+	$emailTemplate = array(
+		'type' => 'mass',
+		'body' => $message,
+		'subject' => $subject,
+		'user' => null,
+		'password' => null,
+		'inviteCode' => null,
+	);
+	$emailTemplate = emailTemplate($emailTemplate);
+	$subject = $emailTemplate['subject'];
+	$body = buildEmail($emailTemplate);
+	sendEmail(null, null, $subject, $body, $GLOBALS['USER']->adminEmail,$to);
 }
 
 function q2a($q){
@@ -5101,7 +5215,7 @@ function buildOmbiList($group, $user){
 	}else{
 		if(is_array($movieList)){
 			$result = $movieList;
-		}elseif(is_array($movieList)){
+		}elseif(is_array($tvList)){
 			$result = $tvList;
 		}else{
 			$result = false;
@@ -5145,7 +5259,7 @@ function outputOmbiRequests($header = "Requested Content", $items, $script = fal
         return '<div id="recentRequests"></div>';
     }else{
 		$className = str_replace(' ', '', $header);
-        return '<div id="recentRequests" class="content-box box-shadow big-box"><h5 id="requestContent-title" style="margin-bottom: -20px" class="text-center">'.$header.'</h5><div class="recentHeader inbox-pagination '.$className.'">'.$hideMenu.'</div><br/><br/><div class="recentItems-request" data-name="'.$className.'">'.implode('',$items).'</div></div>'.($script?'<script>'.$script.'</script>':'');
+        return '<div id="recentRequests" class="content-box box-shadow big-box"><h5 id="requestContent-title" style="margin-bottom: -20px" class="text-center"><span>'.$header.'</span></h5><div class="recentHeader inbox-pagination '.$className.'">'.$hideMenu.'</div><br/><br/><div class="recentItems-request" data-name="'.$className.'">'.implode('',$items).'</div></div>'.($script?'<script>'.$script.'</script>':'');
     }
 }
 
@@ -5229,6 +5343,13 @@ function buildHomepageSettings(){
 					$class .= ' faded';
 				}
 				break;
+			case 'homepageOrdertransmisson':
+				$class = 'green-bg';
+				$image = 'images/transmission.png';
+				if(empty(TRANSMISSIONURL)){
+					$class .= ' faded';
+				}
+				break;
 			case 'homepageOrdernzbget':
 				$class = 'green-bg';
 				$image = 'images/nzbget.png';
@@ -5478,6 +5599,11 @@ function buildHomepageItem($homepageItem, $group, $user){
 				';
 			}
 			break;
+		case 'homepageOrdertransmisson':
+			if(TRANSMISSIONURL != "" && qualifyUser(TRANSMISSIONHOMEAUTH)){
+				$homepageItemBuilt .= buildDownloader('transmission', 'no');
+			}
+			break;
 		case 'homepageOrdernzbget':
 			if(NZBGETURL != "" && qualifyUser(NZBGETHOMEAUTH)){
 				$homepageItemBuilt .= buildDownloader('nzbget');
@@ -5579,7 +5705,124 @@ function buildHomepageItem($homepageItem, $group, $user){
 	return $homepageItemBuilt;
 }
 
-function buildDownloader($name){
+function buildAccordion($items){
+	$i = 1;
+	$variables = '&nbsp; Available Variables: ';
+	$accordion = '<div style="margin-bottom: 0px;" class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">';
+	foreach ($items as $key => $value) {
+		if($value['type'] == 'template' || $value['type'] == 'templateCustom'){
+			foreach ($value['variables'] as $variable) {
+				$variables .= '<mark>'.$variable.'</mark>';
+			}
+			$templateCustom = '
+			<div class="form-content col-sm-12 col-md-12 col-lg-12">
+				<input id="'.$value['template'].'Name_id" name="'.$value['template'].'Name" type="text" class="form-control material input-sm" autocorrect="off" autocapitalize="off" value="'.$value['title'].'">
+				<p class="help-text">Custom Template Name</p>
+			</div>
+			';
+			$accordion .= '
+			<div class="panel panel-default">
+				<div class="panel-heading" role="tab" id="heading-'.$i.'">
+					<h4 class="panel-title" style="text-decoration: none;" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-'.$i.'" aria-expanded="true" aria-controls="collapse-'.$i.'">'.$value['title'].'</h4>
+				</div>
+				<div id="collapse-'.$i.'" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-'.$i.'" aria-expanded="true">
+					<br/>'.$variables.'<br/></br/>
+					'.$templateCustom.'
+					<div class="form-content col-sm-12 col-md-12 col-lg-12">
+						<input id="'.$value['template'].'Subject_id" name="'.$value['template'].'Subject" type="text" class="form-control material input-sm" autocorrect="off" autocapitalize="off" value="'.$value['subject'].'">
+						<p class="help-text">Email Subject</p>
+					</div>
+					<br/></br/>
+					<div class="summernote" name="'.$value['template'].'">'.$value['body'].'</div>
+				</div>
+			</div>
+			';
+			$i++;
+			$variables = '&nbsp; Available Variables: ';
+		}else{
+			$accordion .= '
+			<div class="panel panel-default">
+				<div class="panel-heading" role="tab" id="heading-'.$i.'">
+					<h4 class="panel-title" style="text-decoration: none;" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-'.$i.'" aria-expanded="true" aria-controls="collapse-'.$i.'">Logo URL For Title</h4>
+				</div>
+				<div id="collapse-'.$i.'" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-'.$i.'" aria-expanded="true">
+					<div class="form-content col-sm-12 col-md-12 col-lg-12">
+						<input id="'.$value['name'].'_id" name="'.$value['name'].'" type="text" class="form-control material input-sm" autocorrect="off" autocapitalize="off" value="'.$value['value'].'">
+						<p class="help-text">Logo URL For Title</p>
+					</div>
+					<br/></br/><br/>
+				</div>
+			</div>
+			';
+			$i++;
+		}
+	}
+	$accordion .= '</div>';
+	return $accordion;
+}
+
+function emailTemplate($emailTemplate){
+	$variables = [
+		'{user}' => $emailTemplate['user'],
+		'{domain}' => DOMAIN,
+		'{password}' => $emailTemplate['password'],
+		'{inviteCode}' => $emailTemplate['inviteCode'],
+		'{fullDomain}' => getServerPath(),
+	];
+	$emailTemplate['body'] = strtr($emailTemplate['body'], $variables);
+	$emailTemplate['subject'] = strtr($emailTemplate['subject'], $variables);
+	return $emailTemplate;
+}
+
+function buildEmail($email){
+	$subject = (isset($email['subject'])) ? $email['subject'] : 'Message from Server';
+	$body = (isset($email['body'])) ? $email['body'] : 'Message Error Occured';
+	$type = (isset($email['type'])) ? $email['type'] : 'No Type';
+	switch ($type) {
+		case 'invite':
+			$extra = 'invite';
+			break;
+		case 'reset':
+			$extra = 'reset';
+			break;
+		default:
+			$extra = null;
+			break;
+	}
+	include('email.php');
+	return $email;
+}
+
+function buildDownloader($name, $type = 'both'){
+	if($type == 'both'){
+		$tabs = '
+		<ul class="nav nav-tabs pull-right">
+			<li class="active"><a href="#downloadQueue-'.$name.'" data-toggle="tab" aria-expanded="true">'.translate("QUEUE").'</a></li>
+			<li class=""><a href="#downloadHistory-'.$name.'" data-toggle="tab" aria-expanded="false">'.translate("HISTORY").'</a></li>
+		</ul>
+		';
+		$bodyHistory = '
+		<div class="tab-pane fade" id="downloadHistory-'.$name.'">
+			<div class="table-responsive" style="max-height: 300px">
+				<table class="table table-striped progress-widget zero-m" style="max-height: 300px">
+					<thead>
+						<tr>
+							<th class="col-xs-7 nzbtable-file-row">'.translate("FILE").'</th>
+							<th class="col-xs-2 nzbtable">'.translate("STATUS").'</th>
+							<th class="col-xs-1 nzbtable">'.translate("CATEGORY").'</th>
+							<th class="col-xs-1 nzbtable">'.translate("SIZE").'</th>
+							<th class="col-xs-2 nzbtable">'.translate("PROGRESS").'</th>
+						</tr>
+					</thead>
+					<tbody class="dl-history '.$name.'"></tbody>
+				</table>
+			</div>
+		</div>
+		';
+	}else{
+		$tabs = '';
+		$bodyHistory = '';
+	}
 	return '
 <div id="downloadClientRow" class="row">
 	<div class="col-xs-12 col-md-12">
@@ -5591,11 +5834,8 @@ function buildDownloader($name){
 							<i class="fa fa-repeat"></i>
 						</a>
 					</div>
-					<h3 class="pull-left">'.strtoupper($name).'</h3>
-					<ul class="nav nav-tabs pull-right">
-						<li class="active"><a href="#downloadQueue-'.$name.'" data-toggle="tab" aria-expanded="true">'.translate("QUEUE").'</a></li>
-						<li class=""><a href="#downloadHistory-'.$name.'" data-toggle="tab" aria-expanded="false">'.translate("HISTORY").'</a></li>
-					</ul>
+					<h3 class="pull-left"><span>'.strtoupper($name).'</span></h3>
+					'.$tabs.'
 					<div class="clearfix"></div>
 				</div>
 				<div class="panel-body">
@@ -5616,22 +5856,7 @@ function buildDownloader($name){
 								</table>
 							</div>
 						</div>
-						<div class="tab-pane fade" id="downloadHistory-'.$name.'">
-							<div class="table-responsive" style="max-height: 300px">
-								<table class="table table-striped progress-widget zero-m" style="max-height: 300px">
-									<thead>
-										<tr>
-											<th class="col-xs-7 nzbtable-file-row">'.translate("FILE").'</th>
-											<th class="col-xs-2 nzbtable">'.translate("STATUS").'</th>
-											<th class="col-xs-1 nzbtable">'.translate("CATEGORY").'</th>
-											<th class="col-xs-1 nzbtable">'.translate("SIZE").'</th>
-											<th class="col-xs-2 nzbtable">'.translate("PROGRESS").'</th>
-										</tr>
-									</thead>
-									<tbody class="dl-history '.$name.'"></tbody>
-								</table>
-							</div>
-						</div>
+						'.$bodyHistory.'
 					</div>
 				</div>
 			</div>

+ 6 - 5
homepage.php

@@ -122,7 +122,7 @@ foreach(loadAppearance() as $key => $value) {
 			    left: 5px;
 			}
 			.refreshImage span.w-refresh:hover::before {
-				content: "Refresh";
+				/*content: "Refresh";
 			    font-size: 17px;
 			    float: right;
 			    top: 18px;
@@ -131,7 +131,7 @@ foreach(loadAppearance() as $key => $value) {
 			    color: white;
 			    background: black;
 			    border-radius: 5px;
-			    padding: 0px 20px;
+			    padding: 0px 20px;*/
 			}
             .fc-day-grid-event{
                 cursor: pointer;
@@ -197,7 +197,7 @@ foreach(loadAppearance() as $key => $value) {
                 width: 100%;
                 height: 100%;
                 display: none;
-                z-index: 0;
+                z-index: 1;
                 opacity: .98;
             }
             sort {
@@ -469,7 +469,7 @@ foreach(loadAppearance() as $key => $value) {
 				var needsSlick = true;
 				var name = $(this).attr("data-name");
 				if($(this).hasClass('slick-initialized')){
-					console.log('skipping slick addon for: '+name);
+					//console.log('skipping slick addon for: '+name);
 					needsSlick = false;
 				}
 				if(needsSlick === true){
@@ -804,13 +804,14 @@ foreach(loadAppearance() as $key => $value) {
                 grabcursorenabled: false
             });
 
-            <?php if((NZBGETURL != "" && qualifyUser(NZBGETHOMEAUTH)) || (SABNZBDURL != "" && qualifyUser(SABNZBDHOMEAUTH))){ ?>
+            <?php if((NZBGETURL != "" && qualifyUser(NZBGETHOMEAUTH)) || (SABNZBDURL != "" && qualifyUser(SABNZBDHOMEAUTH)) || (TRANSMISSIONURL != "" && qualifyUser(TRANSMISSIONHOMEAUTH))){ ?>
             var queueRefresh = <?php echo DOWNLOADREFRESH; ?>;
             var historyRefresh = <?php echo HISTORYREFRESH; ?>; // This really doesn't need to happen that often
 
             var queueLoad = function() {
             <?php if(SABNZBDURL != "") { echo '$("tbody.dl-queue.sabnzbd").load("ajax.php?a=sabnzbd-update&list=queue");'; } ?>
             <?php if(NZBGETURL != "") { echo '$("tbody.dl-queue.nzbget").load("ajax.php?a=nzbget-update&list=listgroups");'; } ?>
+			<?php if(TRANSMISSIONURL != "") { echo '$("tbody.dl-queue.transmission").load("ajax.php?a=transmission-update&list=listgroups");'; } ?>
             };
 
             var historyLoad = function() {

BIN
images/flood.png


BIN
images/layercake.png


BIN
images/logarr.png


BIN
images/medusa.png


+ 12 - 12
index.php

@@ -265,6 +265,14 @@ $group = (isset($group) ? $group : "guest");
 		<![endif]-->
 	</head>
 	<style>
+		.la-ball-scale-multiple.la-3x {
+			width: auto !important;
+			height: auto !important;
+		}
+		.logo img {
+		    display: block;
+		    margin: auto;
+		}
 		#splashScreen ping span {
 		    margin-top: 0 !important;
 		    font-size: 10px;
@@ -1045,7 +1053,7 @@ $group = (isset($group) ? $group : "guest");
 			</div>
 		</div>
 		<?php } ?>
-		<?php if (file_exists('config/config.php') && $configReady == "Yes" && $tabSetup == "No" && SPLASH == "true" && $splash && count($splash) > 1) {?>
+		<?php if (file_exists('config/config.php') && $configReady == "Yes" && $tabSetup == "No" && SPLASH == "true" && $splash && count($splash) > 1 && qualifyUser(SPLASHAUTH)) {?>
 		<div id="splashScreen" class="splash-modal modal fade">
 			<div style="background:<?=$sidebar;?>;" class="table-wrapper big-box">
 
@@ -1206,14 +1214,6 @@ $group = (isset($group) ? $group : "guest");
 												<span style="display: block" class="current-time gray text-center"></span>
 											</div>
 											<div class="content-box">
-											<!--
-											<div class="member-info zero-m">
-												<img src="https://www.gravatar.com/avatar/<?=$userpic;?>?s=50&d=mm" alt="user" class="img-circle pull-left">
-												<p><i class="fa fa-user green zero-m"></i><span class="member-name gray"><strong><?php echo strtoupper($USER->username); ?></strong></span></p>
-												<p><i class="fa fa-group green zero-m"></i><span class="member-name gray"><strong> <?php echo strtoupper($USER->role); ?></strong></span></p>
-
-											</div>
-											-->
 												<div class="profile-usertitle">
 													<?php if(GRAVATAR == "true") : ?>
 													<img src="https://www.gravatar.com/avatar/<?=$userpic;?>?s=100&d=mm" class="img-responsive img-circle center-block" alt="user">
@@ -1935,7 +1935,7 @@ $group = (isset($group) ? $group : "guest");
 		$("li[class^='tab-item']").dblclick(function(){
 			var thisidfull = $(this).attr("id");
 			var thisid = thisidfull.substr(0, thisidfull.length-1);
-			var thisframe = $("#content div[data-content-url^='"+thisid+"']").children('iframe');
+			var thisframe = $("#content div[data-content-url='"+thisid+"']").children('iframe');
 			$(thisframe).attr('src', $(thisframe).attr('src'));
 			var refreshBox = $('#content').find('.active');
 
@@ -2097,7 +2097,7 @@ $group = (isset($group) ? $group : "guest");
 
 			var thisid = thisidfull.substr(0, thisidfull.length-1);
 
-			var currentframe = $("#content div[data-content-url^='"+thisid+"']");
+			var currentframe = $("#content div[data-content-url='"+thisid+"']");
 
 			if (currentframe.attr("class") == "iframe active") {
 
@@ -2154,7 +2154,7 @@ $group = (isset($group) ? $group : "guest");
 
 			var thisid = thisidfull.substr(0, thisidfull.length-1);
 
-			var currentframe = $("#contentRight div[data-content-url^='"+thisid+"']");
+			var currentframe = $("#contentRight div[data-content-url='"+thisid+"']");
 
 			if (currentframe.attr("class") == "iframe active") {
 

+ 2 - 1
lang/en.ini

@@ -259,7 +259,7 @@ SHOW_NAMES = "Show Names"
 NOTICE_LAYOUT = "Notice Layout"
 RECENT_ITEMS_LIMIT = "Recent Items Limit"
 ALLOW_SEARCH = "Allow Search"
-CHECK_INVITE = "Enter Invite Code to Procced"
+CHECK_INVITE = "Enter Invite Code to Proceed"
 CODE = "Invite Code"
 INVITE_CODE = "Invite Code"
 DATE_SENT = "Date Sent"
@@ -345,3 +345,4 @@ OMBI_URL = "Ombi V3 URL"
 OMBI_KEY = "Ombi V3 API Key"
 ENABLE_WEATHER = "Enable Weather Widget"
 WEATHER_AUTH = "Minimum authentication level to access Weather Widget"
+TRANSMISSION_URL = "Transmission URL"

+ 1 - 1
lang/es.ini

@@ -259,7 +259,7 @@ SHOW_NAMES = "Show Names"
 NOTICE_LAYOUT = "Notice Layout"
 RECENT_ITEMS_LIMIT = "Recent Items Limit"
 ALLOW_SEARCH = "Allow Search"
-CHECK_INVITE = "Enter Invite Code to Procced"
+CHECK_INVITE = "Enter Invite Code to Proceed"
 CODE = "Invite Code"
 INVITE_CODE = "Invite Code"
 DATE_SENT = "Date Sent"

+ 1 - 1
lang/fr.ini

@@ -259,7 +259,7 @@ SHOW_NAMES = "Show Names"
 NOTICE_LAYOUT = "Notice Layout"
 RECENT_ITEMS_LIMIT = "Recent Items Limit"
 ALLOW_SEARCH = "Allow Search"
-CHECK_INVITE = "Enter Invite Code to Procced"
+CHECK_INVITE = "Enter Invite Code to Proceed"
 CODE = "Invite Code"
 INVITE_CODE = "Invite Code"
 DATE_SENT = "Date Sent"

+ 1 - 1
lang/it.ini

@@ -259,7 +259,7 @@ SHOW_NAMES = "Show Names"
 NOTICE_LAYOUT = "Notice Layout"
 RECENT_ITEMS_LIMIT = "Recent Items Limit"
 ALLOW_SEARCH = "Allow Search"
-CHECK_INVITE = "Enter Invite Code to Procced"
+CHECK_INVITE = "Enter Invite Code to Proceed"
 CODE = "Invite Code"
 INVITE_CODE = "Invite Code"
 DATE_SENT = "Date Sent"

+ 1 - 1
lang/nl.ini

@@ -259,7 +259,7 @@ SHOW_NAMES = "Show Names"
 NOTICE_LAYOUT = "Notice Layout"
 RECENT_ITEMS_LIMIT = "Recent Items Limit"
 ALLOW_SEARCH = "Allow Search"
-CHECK_INVITE = "Enter Invite Code to Procced"
+CHECK_INVITE = "Enter Invite Code to Proceed"
 CODE = "Invite Code"
 INVITE_CODE = "Invite Code"
 DATE_SENT = "Date Sent"

+ 257 - 31
settings.php

@@ -497,6 +497,15 @@ $themeVersion = (!empty(INSTALLEDTHEME) ? explode("-", INSTALLEDTHEME)[1] : null
 							'color' => 'orange',
 							'color2' => 'palette-Light-Blue-A700 bg',
 							'padding' => '2',
+						),array(
+							'id' => 'open-help',
+							'box' => 'help-box',
+							'name' => 'Help & Chat',
+							'icon_1' => 'help-circle',
+							'icon_2' => 'question-circle',
+							'color' => 'orange',
+							'color2' => 'palette-Light-Blue-900 bg',
+							'padding' => '2',
 						),array(
 							'id' => 'open-donate',
 							'box' => 'donate-box',
@@ -843,6 +852,10 @@ echo buildSettings(
 				'id' => 'home_general',
 				'image' => 'images/gear.png',
 				'fields' => array(
+					array(
+						'type' => 'custom',
+						'html' => '<h2>To Enable, please add new tab with url of homepage.php</h2>',
+					),
 					array(
 						'type' => $userSelectType,
 						'labelTranslate' => 'SHOW_HOMEPAGE',
@@ -1371,6 +1384,7 @@ echo buildSettings(
 						'labelTranslate' => 'PASSWORD',
 						'name' => 'nzbgetPassword',
 						'value' => (empty(NZBGETPASSWORD)?'':randString(20)),
+                        'autocomplete' => 'new-password',
 					),
                     array(
 						'type' => $userSelectType,
@@ -1388,6 +1402,49 @@ echo buildSettings(
 					),
 				),
 			),
+			array(
+				'title' => 'Transmission',
+				'id' => 'transmission',
+				'image' => 'images/transmission.png',
+				'fields' => array(
+					array(
+						'type' => $userSelectType,
+						'labelTranslate' => 'SHOW_ON_HOMEPAGE',
+						'name' => 'transmissionHomeAuth',
+						'value' => TRANSMISSIONHOMEAUTH,
+						'options' => $userTypes,
+					),
+					array(
+						'type' => 'text',
+						'placeholder' => 'http://hostname:6789',
+						'labelTranslate' => 'TRANSMISSION_URL',
+						'assist' => 'http://hostname:6789',
+						'name' => 'transmissionURL',
+						'pattern' => $urlPattern,
+						'value' => TRANSMISSIONURL,
+					),
+					array(
+						'type' => 'text',
+						'labelTranslate' => 'USERNAME',
+						'name' => 'transmissionUsername',
+						'value' => TRANSMISSIONUSERNAME,
+					),
+					array(
+						'type' => 'password',
+						'labelTranslate' => 'PASSWORD',
+						'name' => 'transmissionPassword',
+						'value' => (empty(TRANSMISSIONPASSWORD)?'':randString(20)),
+                        'autocomplete' => 'new-password',
+					),
+                    array(
+						'type' => $userSelectType,
+						'labelTranslate' => 'DOWNLOAD_REFRESH',
+						'name' => 'downloadRefresh',
+						'value' => DOWNLOADREFRESH,
+						'options' => $refreshSeconds,
+					),
+				),
+			),
 			array(
 				'title' => 'Calendar',
 				'id' => 'calendar',
@@ -1681,7 +1738,69 @@ foreach (array_filter(get_defined_functions()['user'],function($v) { return strp
 	}
 }
 ksort($backendOptions);
-
+$emailTemplates = array(
+	array(
+		'type' => 'inputbox',
+		'name' => 'emailTempateLogo',
+		'value' => emailTempateLogo,
+	),
+	array(
+		'type' => 'template',
+		'title' => 'Password Reset',
+        'variables' => array('{user}','{domain}','{fullDomain}','{password}'),
+        'subject' => emailTemplateResetPasswordSubject,
+		'body' => emailTemplateResetPassword,
+        'template' => 'emailTemplateResetPassword',
+	),
+	array(
+		'type' => 'template',
+		'title' => 'New Registration',
+        'variables' => array('{user}','{domain}','{fullDomain}'),
+        'subject' => emailTemplateRegisterUserSubject,
+		'body' => emailTemplateRegisterUser,
+        'template' => 'emailTemplateRegisterUser',
+	),
+    array(
+		'type' => 'template',
+		'title' => 'Invite User',
+        'variables' => array('{user}','{domain}','{fullDomain}','{inviteCode}'),
+        'subject' => emailTemplateInviteUserSubject,
+		'body' => emailTemplateInviteUser,
+        'template' => 'emailTemplateInviteUser',
+	),
+	array(
+		'type' => 'templateCustom',
+		'title' => emailTemplateCustomOneName,
+        'variables' => array('{domain}','{fullDomain}'),
+        'subject' => emailTemplateCustomOneSubject,
+		'body' => emailTemplateCustomOne,
+        'template' => 'emailTemplateCustomOne',
+	),
+	array(
+		'type' => 'templateCustom',
+		'title' => emailTemplateCustomTwoName,
+        'variables' => array('{domain}','{fullDomain}'),
+        'subject' => emailTemplateCustomTwoSubject,
+		'body' => emailTemplateCustomTwo,
+        'template' => 'emailTemplateCustomTwo',
+	),
+	array(
+		'type' => 'templateCustom',
+		'title' => emailTemplateCustomThreeName,
+        'variables' => array('{domain}','{fullDomain}'),
+        'subject' => emailTemplateCustomThreeSubject,
+		'body' => emailTemplateCustomThree,
+        'template' => 'emailTemplateCustomThree',
+	),
+	array(
+		'type' => 'templateCustom',
+		'title' => emailTemplateCustomFourName,
+        'variables' => array('{domain}','{fullDomain}'),
+        'subject' => emailTemplateCustomFourSubject,
+		'body' => emailTemplateCustomFour,
+        'template' => 'emailTemplateCustomFour',
+	),
+);
 echo buildSettings(
 	array(
 		'title' => 'Advanced Settings',
@@ -1781,6 +1900,7 @@ echo buildSettings(
 						'name' => 'plexPassword',
 						'class' => 'be-auth be-auth-plex',
 						'value' => (empty(PLEXPASSWORD)?'':randString(20)),
+						'autocomplete' => 'new-password',
 					),
                     array(
 						'type' => 'text',
@@ -1833,6 +1953,7 @@ echo buildSettings(
 						'labelTranslate' => 'COOKIE_PASSWORD',
 						'name' => 'cookiePassword',
 						'value' => (empty(COOKIEPASSWORD)?'':randString(20)),
+                        'autocomplete' => 'new-password',
 					),
                     array(
 						'type' => 'text',
@@ -1898,6 +2019,7 @@ echo buildSettings(
 						'labelTranslate' => 'SMTP_HOST_PASSWORD',
 						'name' => 'smtpHostPassword',
 						'value' => (empty(SMTPHOSTPASSWORD)?'':randString(20)),
+                        'autocomplete' => 'new-password',
 					),
 					array(
 						'type' => 'text',
@@ -1942,6 +2064,25 @@ echo buildSettings(
 							'value' => ENABLEMAIL,
 						),
 					),
+					array(
+						'type' => 'custom',
+						'html' => '<h2>Custom Mail Options</h2>',
+					),
+					array(
+	                    array(
+							'type' => 'custom',
+							'html' => buildAccordion($emailTemplates),
+						),
+	                    array(
+							'type' => 'textarea',
+							'name' => 'emailTemplateCSS',
+							'value' => emailTemplateCSS,
+	                        'labelTranslate' => 'EDIT_CUSTOM_CSS',
+	                        'placeholder' => 'Please Include <style></style> tags',
+							'rows' => 25,
+							'style' => 'background: #000; color: #FFF;',
+						),
+					),
 				),
 			),
 			array(
@@ -1993,13 +2134,22 @@ echo buildSettings(
 							'Sliding' => 'other-thumbslider',
 						),
 					),
-					array(
-						array(
+                    array(
+                        array(
 							'type' => 'checkbox',
 							'labelTranslate' => 'ENABLE_SPLASH_SCREEN',
 							'name' => 'splash',
 							'value' => SPLASH,
 						),
+                        array(
+    						'type' => $userSelectType,
+    						'labelTranslate' => 'MINIMUM_SPLASH_ACCESS',
+    						'name' => 'splashAuth',
+    						'value' => SPLASHAUTH,
+    						'options' => $userTypes,
+    					),
+                    ),
+					array(
 						array(
 							'type' => 'checkbox',
 							'labelTranslate' => 'ENABLE_LOADING_SCREEN',
@@ -2112,7 +2262,7 @@ echo buildSettings(
                                 <div class="small-box fade in" id="donate-org">
                                     <div class="row">
                                         <div class="col-lg-12">
-                                            <div class="big-box">
+
                                                 <div class="jumbotron">
                                                     <div class="container">
                                                         <h2><strong>Hey There <em class="gray"><?php echo ucwords($USER->username);?></em>,</strong></h2>
@@ -2124,11 +2274,11 @@ echo buildSettings(
                                                         <p class="pull-right"><i class="fa fa-heart fa-1x red loop-animation animated pulse" aria-hidden="true"></i> CauseFX</p>
                                                     </div>
                                                 </div>
-                                            </div>
+
                                         </div>
                                     </div>
                                     <div class="row">
-                                        <div class="col-sm-4 col-lg-4">
+                                        <div class="col-sm-6 col-lg-6">
                                             <div class="content-box ultra-widget blue-bg" style="cursor: pointer;" onclick="window.open('https://paypal.me/causefx', '_blank')">
                                                 <div class="w-content big-box">
                                                     <div class="w-progress">
@@ -2144,8 +2294,6 @@ echo buildSettings(
                                                     </span>
                                                 </div>
                                             </div>
-                                        </div>
-                                        <div class="col-sm-4 col-lg-4">
                                             <div class="content-box ultra-widget green-bg" style="cursor: pointer;" onclick="window.open('https://cash.me/$causefx', '_blank')">
                                                 <div class="w-content big-box">
                                                     <div class="w-progress">
@@ -2161,12 +2309,11 @@ echo buildSettings(
                                                     </span>
                                                 </div>
                                             </div>
-                                        </div>
-										 <div class="col-sm-4 col-lg-4">
                                             <div class="content-box ultra-widget red-bg">
                                                 <div class="w-content big-box">
                                                     <div class="w-progress">
                                                         <span class="w-amount">BitCoin</span>
+                                                        <br>
                                                         <small class="text-uppercase">1JLWKsSgDDKdnLjPWbnxfQmCxi8uUohzVv</small>
                                                     </div>
                                                     <span class="w-refresh w-p-icon">
@@ -2176,8 +2323,27 @@ echo buildSettings(
                                                         </span>
                                                     </span>
                                                 </div>
+                                            </div>
+										</div>
+                                        <div class="col-sm-6 col-lg-6">
+                                            <div class="jumbotron">
+                                                <div class="container">
+                                                    <h2><strong>Want to become an  <em class="gray">ORGANIZR</em> Patreon?</strong></h2>
+                                                    <small>By becoming a Patreon, you will get some perks on Discord as well as other things...</small>
+                                                    <br/><br/>
+                                                    <small>Some of the perks are:</small>
+                                                    <br/><br/>
+                                                    <ul>
+                                                        <li>One on One RDP Sessions</li>
+                                                        <li>Help with Custom CSS</li>
+                                                        <li>Feature Request Priority</li>
+                                                        <li>And more..</li>
+                                                    </ul>
+                                                    <p class="pull-right"><a class="btn btn-default" target='_blank' href="https://www.patreon.com/organizr"><i class="fa fa-hand-o-right fa-1x red loop-animation animated pulse" aria-hidden="true"></i> Become Patreon</a></p>
+                                                </div>
                                             </div>
                                         </div>
+
                                     </div>
                                 </div>
                             </div>
@@ -2196,7 +2362,7 @@ echo buildSettings(
                                     <div class="row">
                                         <div class="col-lg-2">
                                             <div class="content-box profile-sidebar box-shadow">
-                                                <img src="images/organizr-logo-h-d.png" width="100%" style="margin-top: -10px;">
+                                                <img src="images/layercake.png" width="50%" style="margin-top: -10px; margin-bottom: 10px;">
                                                 <div class="profile-usermenu">
                                                     <ul class="nav" id="theme-list"></ul>
                                                 </div>
@@ -2226,26 +2392,39 @@ echo buildSettings(
                                 <div class="small-box fade in">
 
 
-                                        <div class="mail-header">
-                                            <p>
-                                                <button class="btn btn-success waves generateEmails">Choose Users</button>
-                                                <button id="selectAllEmail" style="display: none;" class="btn btn-success waves">Select All</button>
-                                            </p>
-                                            <div style="display: none;"class="form-group" id="emailSelect">
-                                            <select multiple="true" size="10" id="email-users" class="form-control"></select>
-                                            </div>
-                                            <div class="form-group">
-                                                <input type="text" class="form-control material" id="mailTo" placeholder="To">
-                                            </div>
-                                            <div class="form-group">
-                                                <input type="text" class="form-control material" id="subject" placeholder="Subject">
-                                            </div>
+                                    <div class="mail-header">
+                                        <div class="sort-todo">
+                                            <button class="btn btn-success btn-labeled waves btn-sm text-uppercase waves-effect waves-float generateEmails">
+												<span class="btn-label"><i class="fa fa-users"></i></span><span class="btn-text">Choose Users</span>
+											</button>
+                                            <button id="selectAllEmail" style="display: none;" class="btn btn-success btn-labeled waves btn-sm text-uppercase waves-effect waves-float">
+												<span class="btn-label"><i class="fa fa-users"></i></span><span class="btn-text">Select All</span>
+											</button>
+											<button id="sendEmail" class="btn btn-success btn-labeled waves btn-sm text-uppercase waves-effect waves-float pull-right">
+												<span class="btn-label"><i class="fa fa-paper-plane"></i></span><span class="btn-text">Send</span>
+											</button>
+											<div class="btn-group">
+												<button id="emailCustom" type="button" class="btn waves btn-labeled btn-dark btn-sm text-uppercase waves-effect waves-float dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="btn-label"><i class="fa fa-envelope"></i></span><span class="btn-text">Custom Email Templates</span></button>
+												<ul class="dropdown-menu">
+													<li class="dropdown-header">Choose a Template Below</li>
+													<li><a onclick="customEmail('one');" href="#"><?php echo emailTemplateCustomOneName; ?></a></li>
+													<li><a onclick="customEmail('two');" href="#"><?php echo emailTemplateCustomTwoName; ?></a></li>
+													<li><a onclick="customEmail('three');" href="#"><?php echo emailTemplateCustomThreeName; ?></a></li>
+													<li><a onclick="customEmail('four');" href="#"><?php echo emailTemplateCustomFourName; ?></a></li>
+												</ul>
+											</div>
                                         </div>
-
-                                        <div class="summernote"></div>
-                                        <button id="sendEmail" class="btn btn-success waves">Send</button>
-
-
+                                        <div style="display: none;"class="form-group" id="emailSelect">
+                                        <select multiple="true" size="10" id="email-users" class="form-control"></select>
+                                        </div>
+                                        <div class="form-group">
+                                            <input type="text" class="form-control material" id="mailTo" placeholder="To">
+                                        </div>
+                                        <div class="form-group">
+                                            <input type="text" class="form-control material" id="subject" placeholder="Subject">
+                                        </div>
+                                    </div>
+                                    <div class="summernote"></div>
                             	</div>
                         	</div>
                     	</div>
@@ -2293,6 +2472,23 @@ echo buildSettings(
                         </div>
                     </div>
                 </div>
+                <div class="email-content help-box white-bg">
+                    <div class="email-body">
+                        <div class="email-header gray-bg">
+                            <button type="button" class="btn btn-danger btn-sm waves close-button"><i class="fa fa-close"></i></button>
+                            <h1>Help & Chat</h1>
+                        </div>
+                        <div class="email-inner small-box">
+                            <div class="email-inner-section">
+                                <div class="small-box fade in">
+
+                                    <embed style="height:calc(100vh - 100px);width:calc(100%)" src='https://titanembeds.com/embed/374648602632388610' />
+
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
                 <div class="email-content info-box white-bg">
                     <div class="email-body">
                         <div class="email-header gray-bg">
@@ -3586,6 +3782,16 @@ echo buildSettings(
                     emailtype: $('#smtpHostType_id').val(),
                     emailauth: $('#smtpHostAuth_id').attr("data-value"),
                 });
+				console.log(
+					'TO: <?php echo $USER->email;?>\n'+
+					'HOST: '+$('#smtpHost_id').val()+'\n'+
+					'PORT: '+$('#smtpHostPort_id').val()+'\n'+
+					'USERNAME: '+$('#smtpHostUsername_id').val()+'\n'+
+					'SENDER NAME: '+$('#smtpHostSenderName_id').val()+'\n'+
+					'SENDER EMAIL: '+$('#smtpHostSenderEmail_id').val()+'\n'+
+					'TYPE: '+$('#smtpHostType_id').val()+'\n'+
+					'AUTH: '+$('#smtpHostAuth_id').attr("data-value")+'\n'
+				);
                 console.log("ajax done");
             });
             //Custom Themes
@@ -3823,7 +4029,7 @@ echo buildSettings(
                 }
             });
 
-            $("#open-info, #open-users, #open-logs, #open-advanced, #open-homepage, #open-colors, #open-tabs, #open-donate, #open-invites , #open-themes, #open-speedtest, #open-email").on("click",function (e) {
+            $("#open-info, #open-users, #open-logs, #open-advanced, #open-homepage, #open-colors, #open-tabs, #open-donate, #open-invites , #open-themes, #open-speedtest, #open-email, #open-help").on("click",function (e) {
                 $(".email-content").removeClass("email-active");
                 $('html').removeClass("overhid");
                 if($(window).width() < 768){
@@ -3854,6 +4060,26 @@ echo buildSettings(
                 e.preventDefault();
             });
 
+			function customEmail(id){
+				if(id == 'one'){
+					var Body = '<?php echo emailTemplateCustomOne; ?>';
+					var Subject = '<?php echo emailTemplateCustomOneSubject; ?>';
+				}else if(id == 'two'){
+					var Body = '<?php echo emailTemplateCustomTwo; ?>';
+					var Subject = '<?php echo emailTemplateCustomTwoSubject; ?>';
+				}else if(id == 'three'){
+					var Body = '<?php echo emailTemplateCustomThree; ?>';
+					var Subject = '<?php echo emailTemplateCustomThreeSubject; ?>';
+				}else if(id == 'four'){
+					var Body = '<?php echo emailTemplateCustomFour; ?>';
+					var Subject = '<?php echo emailTemplateCustomFourSubject; ?>';
+				}
+				console.log(Body);
+				console.log(Subject);
+				$('#subject').val(Subject);
+				$('.email-box .note-editable.panel-body').html(Body);
+			}
+
             function checkGithub() {
                 $.ajax({
                     type: "GET",

+ 40 - 45
user.php

@@ -403,21 +403,17 @@
 			$update = "UPDATE users SET password = '$dbpassword' WHERE email= '$email'";
    			writeLog("success", "$username has reset their password");
 			$this->database->exec($update);
-            //$this->info("Email has been sent with new password");
-			// step 3: notify the user of the new password
-			$subject = DOMAIN . " Password Reset";
-			$language = new setLanguage;
-			$domain = getServerPath();
-			$body = orgEmail(
-					$header = $language->translate('EMAIL_RESET_HEADER'),
-					$title = $language->translate('EMAIL_RESET_TITLE'),
-					$user = $username,
-					$mainMessage =$language->translate('EMAIL_RESET_MESSAGE')."<br/>".$newpassword,
-					$button = $language->translate('EMAIL_RESET_BUTTON'),
-					$buttonURL = $domain,
-					$subTitle = $language->translate('EMAIL_RESET_SUBTITLE'),
-					$subMessage = $language->translate('EMAIL_RESET_SUBMESSAGE')
-					);
+			$emailTemplate = array(
+				'type' => 'reset',
+				'body' => emailTemplateResetPassword,
+				'subject' => emailTemplateResetPasswordSubject,
+				'user' => $username,
+				'password' => $newpassword,
+				'inviteCode' => null,
+			);
+			$emailTemplate = emailTemplate($emailTemplate);
+			$subject = $emailTemplate['subject'];
+			$body = buildEmail($emailTemplate);
             $this->startEmail($email, $username, $subject, $body);
 		}
 	// ------------------
@@ -542,7 +538,7 @@
 		 * is profile information that can be set, but in no way
 		 * needs to be, in the user's profile section
 		 */
-		function register_user($username, $email, $sha1, &$registration_callback = false, $settings, $validate) {
+		function register_user($username, $email, $sha1, &$registration_callback = false, $settings, $validate, $roleOverride = 'user', $password = null) {
 			//Admin bypass
 			if($validate == null){
 				$override = false;
@@ -573,6 +569,7 @@
             foreach($this->database->query($queryAdmin) as $data) {
                 $newRole = "user";
             }
+			if($roleOverride == 'admin'){ $newRole = "admin"; }
 			if($newRole == "user" && $validate == null){
 				writeLog("error", "$username on IP ".$_SERVER['REMOTE_ADDR']." is trying to hack your Organizr");
 				$this->error = "Hack attempt has been made. What are you doing? Logging your IP now...";
@@ -625,24 +622,21 @@
 				//$this->info("created user directory $dir");
 				// if there is a callback, call it
 				if($registration_callback !== false) { $registration_callback($username, $email, $dir); }
-                if($settings !== 'true' && $settings !== true) { $this->login_user($username, $sha1, true, '', false); }
+                if($settings !== 'true' && $settings !== true) { $this->login_user($username, $sha1, true, $password, false); }
 				//send email
 				if($username && User::use_mail)
 				{
-					// send email notification
-					$subject = "Welcome to ".DOMAIN;
-					$language = new setLanguage;
-					$domain = getServerPath();
-					$body = orgEmail(
-						$header = $language->translate('EMAIL_NEWUSER_HEADER'),
-						$title = $language->translate('EMAIL_NEWUSER_TITLE'),
-						$user = $username,
-						$mainMessage =$language->translate('EMAIL_NEWUSER_MESSAGE'),
-						$button = $language->translate('EMAIL_NEWUSER_BUTTON'),
-						$buttonURL = $domain,
-						$subTitle = $language->translate('EMAIL_NEWUSER_SUBTITLE'),
-						$subMessage = $language->translate('EMAIL_NEWUSER_SUBMESSAGE')
-						);
+					$emailTemplate = array(
+						'type' => 'registration',
+						'body' => emailTemplateRegisterUser,
+						'subject' => emailTemplateRegisterUserSubject,
+						'user' => $username,
+						'password' => null,
+						'inviteCode' => null,
+					);
+					$emailTemplate = emailTemplate($emailTemplate);
+					$subject = $emailTemplate['subject'];
+					$body = buildEmail($emailTemplate);
 					$this->startEmail($email, $username, $subject, $body);
 				}
 				return true;
@@ -707,10 +701,11 @@
 
 			if ($authSuccess) {
 				// Make sure user exists in database
-				$query = "SELECT role FROM users WHERE username = '".$username."' COLLATE NOCASE";
+				$query = "SELECT username FROM users WHERE username = '".$username."' OR email = '".$username."' COLLATE NOCASE";
 				$userExists = false;
 				foreach($this->database->query($query) as $data) {
 					$userExists = true;
+					$username = $data['username'];
 					break;
 				}
 
@@ -761,7 +756,8 @@
 				} else if (AUTHBACKENDCREATE !== 'false' && $surface) {
 					// Create User
 					$falseByRef = false;
-					$this->register_user($username, (is_array($authSuccess) && isset($authSuccess['email']) ? $authSuccess['email'] : ''), $sha1, $falseByRef, !$remember, true);
+					if(isset($authSuccess['type'])){ $roleOverride = $authSuccess['type']; }else{ $roleOverride = 'user'; }
+					$this->register_user($username, (is_array($authSuccess) && isset($authSuccess['email']) ? $authSuccess['email'] : ''), $sha1, $falseByRef, !$remember, true, $roleOverride, $password);
 				} else {
 					// authentication failed
 					//$this->info("Successful Backend Auth, No User in DB, Create Set to False");
@@ -872,18 +868,17 @@
 			$this->info("$email has been invited to the $server server");
 			if($insert && User::use_mail)
 			{
-				// send email notification
-				$subject = DOMAIN . " $uServer ".$language->translate('INVITE_CODE');
-				$body = orgEmail(
-					$header = explosion($language->translate('EMAIL_INVITE_HEADER'), 0)." ".$uServer." ".explosion($language->translate('EMAIL_INVITE_HEADER'), 1),
-					$title = $language->translate('EMAIL_INVITE_TITLE'),
-					$user = $username,
-					$mainMessage = explosion($language->translate('EMAIL_INVITE_MESSAGE'), 0)." ".$uServer." ".explosion($language->translate('EMAIL_INVITE_MESSAGE'), 1)." ".$inviteCode,
-					$button = explosion($language->translate('EMAIL_INVITE_BUTTON'), 0)." ".$uServer." ".explosion($language->translate('EMAIL_INVITE_BUTTON'), 1),
-					$buttonURL = $link,
-					$subTitle = $language->translate('EMAIL_INVITE_SUBTITLE'),
-					$subMessage = explosion($language->translate('EMAIL_INVITE_SUBMESSAGE'), 0)." <a href='".$domain."?inviteCode'>".$domain."</a> ".explosion($language->translate('EMAIL_INVITE_SUBMESSAGE'), 1)
-					);
+				$emailTemplate = array(
+					'type' => 'invite',
+					'body' => emailTemplateInviteUser,
+					'subject' => emailTemplateInviteUserSubject,
+					'user' => $username,
+					'password' => null,
+					'inviteCode' => $inviteCode,
+				);
+				$emailTemplate = emailTemplate($emailTemplate);
+				$subject = $emailTemplate['subject'];
+				$body = buildEmail($emailTemplate);
                 $this->startEmail($email, $username, $subject, $body);
 			}
 		}

+ 67 - 64
vendor/composer/installed.json

@@ -171,70 +171,6 @@
             "url"
         ]
     },
-    {
-        "name": "guzzlehttp/guzzle",
-        "version": "6.2.3",
-        "version_normalized": "6.2.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/guzzle/guzzle.git",
-            "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006",
-            "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006",
-            "shasum": ""
-        },
-        "require": {
-            "guzzlehttp/promises": "^1.0",
-            "guzzlehttp/psr7": "^1.4",
-            "php": ">=5.5"
-        },
-        "require-dev": {
-            "ext-curl": "*",
-            "phpunit/phpunit": "^4.0",
-            "psr/log": "^1.0"
-        },
-        "time": "2017-02-28T22:50:30+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "6.2-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "files": [
-                "src/functions_include.php"
-            ],
-            "psr-4": {
-                "GuzzleHttp\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Michael Dowling",
-                "email": "mtdowling@gmail.com",
-                "homepage": "https://github.com/mtdowling"
-            }
-        ],
-        "description": "Guzzle is a PHP HTTP client library",
-        "homepage": "http://guzzlephp.org/",
-        "keywords": [
-            "client",
-            "curl",
-            "framework",
-            "http",
-            "http client",
-            "rest",
-            "web service"
-        ]
-    },
     {
         "name": "kryptonit3/sonarr",
         "version": "1.0.5",
@@ -946,5 +882,72 @@
             "JWS",
             "jwt"
         ]
+    },
+    {
+        "name": "guzzlehttp/guzzle",
+        "version": "6.3.0",
+        "version_normalized": "6.3.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/guzzle/guzzle.git",
+            "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699",
+            "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699",
+            "shasum": ""
+        },
+        "require": {
+            "guzzlehttp/promises": "^1.0",
+            "guzzlehttp/psr7": "^1.4",
+            "php": ">=5.5"
+        },
+        "require-dev": {
+            "ext-curl": "*",
+            "phpunit/phpunit": "^4.0 || ^5.0",
+            "psr/log": "^1.0"
+        },
+        "suggest": {
+            "psr/log": "Required for using the Log middleware"
+        },
+        "time": "2017-06-22T18:50:49+00:00",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "6.2-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "files": [
+                "src/functions_include.php"
+            ],
+            "psr-4": {
+                "GuzzleHttp\\": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Michael Dowling",
+                "email": "mtdowling@gmail.com",
+                "homepage": "https://github.com/mtdowling"
+            }
+        ],
+        "description": "Guzzle is a PHP HTTP client library",
+        "homepage": "http://guzzlephp.org/",
+        "keywords": [
+            "client",
+            "curl",
+            "framework",
+            "http",
+            "http client",
+            "rest",
+            "web service"
+        ]
     }
 ]

+ 0 - 41
vendor/guzzlehttp/guzzle/.travis.yml

@@ -1,41 +0,0 @@
-language: php
-
-sudo: false
-
-php:
-  - 5.5
-  - 5.6
-  - 7.0
-  - 7.1
-  - hhvm
-
-before_script:
-  - curl --version
-  - composer install --no-interaction --prefer-source --dev
-  - ~/.nvm/nvm.sh install v0.6.14
-  - ~/.nvm/nvm.sh run v0.6.14
-  - '[ "$TRAVIS_PHP_VERSION" != "7.0" ] || echo "xdebug.overload_var_dump = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini'
-
-script: make test
-
-matrix:
-  allow_failures:
-    - php: hhvm
-  fast_finish: true
-
-before_deploy:
-  - rvm 1.9.3 do gem install mime-types -v 2.6.2
-  - make package
-
-deploy:
-  provider: releases
-  api_key:
-    secure: UpypqlYgsU68QT/x40YzhHXvzWjFwCNo9d+G8KAdm7U9+blFfcWhV1aMdzugvPMl6woXgvJj7qHq5tAL4v6oswCORhpSBfLgOQVFaica5LiHsvWlAedOhxGmnJqMTwuepjBCxXhs3+I8Kof1n4oUL9gKytXjOVCX/f7XU1HiinU=
-  file:
-    - build/artifacts/guzzle.phar
-    - build/artifacts/guzzle.zip
-  on:
-    repo: guzzle/guzzle
-    tags: true
-    all_branches: true
-    php: 5.5

+ 21 - 0
vendor/guzzlehttp/guzzle/CHANGELOG.md

@@ -1,5 +1,26 @@
 # CHANGELOG
 
+## 6.3.0 - 2017-06-22
+
+* Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659)
+* Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621)
+* Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580)
+* Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609)
+* Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641)
+* Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611)
+* Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811)
+* Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642)
+* Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569)
+* Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711)
+* Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745)
+* Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721)
+* Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318)
+* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684)
+* Improvement:  	Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827)
+
+
++ Minor code cleanups, documentation fixes and clarifications.
+
 ## 6.2.3 - 2017-02-28
 
 * Fix deprecations with guzzle/psr7 version 1.4

+ 10 - 11
vendor/guzzlehttp/guzzle/README.md

@@ -19,15 +19,13 @@ trivial to integrate with web services.
 
 ```php
 $client = new \GuzzleHttp\Client();
-$res = $client->request('GET', 'https://api.github.com/user', [
-    'auth' => ['user', 'pass']
-]);
+$res = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle');
 echo $res->getStatusCode();
 // 200
 echo $res->getHeaderLine('content-type');
 // 'application/json; charset=utf8'
 echo $res->getBody();
-// {"type":"User"...'
+// '{"id": 1420053, "name": "guzzle", ...}'
 
 // Send an asynchronous request.
 $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
@@ -40,7 +38,7 @@ $promise->wait();
 ## Help and docs
 
 - [Documentation](http://guzzlephp.org/)
-- [stackoverflow](http://stackoverflow.com/questions/tagged/guzzle)
+- [Stack Overflow](http://stackoverflow.com/questions/tagged/guzzle)
 - [Gitter](https://gitter.im/guzzle/guzzle)
 
 
@@ -75,14 +73,15 @@ composer.phar update
 
 ## Version Guidance
 
-| Version | Status      | Packagist           | Namespace    | Repo                | Docs                | PSR-7 |
-|---------|-------------|---------------------|--------------|---------------------|---------------------|-------|
-| 3.x     | EOL         | `guzzle/guzzle`     | `Guzzle`     | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No    |
-| 4.x     | EOL         | `guzzlehttp/guzzle` | `GuzzleHttp` | N/A                 | N/A                 | No    |
-| 5.x     | Maintained  | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No    |
-| 6.x     | Latest      | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes   |
+| Version | Status     | Packagist           | Namespace    | Repo                | Docs                | PSR-7 | PHP Version |
+|---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------|
+| 3.x     | EOL        | `guzzle/guzzle`     | `Guzzle`     | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No    | >= 5.3.3    |
+| 4.x     | EOL        | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A                 | No    | >= 5.4      |
+| 5.x     | Maintained | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No    | >= 5.4      |
+| 6.x     | Latest     | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes   | >= 5.5      |
 
 [guzzle-3-repo]: https://github.com/guzzle/guzzle3
+[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x
 [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3
 [guzzle-6-repo]: https://github.com/guzzle/guzzle
 [guzzle-3-docs]: http://guzzle3.readthedocs.org/en/latest/

+ 4 - 1
vendor/guzzlehttp/guzzle/composer.json

@@ -19,7 +19,7 @@
     },
     "require-dev": {
         "ext-curl": "*",
-        "phpunit/phpunit": "^4.0",
+        "phpunit/phpunit": "^4.0 || ^5.0",
         "psr/log": "^1.0"
     },
     "autoload": {
@@ -33,6 +33,9 @@
             "GuzzleHttp\\Tests\\": "tests/"
         }
     },
+    "suggest": {
+        "psr/log": "Required for using the Log middleware"
+    },
     "extra": {
         "branch-alias": {
             "dev-master": "6.2-dev"

+ 7 - 1
vendor/guzzlehttp/guzzle/src/Client.php

@@ -63,6 +63,8 @@ class Client implements ClientInterface
     {
         if (!isset($config['handler'])) {
             $config['handler'] = HandlerStack::create();
+        } elseif (!is_callable($config['handler'])) {
+            throw new \InvalidArgumentException('handler must be a callable');
         }
 
         // Convert the base_uri to a UriInterface
@@ -350,6 +352,10 @@ class Client implements ClientInterface
                     $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
                     $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
                     break;
+                case 'ntlm':
+                    $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
+                    $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
+                    break;
             }
         }
 
@@ -402,7 +408,7 @@ class Client implements ClientInterface
         throw new \InvalidArgumentException('Passing in the "body" request '
             . 'option as an array to send a POST request has been deprecated. '
             . 'Please use the "form_params" request option to send a '
-            . 'application/x-www-form-urlencoded request, or a the "multipart" '
+            . 'application/x-www-form-urlencoded request, or the "multipart" '
             . 'request option to send a multipart/form-data request.');
     }
 }

+ 49 - 0
vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php

@@ -86,6 +86,25 @@ class CookieJar implements CookieJarInterface
         return false;
     }
 
+    /**
+     * Finds and returns the cookie based on the name
+     *
+     * @param string $name cookie name to search for
+     * @return SetCookie|null cookie that was found or null if not found
+     */
+    public function getCookieByName($name)
+    {
+        // don't allow a null name
+        if($name === null) {
+            return null;
+        }
+        foreach($this->cookies as $cookie) {
+            if($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) {
+                return $cookie;
+            }
+        }
+    }
+
     public function toArray()
     {
         return array_map(function (SetCookie $cookie) {
@@ -216,11 +235,41 @@ class CookieJar implements CookieJarInterface
                 if (!$sc->getDomain()) {
                     $sc->setDomain($request->getUri()->getHost());
                 }
+                if (0 !== strpos($sc->getPath(), '/')) {
+                    $sc->setPath($this->getCookiePathFromRequest($request));
+                }
                 $this->setCookie($sc);
             }
         }
     }
 
+    /**
+     * Computes cookie path following RFC 6265 section 5.1.4
+     *
+     * @link https://tools.ietf.org/html/rfc6265#section-5.1.4
+     *
+     * @param RequestInterface $request
+     * @return string
+     */
+    private function getCookiePathFromRequest(RequestInterface $request)
+    {
+        $uriPath = $request->getUri()->getPath();
+        if (''  === $uriPath) {
+            return '/';
+        }
+        if (0 !== strpos($uriPath, '/')) {
+            return '/';
+        }
+        if ('/' === $uriPath) {
+            return '/';
+        }
+        if (0 === $lastSlashPos = strrpos($uriPath, '/')) {
+            return '/';
+        }
+
+        return substr($uriPath, 0, $lastSlashPos);
+    }
+
     public function withCookieHeader(RequestInterface $request)
     {
         $values = [];

+ 21 - 1
vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php

@@ -1,7 +1,27 @@
 <?php
 namespace GuzzleHttp\Exception;
 
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
 /**
  * Exception when an HTTP error occurs (4xx or 5xx error)
  */
-class BadResponseException extends RequestException {}
+class BadResponseException extends RequestException
+{
+    public function __construct(
+        $message,
+        RequestInterface $request,
+        ResponseInterface $response = null,
+        \Exception $previous = null,
+        array $handlerContext = []
+    ) {
+        if (null === $response) {
+            @trigger_error(
+                'Instantiating the ' . __CLASS__ . ' class without a Response is deprecated since version 6.3 and will be removed in 7.0.',
+                E_USER_DEPRECATED
+            );
+        }
+        parent::__construct($message, $request, $response, $previous, $handlerContext);
+    }
+}

+ 13 - 6
vendor/guzzlehttp/guzzle/src/Exception/RequestException.php

@@ -81,10 +81,10 @@ class RequestException extends TransferException
         $level = (int) floor($response->getStatusCode() / 100);
         if ($level === 4) {
             $label = 'Client error';
-            $className = __NAMESPACE__ . '\\ClientException';
+            $className = ClientException::class;
         } elseif ($level === 5) {
             $label = 'Server error';
-            $className = __NAMESPACE__ . '\\ServerException';
+            $className = ServerException::class;
         } else {
             $label = 'Unsuccessful request';
             $className = __CLASS__;
@@ -93,13 +93,15 @@ class RequestException extends TransferException
         $uri = $request->getUri();
         $uri = static::obfuscateUri($uri);
 
-        // Server Error: `GET /` resulted in a `404 Not Found` response:
+        // Client Error: `GET /` resulted in a `404 Not Found` response:
         // <html> ... (truncated)
         $message = sprintf(
-            '%s: `%s` resulted in a `%s` response',
+            '%s: `%s %s` resulted in a `%s %s` response',
             $label,
-            $request->getMethod() . ' ' . $uri,
-            $response->getStatusCode() . ' ' . $response->getReasonPhrase()
+            $request->getMethod(),
+            $uri,
+            $response->getStatusCode(),
+            $response->getReasonPhrase()
         );
 
         $summary = static::getResponseBodySummary($response);
@@ -129,6 +131,11 @@ class RequestException extends TransferException
         }
 
         $size = $body->getSize();
+
+        if ($size === 0) {
+            return null;
+        }
+
         $summary = $body->read(120);
         $body->rewind();
 

+ 28 - 5
vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php

@@ -16,7 +16,7 @@ use Psr\Http\Message\RequestInterface;
 class CurlFactory implements CurlFactoryInterface
 {
     /** @var array */
-    private $handles;
+    private $handles = [];
 
     /** @var int Total number of idle handles to keep in cache */
     private $maxHandles;
@@ -163,7 +163,7 @@ class CurlFactory implements CurlFactoryInterface
         // If an exception was encountered during the onHeaders event, then
         // return a rejected promise that wraps that exception.
         if ($easy->onHeadersException) {
-            return new RejectedPromise(
+            return \GuzzleHttp\Promise\rejection_for(
                 new RequestException(
                     'An error was encountered during the on_headers event',
                     $easy->request,
@@ -186,7 +186,7 @@ class CurlFactory implements CurlFactoryInterface
             ? new ConnectException($message, $easy->request, null, $ctx)
             : new RequestException($message, $easy->request, $easy->response, null, $ctx);
 
-        return new RejectedPromise($error);
+        return \GuzzleHttp\Promise\rejection_for($error);
     }
 
     private function getDefaultConf(EasyHandle $easy)
@@ -326,12 +326,20 @@ class CurlFactory implements CurlFactoryInterface
                 $conf[CURLOPT_SSL_VERIFYHOST] = 2;
                 $conf[CURLOPT_SSL_VERIFYPEER] = true;
                 if (is_string($options['verify'])) {
-                    $conf[CURLOPT_CAINFO] = $options['verify'];
+                    // Throw an error if the file/folder/link path is not valid or doesn't exist.
                     if (!file_exists($options['verify'])) {
                         throw new \InvalidArgumentException(
                             "SSL CA bundle not found: {$options['verify']}"
                         );
                     }
+                    // If it's a directory or a link to a directory use CURLOPT_CAPATH.
+                    // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
+                    if (is_dir($options['verify']) ||
+                        (is_link($options['verify']) && is_dir(readlink($options['verify'])))) {
+                        $conf[CURLOPT_CAPATH] = $options['verify'];
+                    } else {
+                        $conf[CURLOPT_CAINFO] = $options['verify'];
+                    }
                 }
             }
         }
@@ -370,15 +378,30 @@ class CurlFactory implements CurlFactoryInterface
             $conf[CURLOPT_FILE] = fopen('php://temp', 'w+');
             $easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]);
         }
-
+        $timeoutRequiresNoSignal = false;
         if (isset($options['timeout'])) {
+            $timeoutRequiresNoSignal |= $options['timeout'] < 1;
             $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
         }
 
+        // CURL default value is CURL_IPRESOLVE_WHATEVER
+        if (isset($options['force_ip_resolve'])) {
+            if ('v4' === $options['force_ip_resolve']) {
+                $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;
+            } else if ('v6' === $options['force_ip_resolve']) {
+                $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6;
+            }
+        }
+
         if (isset($options['connect_timeout'])) {
+            $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
             $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
         }
 
+        if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
+            $conf[CURLOPT_NOSIGNAL] = true;
+        }
+
         if (isset($options['proxy'])) {
             if (!is_array($options['proxy'])) {
                 $conf[CURLOPT_PROXY] = $options['proxy'];

+ 17 - 4
vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php

@@ -1,6 +1,7 @@
 <?php
 namespace GuzzleHttp\Handler;
 
+use GuzzleHttp\Exception\RequestException;
 use GuzzleHttp\HandlerStack;
 use GuzzleHttp\Promise\PromiseInterface;
 use GuzzleHttp\Promise\RejectedPromise;
@@ -13,7 +14,7 @@ use Psr\Http\Message\ResponseInterface;
  */
 class MockHandler implements \Countable
 {
-    private $queue;
+    private $queue = [];
     private $lastRequest;
     private $lastOptions;
     private $onFulfilled;
@@ -73,12 +74,24 @@ class MockHandler implements \Countable
         $this->lastOptions = $options;
         $response = array_shift($this->queue);
 
+        if (isset($options['on_headers'])) {
+            if (!is_callable($options['on_headers'])) {
+                throw new \InvalidArgumentException('on_headers must be callable');
+            }
+            try {
+                $options['on_headers']($response);
+            } catch (\Exception $e) {
+                $msg = 'An error was encountered during the on_headers event';
+                $response = new RequestException($msg, $request, $response, $e);
+            }
+        }
+
         if (is_callable($response)) {
             $response = call_user_func($response, $request, $options);
         }
 
         $response = $response instanceof \Exception
-            ? new RejectedPromise($response)
+            ? \GuzzleHttp\Promise\rejection_for($response)
             : \GuzzleHttp\Promise\promise_for($response);
 
         return $response->then(
@@ -107,7 +120,7 @@ class MockHandler implements \Countable
                 if ($this->onRejected) {
                     call_user_func($this->onRejected, $reason);
                 }
-                return new RejectedPromise($reason);
+                return \GuzzleHttp\Promise\rejection_for($reason);
             }
         );
     }
@@ -145,7 +158,7 @@ class MockHandler implements \Countable
     /**
      * Get the last received request options.
      *
-     * @return RequestInterface
+     * @return array
      */
     public function getLastOptions()
     {

+ 47 - 4
vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php

@@ -67,7 +67,7 @@ class StreamHandler
             $e = RequestException::wrapException($request, $e);
             $this->invokeStats($options, $request, $startTime, null, $e);
 
-            return new RejectedPromise($e);
+            return \GuzzleHttp\Promise\rejection_for($e);
         }
     }
 
@@ -119,7 +119,7 @@ class StreamHandler
             } catch (\Exception $e) {
                 $msg = 'An error was encountered during the on_headers event';
                 $ex = new RequestException($msg, $request, $response, $e);
-                return new RejectedPromise($ex);
+                return \GuzzleHttp\Promise\rejection_for($ex);
             }
         }
 
@@ -301,6 +301,18 @@ class StreamHandler
             );
         }
 
+        // Microsoft NTLM authentication only supported with curl handler
+        if (isset($options['auth'])
+            && is_array($options['auth'])
+            && isset($options['auth'][2])
+            && 'ntlm' == $options['auth'][2]
+        ) {
+
+            throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
+        }
+
+        $uri = $this->resolveHost($request, $options);
+
         $context = $this->createResource(
             function () use ($context, $params) {
                 return stream_context_create($context, $params);
@@ -308,14 +320,45 @@ class StreamHandler
         );
 
         return $this->createResource(
-            function () use ($request, &$http_response_header, $context) {
-                $resource = fopen((string) $request->getUri()->withFragment(''), 'r', null, $context);
+            function () use ($uri, &$http_response_header, $context, $options) {
+                $resource = fopen((string) $uri, 'r', null, $context);
                 $this->lastHeaders = $http_response_header;
+
+                if (isset($options['read_timeout'])) {
+                    $readTimeout = $options['read_timeout'];
+                    $sec = (int) $readTimeout;
+                    $usec = ($readTimeout - $sec) * 100000;
+                    stream_set_timeout($resource, $sec, $usec);
+                }
+
                 return $resource;
             }
         );
     }
 
+    private function resolveHost(RequestInterface $request, array $options)
+    {
+        $uri = $request->getUri();
+
+        if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) {
+            if ('v4' === $options['force_ip_resolve']) {
+                $records = dns_get_record($uri->getHost(), DNS_A);
+                if (!isset($records[0]['ip'])) {
+                    throw new ConnectException(sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
+                }
+                $uri = $uri->withHost($records[0]['ip']);
+            } elseif ('v6' === $options['force_ip_resolve']) {
+                $records = dns_get_record($uri->getHost(), DNS_AAAA);
+                if (!isset($records[0]['ipv6'])) {
+                    throw new ConnectException(sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
+                }
+                $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']');
+            }
+        }
+
+        return $uri;
+    }
+
     private function getDefaultContext(RequestInterface $request)
     {
         $headers = '';

+ 1 - 1
vendor/guzzlehttp/guzzle/src/Middleware.php

@@ -102,7 +102,7 @@ final class Middleware
                             'error'    => $reason,
                             'options'  => $options
                         ];
-                        return new RejectedPromise($reason);
+                        return \GuzzleHttp\Promise\rejection_for($reason);
                     }
                 );
             };

+ 2 - 8
vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php

@@ -14,9 +14,6 @@ class PrepareBodyMiddleware
     /** @var callable  */
     private $nextHandler;
 
-    /** @var array */
-    private static $skipMethods = ['GET' => true, 'HEAD' => true];
-
     /**
      * @param callable $nextHandler Next handler to invoke.
      */
@@ -36,9 +33,7 @@ class PrepareBodyMiddleware
         $fn = $this->nextHandler;
 
         // Don't do anything if the request has no body.
-        if (isset(self::$skipMethods[$request->getMethod()])
-            || $request->getBody()->getSize() === 0
-        ) {
+        if ($request->getBody()->getSize() === 0) {
             return $fn($request, $options);
         }
 
@@ -54,8 +49,7 @@ class PrepareBodyMiddleware
         }
 
         // Add a default content-length or transfer-encoding header.
-        if (!isset(self::$skipMethods[$request->getMethod()])
-            && !$request->hasHeader('Content-Length')
+        if (!$request->hasHeader('Content-Length')
             && !$request->hasHeader('Transfer-Encoding')
         ) {
             $size = $request->getBody()->getSize();

+ 12 - 6
vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php

@@ -19,6 +19,8 @@ class RedirectMiddleware
 {
     const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
 
+    const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
+
     public static $defaultSettings = [
         'max'             => 5,
         'protocols'       => ['http', 'https'],
@@ -108,23 +110,27 @@ class RedirectMiddleware
         if (!empty($options['allow_redirects']['track_redirects'])) {
             return $this->withTracking(
                 $promise,
-                (string) $nextRequest->getUri()
+                (string) $nextRequest->getUri(),
+                $response->getStatusCode()
             );
         }
 
         return $promise;
     }
 
-    private function withTracking(PromiseInterface $promise, $uri)
+    private function withTracking(PromiseInterface $promise, $uri, $statusCode)
     {
         return $promise->then(
-            function (ResponseInterface $response) use ($uri) {
+            function (ResponseInterface $response) use ($uri, $statusCode) {
                 // Note that we are pushing to the front of the list as this
                 // would be an earlier response than what is currently present
                 // in the history header.
-                $header = $response->getHeader(self::HISTORY_HEADER);
-                array_unshift($header, $uri);
-                return $response->withHeader(self::HISTORY_HEADER, $header);
+                $historyHeader = $response->getHeader(self::HISTORY_HEADER);
+                $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
+                array_unshift($historyHeader, $uri);
+                array_unshift($statusHeader, $statusCode);
+                return $response->withHeader(self::HISTORY_HEADER, $historyHeader)
+                                ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
             }
         );
     }

+ 11 - 0
vendor/guzzlehttp/guzzle/src/RequestOptions.php

@@ -237,8 +237,19 @@ final class RequestOptions
      */
     const TIMEOUT = 'timeout';
 
+    /**
+     * read_timeout: (float, default=default_socket_timeout ini setting) Float describing
+     * the body read timeout, for stream requests.
+     */
+    const READ_TIMEOUT = 'read_timeout';
+
     /**
      * version: (float) Specifies the HTTP protocol version to attempt to use.
      */
     const VERSION = 'version';
+
+    /**
+     * force_ip_resolve: (bool) Force client to use only ipv4 or ipv6 protocol
+     */
+    const FORCE_IP_RESOLVE = 'force_ip_resolve';
 }

+ 1 - 1
vendor/guzzlehttp/guzzle/src/RetryMiddleware.php

@@ -97,7 +97,7 @@ class RetryMiddleware
                 null,
                 $reason
             )) {
-                return new RejectedPromise($reason);
+                return \GuzzleHttp\Promise\rejection_for($reason);
             }
             return $this->doRetry($req, $options);
         };

+ 2 - 0
vendor/guzzlehttp/guzzle/src/functions.php

@@ -167,6 +167,8 @@ function default_ca_bundle()
         '/etc/ssl/certs/ca-certificates.crt',
         // FreeBSD (provided by the ca_root_nss package)
         '/usr/local/share/certs/ca-root-nss.crt',
+        // SLES 12 (provided by the ca-certificates package)
+        '/var/lib/ca-certificates/ca-bundle.pem',
         // OS X provided by homebrew (using the default path)
         '/usr/local/etc/openssl/cert.pem',
         // Google app engine