Jump to content

fastsol

Moderators
  • Posts

    827
  • Joined

  • Last visited

  • Days Won

    9

Everything posted by fastsol

  1. That would be an issue with your php installation then. https://www.google.com/search?q=Call+to+undefined+function%3A+json_decode%28%29&ie=utf-8&oe=utf-8
  2. You didn't call the function, you only defined it. Based on how it looks like you want to validate the captcha, do this instead. <?php function validCaptchaV2() { $secret_key = 'my_private_key_goes_here'; $resp = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret_key."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']); $answer = json_decode($resp); return $answer->success; } $firstname = $_POST['firstname']; $surname = $_POST['surname']; $emailaddress = $_POST['emailaddress']; $telephone = $_POST['telephone']; $enquiry = $_POST['enquiry']; $body = "First Name: $firstname \n Surname: $surname \n Telephone Number: $telephone \nMessage: $enquiry"; // if CAPTCHA is entered incorrectly if(validCaptchaV2() === FALSE) { header('Location: captcha_unsuccessful.html'); exit; } else { // If CAPTCHA is valid $emailSubject = 'Customer Enquiry'; $webMaster = 'my_email_goes_here';
  3. The variables on this line won't fire cause you have them inside 'single quotes'. $response = sendSMS('textmarketerusername', 'textmarketerpassword', '{$mobnumber}', '{$row["description"]} expiry date: {$row["datedue"]}', '{$row["description"]} expiry date: {$row["datedue"]}');
  4. The way you check the captcha value is different in the V2. Here is a simplified version of a function I use to validate the captcha function validCaptchaV2() { $secret_key = 'Your secret key'; $resp = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret_key."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']); $answer = json_decode($resp); if($answer->success === FALSE) { //Do whatever logic you want for the error here //Errors::set("The Captcha did not pass validation. Please try again."); return FALSE; } else{ return TRUE; } }
  5. Here is a pretty good tutorial on how to use the new api https://www.youtube.com/watch?v=BD1dOWIABe0
  6. Yes I suppose the if($this->client) is redundant since the class is already type hinting for such a client. I did know about the require_once issue too, not really sure why at the time I put in the class rather than the global system. Thanks for the insights.
  7. Yeah, I understand those apsects. The Config class is static mainly cause it's just used to get values from a certain array of values across the entire system. It makes it easier and faster to check certain vars by not having to use isset first and then check it's value, cause the class does all that for you. And yes I suppose it could have been made non-static but then I had to deal with scope and I just wanted a easier way around certain things. I fully understand scope and how the DI takes care of it. Beyond that stuff, are the classes decent? I know they're small so they can't be too bad and it's not like I don't know what I'm doing with php, just not totally with class methodology.
  8. I actually have a reminder in my phone calendar each month to go in and sync the server time. I ran into an error using the Google API that it wouldn't let the AUTH happen cause the time my server was returning was too far off from what they expected, so it wouldn't authorize the api call. As soon as I synced the time, the api loaded just fine again.
  9. Well I've decided to abandon this project for now. I need to learn too much to make it right and I don't have the time right now. Hopefully next spring I can rebuild the entire site in a solid framework and all will be well. But for now, I do have a couple small classes that I would like an opinion on how to improve. They are for connecting to and using the Google Calendar API. One class handles the connecting and the other makes the calls. I know for sure that one class is totally dependent on another static class in my system and I understand that that is wrong. I understand the concept of dependency injection but find the overall concept of throwing classes around to inject isn't good either. I'm sure that a solid framework solves those issues, but for now this is what I have to work with. So guidance would be greatly appreciated, examples speak louder GoogleAuth class <?php class GoogleAuth { protected $client; public function __construct(Google_Client $googleClient) { $this->client = $googleClient; if($this->client) { $this->client->setApplicationName(Config::get('cal_cred/cal_project_name')); $this->client->setAccessType("offline"); /*if (!empty($_SESSION['service_token'])) { $this->client->setAccessToken($_SESSION['service_token']); }*/ $cred = new Google_Auth_AssertionCredentials( Config::get('cal_cred/cal_email_address'), Config::get('cal_cred/cal_scopes'), file_get_contents(Config::get('cal_cred/cal_p12_file')) ); $this->client->setAssertionCredentials($cred); //diagDiv($this->client); if($this->client->getAuth()->isAccessTokenExpired()) { $this->client->getAuth()->refreshTokenWithAssertion($cred); } //$_SESSION['service_token'] = $this->client->getAccessToken(); } } } ?> GoogleCalendar class <?php class GoogleCalendar { protected $setup; protected $event_params; protected $cal_event; protected $createdEvent; protected $gsc; protected $auth; protected $cal; protected $lastInsertId; protected $deletedEvent; protected $updatedEvent; protected $error; public function __construct() { require_once(ROOT.'site_specific/other_pages/Google/autoload.php'); $this->client = new Google_Client; $this->auth = new GoogleAuth($this->client); $this->gsc = new Google_Service_Calendar($this->client); } // Must provide: desc, start and end elements. location is an optional element. // start and end must be in this format 2015-06-04T11:30:00 public function event_params(array $params) { $this->event_params = $params; return $this; } public function calendarEvent() { $this->cal_event = ''; $this->cal_event = new Google_Service_Calendar_Event(); $this->cal_event->setSummary($this->event_params['desc']); (!empty($this->event_params['location'])) ? $this->cal_event->setLocation($this->event_params['location']) : ''; $start = new Google_Service_Calendar_EventDateTime(); $start->setTimeZone(Config::get('cal_cred/cal_timezone')); $start->setDateTime($this->event_params['start']); $this->cal_event->setStart($start); $end = new Google_Service_Calendar_EventDateTime(); $end->setTimeZone(Config::get('cal_cred/cal_timezone')); $end->setDateTime($this->event_params['end']); $this->cal_event->setEnd($end); return $this; } public function insert_event() { try { $this->createdEvent = $this->gsc->events->insert(Config::get('cal_cred/cal_name'), $this->cal_event); $this->lastInsertId = $this->createdEvent->getId(); } catch(Google_Service_Exception $e) { $this->error = $e; } return $this; } public function update_event($event_id) { try { $this->updatedEvent = $this->gsc->events->update(Config::get('cal_cred/cal_name'), $event_id, $this->cal_event); } catch(Google_Service_Exception $e) { $this->error = $e; } return $this; } public function quickAdd_event($info) { try { $this->quickAddEvent = $this->gsc->events->quickAdd(Config::get('cal_cred/cal_name'), $info); $this->lastInsertId = $this->quickAddEvent->getId(); } catch(Google_Service_Exception $e) { $this->error = $e; } return $this; } public function delete_event($event_id) { try { $this->deletedEvent = $this->gsc->events->delete(Config::get('cal_cred/cal_name'), $event_id); } catch(Google_Service_Exception $e) { $this->error = $e; } return $this; } public function lastInsertId() { return $this->lastInsertId; } public function error() { return $this->error; } public function getItemById($id) { return $this->gsc->events->get(Config::get('cal_cred/cal_name'), $id); } } ?> This is how I would typically use these classes if(Config::get('use_gcal') === TRUE) { $gc = new GoogleCalendar; $event = $gc->getItemById($google_id); $time_format = "Y-m-d\TH:i:s"; $stime = date($time_format, $post_time); $etime = date($time_format, strtotime("+2 hours", $post_time)); $google_params = [ 'desc' => $event->summary, 'location' => html_entity_decode(Config::get('waiting_spot_options/'.$wait_id), ENT_QUOTES), 'start' => $stime, 'end' => $etime ]; $gc->event_params($google_params); $gc->calendarEvent(); $gc->update_event($google_id); }
  10. I've been battling this all day and haven't gotten nearly as far as I had hoped. I've made many new class pages and broken out many aspects, but I still can't get the flow down in my head. That processquote() does so much and it needs to do it in a certain order that I can't figure out how to break it apart without literally breaking it.
  11. Ahh, now I see the potential maxxd. As much as I'd love to integrate my cms into a far superior MVC type thing, it would be mind boggling hard and time consuming. It was built in procedural with tons of features and tons of files that would need complete recoding. So I'll just have to make it work in sections that are important to make easier to upgrade, like my quote system.
  12. I think I understand what you're getting at, but it doesn't seem to really solve a problem if you have to always do a method_exists or function_exists check every time you want to use the dynamic made function. Might as well just do it the way I am with still less code, unless I'm not understanding fully.
  13. I've watched some videos and read some things and I think I have a grasp as to what to do with the validation part of the processquote(). I also think I understand what I can do with the bottom part of the function to, but the middle area where I do a number of queries and some other logic I can't seem to grasp how to break that out into other classes or methods. Could anyone just give me a quick concept of how you would possibly break out this part of the code. I totally understand that it won't be anything real accurate, I'm just looking for an example of logic behind it. $now = time(); $units_text = "Prices include all parts and labor:\r\n".$email_units; $where = ''; $date_sent = ''; $date_modified = NULL; // INSERT/UPDATE QUOTE_RESPONSES $params = [ 'request_id' => [$q_id, 'INT'], 'date_modified' => NULL, 'body' => $ebody, 'code' => $code, 'notes' => $notes, 'unit_pricing' => $units_text ]; if($i->get('action') == "add") { $params['code'] = randomCode(20); $code = $params['code']; $set = $this->db->insert(QUOTE_RESPONSES, $params); } elseif($i->get('action') == "edit") { $params['date_modified'] = date("Y-m-d H:i:s"); $set = $this->db->update(QUOTE_RESPONSES, $params, '`id` = '.$resp_id, 1); } $last_id = ($i->get('action') == "add") ? $set->lastInsertId() : $resp_id; ///////////// END /////////////////////////////////// // UPDATE REFERRALS if($i->get('action') == "add") { (new QuoteReferral)->setQuoteId($last_id, $q_id); } //////////// END ////////////////////// // Clear QUOTE_ITEMS if($i->get('action') == "edit") { $qi->deleteQuoteItems($resp_id); } /////////// END ////////////////////// // UPDATE QUOTE_REQUESTS with posted vehicle info. $params = [ 'vehicle_make_id' => [$make_id, 'INT'], 'vehicle_model_id' => [$model_id, 'INT'], 'vehicle_year_id' => [$year, 'INT'], 'vehicle_sufix' => $car_sufix ]; (new QuoteRequest)->updateById($params, $q_id); ///////// END ////////////////////////////////////////// // SET new QUOTE_ITEMS foreach($unit as $key => $val) { $params = []; if(!empty($val['price'])) { $note = (!empty($val['note'])) ? sanitize($val['note']) : ''; $unit_price = addSalesTax($val['price'], Config::get('tax_rate')); $add_amt = ($val['on_sale'] == TRUE) ? (int)$val['price'] - (int)$val['sale_price'] : (int)$val['price'] - (int)$val['original_price']; $params = [ 'item' => $key, 'quote_price' => [$val['price'], 'INT'], 'response_id' => [$last_id, 'INT'], 'product_id' => [$val['product_id'], 'INT'], 'item_note' => $note, 'add_amt' => [$add_amt, 'INT'] ]; $qi->insertQuoteItems($params); } } ////////// END /////////////////////////////// if($i->get('action') == "add") { $link_url = 'http://remotelystartedmn.com/quotes.php?quote-id='.$last_id.'&c='.$code.'&direct'; $email_link_url = $link_url.'&e=1'; $set = $this->db->update(QUOTE_RESPONSES, [/*'signature' => $signature, */'quote_link' => $email_link_url], '`id`= '.$last_id); $qid = $i->get('quote-id', '', 'int'); (new QuoteRequest)->updateResponseType($qid);
  14. Thank you. I watched the video and will do plenty of research and playing to see what I can come up with.
  15. I fully agree citypaul. There is a tremendous amount of code that is intertwined. Much of this was written a few years ago while I was still learning mainstream php and have adapted it to better and better practices over the time, but I have always known that it's far from perfect. I fully understand this is procedural code, especially since I literally took a bunch of functions and placed them into a class, simply to try and organize them and maybe it would have just been better to make more organized function pages than classes that aren't really classes. I really really want to improve this code as I expect to expand it immensely in the future and I want it to be easier and more efficient when doing so. I believe I have the ability to make this better, but I think my main struggle in figuring out how to break this apart is dealing with the validation and then building the output desired without passing a ton of things back and forth amongst several classes that again probably don't have anything to do with each other. If I could get even a basic example based on my code of how to break it apart, that would likely help a ton.
  16. Sure. It gets called after submitting a form with in the admin area. I will only post the relevant code, the rest of the code just contains the setup of the form. if(Input::noVal('quote-id|g') && Input::noVal('response-id|g')) { redirect(Config::get('admin_redirect_page')); } elseif(Input::exists('submit|p') && Input::exists('action|g') && in_array(Input::val('action|g'), array("add", "edit"))) { $results = $qResponse->processQuote(); } elseif(Input::exists('quote-id|g') && Input::val('action|g') == "add") {$results = $qRequest->selectQuoteRequest()->results();} elseif(Input::exists('response-id|g') && Input::val('action|g') == "edit") {$results = $qResponse->selectResponse(Input::val('response-id|g'), TRUE);} $check_num = ''; if(Input::noVal('response-id|g') && Input::notExists('submit|p')) { $check = DB::getInstance()->query("SELECT `id` FROM `".QUOTE_RESPONSES."` WHERE `request_id` = ".(int)Input::val('quote-id|g')); if($check_num = $check->rowCount() > 0) { echo formComplete('A Quote has already been made for this request.', TRUE); } } if(!empty($results) && empty($check_num)) { The page that holds this code is not in a class, it's just an admin area viewing/posting page. This is the whole page, just in case you want more, but the code above is where the processquote() is. This code is an include file with in a wrapped admin area. So whatever happens on this page will display or happen within a predefined div within the page, so it can't/won't effect the rest of the admin area, like menus or manipulation of the page around it. <?php if(!defined('body_id')){ header("Location: /404.php"); exit; } $qRequest = new QuoteRequest; $qResponse = new QuoteResponse; /*if(Input::exists('update|p')) { $qRequest->changeResponseType(QUOTE_REQUESTS); echo formComplete("Emailed Updated", TRUE); } else*/if(empty(Input::super('post')) && Input::notExists('action|g')) { $results = $qRequest->allQuoteRequests($start)->results(); if(!empty($results)) {nexPrevStandardAdmin(end($results), Config::get('quote_requests_per_page'));} ?> <form action="" method="post"> <!--<div class="right"><?php //if(!empty($results)){echo '<input name="update" type="submit" value="Update Emailed" />';} ?></div>--> <table id="admin_table" cellpadding="4" class="admin-tbl"> <tr> <?php $th = array("Name", "Vehicle", "Date", "ID#", "Read", "Actions"); echo adminThList($th); ?> </tr> <?php if(empty($results)){} else { foreach($results as $r) { //print_r($r); if(!is_array($r)){} else { $already_quoted=''; $has_read=''; $name = (empty($r['response'])) ? '<span style="color: #FF0000">'.$r['name'].'</span>' : $r['name']; /*if(empty($r['response_id']) && $r['already_quoted'] > 0) { $already_quoted = 'style="background: yellow"'; }*/ if($r['email'] == Config::get('no_email')) { $has_read = NO_EMAIL_ICON; } elseif($r['viewed_by_email'] == FALSE && $r['viewed_by_txt'] == FALSE && $r['read_quote'] == TRUE) { $has_read = CHECK_MARK; } elseif($r['viewed_by_email'] == FALSE && $r['viewed_by_txt'] == FALSE && $r['read_quote'] == FALSE && empty($r['response_id'])) {} elseif($r['viewed_by_email'] == FALSE && $r['viewed_by_txt'] == FALSE && $r['read_quote'] == FALSE) { $has_read = RED_X; } else { $has_read .= ($r['viewed_by_email'] == TRUE) ? ENVELOPE_ICON : ''; $has_read .= ($r['viewed_by_txt'] == TRUE) ? SMS_ICON : ''; } $icon_spacing = ' '; // Used to mark quotes are emailed, keeping just in case need it later. //<input type="checkbox" name="iemailed['.$r['id'].']" value="'.$r['id'].'"> echo '<tr> <td style="max-width:150px">'.adminLinks('qsearch', 'tbl_field=Name&srch=Search&searched='.$r['name'], '', $name).'</td> <td '.$already_quoted.'>'.adminLinks('qsearch', 'tbl_field=Vehicle&srch=Search&searched='.$r['actual_vehicle'], '', $r['actual_vehicle']).'</td> <td class="center">', date("m-d-y", $r['date_sent']), '</td> <td class="center">', (!empty($r['response_id'])) ? adminLinks('sresponse', 'quote-id='.$r['response_id'], 'view', $r['response_id']) : '', (!empty($r['response_id']) && $r['quote_active'] == FALSE) ? '<br>'.RED_X : '', '</td> <td class="center">'.$has_read.'</td> <td class="center icon-spacing">', (empty($r['response_id']) && $r['response'] != "Emailed") ? '' : (($r['response'] == "Emailed") ? EMAILED_ICON : ''), (empty($r['response_id'])) ? adminLinks('', 'quote-id='.$r['id'], 'add', ADD_QUOTE_ICON) : '' /*adminLinks('', 'quote-id='.$r['id'], 'view', Q_INFO_ICON)*/, (!empty($r['response_id']) && empty($r['deposit_id'])) ? adminLinks('', 'response-id='.$r['response_id'], 'edit', UPDATE_Q_ICON) : '', (!empty($r['response_id']) && empty($r['deposit_id'])) ? adminLinks('sdeposit', 'quote-id='.$r['response_id'], 'add', DEPOSIT_ICON) : ((!empty($r['deposit_id'])) ? DEPOSIT_MADE_ICON : ''), (empty($r['response_id'])) ? adminLinks('', 'quote-id='.$r['id'], 'delete', GARBAGE): '', '</td>'; echo adminExtendedDisplay($r); echo '</tr>'; } } } ?> </table> </form> <?php } elseif(Input::val('action|g') == "view") { $results = $qRequest->selectQuoteRequest()->results(); $nodisplay = array('id', 'response', 'date_sent', 'signature', 'read_quote', 'purchased', 'body', 'notes', 'unit_pricing', 'code', 'request_id', 'vehicle_make_id', 'vehicle_model_id' , 'vehicle_year_id'); $html=''; foreach($results as $key => $val) { if(!in_array($key, $nodisplay)) { if($key == "city" && !empty($val)) { $html .= ucwords($key).' = '.getCityNameAndState($val).'<br>'; } elseif($key == "key_id" && !empty($val)) { $img_loc_string = getKeyImages($val); $html .= '<img src="'.IMAGE_LAY_SITE.$img_loc_string[0]['image'].'"><br>'; } elseif($key == "options") { $html .= nl2br(ucwords($val)); } else { if($val == "Push To Start"){ $val = '<span class="bold">'.$val.'</span>'; } elseif($val == "Manual"){ $val = '<span class="bold">'.$val.'</span>'; } elseif($val == "Turn A Knob"){ $val = '<span class="bold">'.$val.'</span>'; } $html .= ucwords($key).' = '.$val.'<br>'; } } } echo '<h1>Original Request</h1>'.$html; } elseif(Input::val('action|g') == "delete") { if(Input::exists('delete|p')) { if($qRequest->deleteRequest() === TRUE) {echo formComplete("Quote Request Deleted", TRUE);} } elseif(Input::exists('quote-id|g')) { $results = $qRequest->selectQuoteRequest()->results(); $form_fields = array( array("tag" => array("function", "class=\"bold\""), "text" => "name:", "name" => "name", "class_fields" => FALSE, "type" => "text", "required" => FALSE, "value_results_name" => "name", "admin_notes" => FALSE, "options" => array(), "function" => $results['name'] ), array("tag" => array("function", "class=\"bold\""), "text" => "vehicle:", "name" => "vehicle", "class_fields" => FALSE, "type" => "text", "required" => FALSE, "value_results_name" => "vehicle", "admin_notes" => FALSE, "options" => array(), "function" => $results['actual vehicle'] ), array("tag" => array("function", "class=\"bold\""), "text" => "date sent:", "name" => "date_sent", "class_fields" => FALSE, "type" => "text", "required" => FALSE, "value_results_name" => "date_sent", "admin_notes" => FALSE, "options" => array(), "function" => date("m-d-Y", $results['date_sent']) ), "form_button" => array("name" => "delete", "type" => "submit", "value" => "delete", "attributes" => "") ); adminForm($form_fields, (isset($results)) ? $results: ''); } } else { if(Input::noVal('quote-id|g') && Input::noVal('response-id|g')) { redirect(Config::get('admin_redirect_page')); } elseif(Input::exists('submit|p') && Input::exists('action|g') && in_array(Input::val('action|g'), array("add", "edit"))) { $results = $qResponse->processQuote(); } elseif(Input::exists('quote-id|g') && Input::val('action|g') == "add") {$results = $qRequest->selectQuoteRequest()->results();} elseif(Input::exists('response-id|g') && Input::val('action|g') == "edit") {$results = $qResponse->selectResponse(Input::val('response-id|g'), TRUE);} $check_num = ''; if(Input::noVal('response-id|g') && Input::notExists('submit|p')) { $check = DB::getInstance()->query("SELECT `id` FROM `".QUOTE_RESPONSES."` WHERE `request_id` = ".(int)Input::val('quote-id|g')); if($check_num = $check->rowCount() > 0) { echo formComplete('A Quote has already been made for this request.', TRUE); } } if(!empty($results) && empty($check_num)) { ?> <div id="admin-form" class="form-bkgnd"> <div id="original-request" style="padding-left: 6px;"> <?php if(Input::notExists('submit|p')) { $nodisplay = array('id', 'quote_active', 'request_active', 'response', 'date_sent', 'signature', 'read_quote', 'purchased', 'body', 'notes', 'unit_pricing', 'code', 'request_id', 'vehicle_make_id', 'vehicle_model_id', 'vehicle_year_id'); $html='<div id="request-info-left">'; $car_addition=''; $display_count = 0; foreach($results as $key => $val) { if(!in_array($key, $nodisplay)) { if($key == "city" && !empty($val)) { $html .= ucwords($key).' = '.getCityNameAndState($val).'<br>'; } elseif($key == "key_id" && !empty($val)) { $img_loc_string = getKeyImages($val); $html .= '<img src="'.IMAGE_LAY_SITE.$img_loc_string[0]['image'].'"><br>'; } elseif($key == 'key_image_upload' && !empty($val)) { $html .= '<a href="'.PLUGINS_QUOTES.'serve-key-image.php?image='.$val.'" target="_blank"> <img src="'.PLUGINS_QUOTES.'serve-key-image.php?image='.$val.'" class="key-image-upload-admin"> Click To Enlarge</a><br>'; } elseif($key == "options") { $html .= nl2br(ucwords($val)); } elseif(empty($val)) { $html .= ucwords($key).' = '.$val.'<br>'; } else/*if($key == "key_type")*/ { if($val == "Push To Start") { if(Input::val('action|g') != "edit") { $car_addition .= ' PTS'; } $val = '<span class="bold">'.$val.'</span>'; } elseif($val == "Manual") { if(Input::val('action|g') != "edit") { $car_addition .= ' Manual Trans'; } $val = '<span class="bold">'.$val.'</span>'; } elseif($val == "Turn A Knob") { if(Input::val('action|g') != "edit") { $car_addition .= ' Intellikey'; } $val = '<span class="bold">'.$val.'</span>'; } elseif($val == "Hybrid" || $val == "Diesel") { if(Input::val('action|g') != "edit") { $car_addition .= ' '.$val; } $val = '<span class="bold">'.$val.'</span>'; } /*elseif($key == '40bit' || $key == '80bit') { $car_addition .= $key; }*/ $html .= ucwords($key).' = '.$val.'<br>'; } //else{ $html .= ucwords($key).' = '.$val.'<br>'; } $display_count++; if($display_count == 9) { $html .= '</div><div id="request-info-right">'; } } } $html .= '</div><div class="clear"></div>'; $_SESSION['quote_original_info'] = $html; $html=''; } echo (isset($_SESSION['quote_original_info'])) ? $_SESSION['quote_original_info'] : ''; ?> </div><br> <?php echo (Input::hasVal('quote-id|g')) ? '<button onclick="window.location.href=\'/a.php?menu=Quotes&admin_page=quotes_send_email&action=add&quote-id='.(int)Input::val('quote-id|g').'\'">Email Client</button><br><br>' : ''; ?> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">Your car does require a bypass module for the chip in the key.</span><br><br> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">The price will include keyless entry and trunk pop on the new remotes so you can retain those functions while the car is remote started.</span><br><br> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">The keyless entry is included FREE of charge on your vehicle and is a $20 value.</span><br><br> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">The trunk pop is included FREE of charge on your vehicle and is a $20 value.</span><br><br> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">You will need to give up a key for the install. Meaning you would arrive with 2 keys and leave with 1 key in hand. The other key would be hidden permanently in the dash. If you need/want to have more than 1 key after the install, it is suggested to have an additional key cut and programmed by a locksmith or dealership before the install is performed.</span><br><br> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">Great news, your car does not require any additional parts or labor when utilizing the Direct Fit kits.</span><br><br> <button class="copy-span">Copy To Email</button><span class="copy-to-textarea">Your factory remote key will still operate as it does now and will still be used to unlock the doors.</span><br><br> <!--<script type="text/javascript" src="scripts/jscripts/tiny_mce/tiny_mce.js"></script> <script type="text/javascript" src="scripts/textarea-mce.js"></script> --> <?php /*if(isset($drone)){ echo '<div id="drone_notes"><span class="bold">DroneMobile Notes:</span> <br>Make sure to check if the bypass being used will support Telematics Gateway when using the DroneMobile.</div>'; } */ //$car_make = explode(" ", $results['vehicle']); $car_model = stripKeyTypeFromName($results['vehicle_model_name']); $get_notes = adminVehicleNotes($results['vehicle_make_id']); echo (!empty($get_notes)) ? '<div id="car_notes"><span class="bold">'.$results['vehicle_make_name'].' Notes</span><br>'. nl2br(preg_replace("/\w*?".preg_quote($car_model)."\w*/i", '<span class="highlight-purple">$0</span>', $get_notes['notes'])).'</div>' : ''; if(Input::notExists('submit|p') && Input::exists('response-id|g')) { $_SESSION['units_requested'] = $results['units'] = explode(", ", $results['units']); } elseif(Input::notExists('submit|p') /*&& !isset($_GET['response-id'])*/) { $_SESSION['units_requested'] = explode(", ", $results['units']); } /*$units = (isset($results['units']) && !is_array($results['units'])) ? explode(", ", $results['units']) : ((isset($results['units'])) ? $results['units'] : '');*/ $quote_items = (Input::exists('response-id|g') && Input::val('action|g') == "edit" && Input::notExists('submit|p')) ? (new QuoteItems)->selectQuoteItems()->results() : array(); $num = 1; foreach(allUnits("(`".CATEGORIES."`.`cat_name` = 'Two Way Remotes' OR `".CATEGORIES."`.`cat_name` = 'One Way Remotes' OR `".CATEGORIES."`.`cat_name` = 'Make Specific Models' OR `".CATEGORIES."`.`cat_name` = 'Custom Packages')", "`".CATEGORIES."`.`cat_name`, `".PRODUCTS."`.`prod_name`, `".PRODUCTS."`.`price` ASC") as $u) { if(!empty($quote_items)) { foreach($quote_items as $key => $val) { if($val['product_id'] == $u['id']) { $results['units'][$u['prod_name']]['price'] = $val['quote_price']; $results['units'][$u['prod_name']]['note'] = $val['item_note']; } } } $html = '<div><label>';// Open wrap div $html .= (in_array($u['prod_name'], $_SESSION['units_requested'])) ? '<span class="bold">'.$u['prod_name'].'</span>' : $u['prod_name']; $html .= (isOnSale($u['sp_start'], $u['sp_end']) === TRUE) ? ' <span class="on-sale" id="price-'.$num.'">'.$u['sp_price'].'</span>' : ' <span id="price-'.$num.'">'.$u['price'].'</span>'; $html .= '<img class="expand-symbol expand" data-expand-id="'.$num.'" src="'.EXPAND_SYMBOL.'"></label><input name="units['.$u['prod_name'].'][price]" type="text" value="'; $html .= (isset($results['units'][$u['prod_name']]['price'])) ? $results['units'][$u['prod_name']]['price'] : ''; $html .= '" style="width: 40px;" id="prod-expand-'.$num.'"><input name="units['.$u['prod_name'].'][note]" type="text" value="'; $html .= (isset($results['units'][$u['prod_name']]['note'])) ? $results['units'][$u['prod_name']]['note'] : ''; $html .= '" style="width: 400px;">'; $html .= '<input name="units['.$u['prod_name'].'][product_id]" type="hidden" value="'; $html .= (isset($results['units'][$u['prod_name']]['product_id'])) ? $results['units'][$u['prod_name']]['product_id'] : $u['id']; $html .= '">'; $html .= '<input name="units['.$u['prod_name'].'][original_price]" type="hidden" value="'.$u['price'].'">'; $html .= '<input name="units['.$u['prod_name'].'][sale_price]" type="hidden" value="'.$u['sp_price'].'">'; $html .= '<input name="units['.$u['prod_name'].'][on_sale]" type="hidden" value="'; $html .= (isOnSale($u['sp_start'], $u['sp_end']) === TRUE) ? 1 : 0; $html .= '">'; $html .= '<div id="expand_'.$num.'" class="item-option-expand">'; foreach(Config::get('expand_options') as $eo => $eo_val) { $html .= '<input type="checkbox" value="'.$eo_val.'" class="expand_value" data-ex-id="'.$num.'">'.$eo.' '; } $html .= '</div></div>';// Close expand and wrap divs $html_array[] = $html; $num++; } $output = uList($html_array, "unit-list"); $html_array=''; $html=''; /*foreach(allUnits("`".PRODUCTS."`.`Bypass Modules`=1") as $b) { $html[] = '<input type="radio" name="bypass" value="'.$b['prod_name'].'"> '.$b['prod_name']; } */ /*$byp = allUnits("`".PRODUCTS."`.`Bypass Modules`=1"); $bypasses[] = ''; foreach($byp as $p) { $bypasses[] = $p['prod_name']; } */ //$results['signature'] = (isset($results['signature'])) ? $results['signature'] : $signature; $results['email_body'] = (Input::val('action|g') == "edit" && Input::notExists('submit|p')) ? $results['body'] : ((isset($results['email_body'])) ? $results['email_body'] : ''); $results['vehicle_sufix'] = (Input::val('action|g') == "add" && empty($results['vehicle_sufix'])) ? trim($car_addition) : $results['vehicle_sufix']; //$results['vehicle'] = (isset($results['vehicle'])) ? str_replace(array(' (standard key)', ' (push-to-start)'), '', $results['vehicle']) : ''; require_once(ROOT.PLUGINS_QUOTES.'admin_vehicle_select.php'); $form_fields = array( array("tag" => array("label"), "text" => "name:", "name" => "name", "class_fields" => TRUE, "type" => "text", "required" => TRUE, "value_results_name" => "name", "admin_notes" => FALSE, "options" => array("input_op" => 'maxlength="45"'), ), array("tag" => array("function"), "text" => "vehicle:", "name" => "vehicle", "class_fields" => TRUE, "type" => "text", "required" => TRUE, "value_results_name" => "vehicle", "admin_notes" => FALSE, "options" => array(), "function" => $vhtml ), array("tag" => array("label"), "text" => "vehicle sufix:", "name" => "vehicle_sufix", "class_fields" => TRUE, "type" => "text", "required" => FALSE, "value_results_name" => "vehicle_sufix", "admin_notes" => FALSE, "options" => array("input_op" => 'maxlength="100"'), ), array("tag" => array("label"), "text" => "email body:", "name" => "email_body", "class_fields" => TRUE, "type" => "textarea", "required" => TRUE, "value_results_name" => "email_body", "admin_notes" => FALSE, "options" => array("input_op" => 'style="width: 600px; height: 200px;"'), ), array("tag" => array("function"), "text" => "available units:", "name" => "", "class_fields" => TRUE, "type" => "text", "required" => FALSE, "value_results_name" => "", "admin_notes" => FALSE, "options" => array(), "function" => $output ), /*array("tag" => array("function"), "text" => "Bypass Used:", "name" => "", "class_fields" => TRUE, "type" => "text", "required" => FALSE, "value_results_name" => "", "admin_notes" => FALSE, "options" => array(), "function" => selectBox('bypass', $bypasses, (isset($results['bypass'])) ? $results['bypass'] : '', 'val', TRUE) ), */ array("tag" => array("label"), "text" => "notes:", "name" => "notes", "class_fields" => TRUE, "type" => "textarea", "required" => FALSE, "value_results_name" => "notes", "admin_notes" => FALSE, "options" => array(), ), /*array("tag" => array("label"), "text" => "signature:", "name" => "signature", "class_fields" => TRUE, "type" => "textarea", "required" => FALSE, "value_results_name" => "signature", "admin_notes" => FALSE, "options" => array("input_op" => 'style="width: 600px;"'), ),*/ "hiddens" => array("email" => (isset($results['email'])) ? $results['email'] : '', "code" => (isset($results['code'])) ? $results['code'] : '', "quote_id" => (isset($results['quote_id'])) ? $results['quote_id'] : Input::val('quote-id|g'), "send_sms" => (isset($results['send_sms'])) ? $results['send_sms'] : '', "phone" => (isset($results['phone'])) ? $results['phone'] : '', "vehicle_make_name" => (isset($results['vehicle_make_name'])) ? $results['vehicle_make_name'] : '', "vehicle_model_name" => (isset($results['vehicle_model_name'])) ? $results['vehicle_model_name'] : ''), "form_button" => array("name" => "submit", "type" => "submit", "value" => "submit", "attributes" => "") ); adminForm($form_fields, (isset($results)) ? $results : '', 'response-form'); ?> </div> <script> $(document).ready(function(){ $('.expand-symbol').on('click', function(){ var num = $(this).data('expand-id'); $('#expand_'+num).slideToggle(); }); $('.expand_value').on('click', function(){ var value = parseInt($(this).val()); var expand_id = $(this).data('ex-id'); var price_input = $('#prod-expand-'+expand_id); if($(price_input).val() == ''){ var price= parseInt($('#price-'+expand_id).text()); } else{ var price = parseInt($(price_input).val()); } if($(this).prop('checked')){ var new_price = price + value; } else{ var new_price = price - value; } $(price_input).val(new_price); }); $('.copy-span').on('click', function(){ var text = $(this).next('span').text() + "\r\n\r\n", old_text = $("textarea[name='email_body']").val(); $("textarea[name='email_body']").val(old_text + text); }); }); </script> <span> Confirmed Cars where factory keyless works while running:<br> 2011 Rogue standard key<br> 2007 Explorer<br> 2004 Sentra<br> 2010 Focus<br> 2003 Murano<br> 2003 Ranger<br> 2005 Altima<br> 1999 Cherokee<br> 2005 Sierra<br> 2010 Mazda 3 Flip-key<br> 2010 Mazda 6 Flip-key<br> 2008 Outback w/Remote key<br> All Toyota Remote Keys<br> All Nissan Push-to-Start and Intellikey style<br> All Fords with remote keys<br> </span><br> <span> Cars that the factory keyless DOES NOT work while running:<br> All Hondas<br> All Hyundai/Kia except select PTS versions<br> Most 2002-older Fords<br> Mazda Intellikey<br> </span> <?php $docs = getDocs("admin_files"); ?> <br> <table cellpadding="6" id="admin_table" class="admin-tbl hide"> <tr> <th>Folder / Files</th> <th>Relative Path</th> </tr> <?php $td = "gray-td"; foreach($docs as $doc => $val) { echo '<tr class="'.$td.'"><td colspan="2">'.FOLDER.' '.$doc; unset($val[0], $val[1]); if(!isset($val[2])) {echo ' - Folder is empty</td></tr>';} else {echo '</td></tr>';} foreach($val as $v) {echo '<tr><td class="indent">'.$v.'</td> <td>admin_files/'.$doc.'/'.$v.'</td> </tr>';} } ?> </table> <?php } } ?>
  17. The QuoteResponse in my mind was a class that deals with anything that had to do with the response of the quote request. I agree with the breaking out the validation, but I haven't been able to figure out a way to do that universally among the classes and still achieve the validation I want. I've looked at validation type classes and didn't feel they offer much of a better solution cause it's still repeating code within the class method to setup everything. Could you do a quick example of break out classes or methods to make the processquote() "better", doesn't have to actually function, just parts you would move out to other areas.
  18. So I'm fairly confident that I understand the idea of having a class with minimal responsibility but I struggle with concept of having tons of little classes instead of a few larger ones that encompass more responsibility. Just seems a bit silly to break it down into several classes when it could be just one. I had 2 function pages that held a few dozen regular functions that all relate to a specific aspect of my site, hence why they were grouped among these 2 pages. I am trying to organize them into classes and make it easier to expand in the future and eliminate duplicate code from the functions, like always setting $db = DB::getInstance(); to be able to use my db class. So now I have 13 new classes with functions that relate to the class. I think that is a good start, but I feel like it's not enough, or not enough in the proper direction of how a class should act. Here is a sample of a new class. Can you take a look at it and give advice on how you might change or extract its responsibility to an additional class/es, or if it's just fie the way it is. There are a few functions in these classes that I'm really not sure how to split apart any more, simply cause they are form processing functions that validate, set errors, return messages, email and do db stuff. But I have classes in those functions that are already doing things separately and the flow of logic would be hard to break apart and maintain the functions goal of form processing quickly and efficiently in one spot. QuoteResponse.class.php <?php class QuoteResponse extends QuoteSystem { public function __construct() { parent::__construct(); } public function verifyReferralCode($ref_code) { return $this->db->query("SELECT COUNT(`id`) FROM `".QUOTE_RESPONSES."` WHERE `id` = {$ref_code}"); } public function checkQuoteExists($q_id) { return $this->db->query("SELECT `id` FROM `".QUOTE_RESPONSES."` WHERE `request_id` = ".$q_id); } // Gets info for the given quote-id and c code for a client view public function getQuote() { $id = (int)Input::val('quote-id|g'); $code = sanitize(Input::val('c|g')); $get = $this->db->prepare("SELECT `".QUOTE_RESPONSES."`.*, `".QUOTE_ITEMS."`.*, `".PRODUCTS."`.*, `".QUOTE_DEPOSITS."`.`id` AS `deposit_id`, `".QUOTE_DEPOSITS."`.`product_id` AS `deposit_prod`, `".QUOTE_DEP_RESP."`.`id` as `dep_resp_id`, `".QUOTE_REQUESTS."`.`cookie_code`, `".QUOTE_REQUESTS."`.`id` as `orig_quote_id`, ".CONCAT_VEHICLE." AS `vehicle`, `".QUOTE_REQUESTS."`.`vehicle_sufix`, `".QUOTE_REQUESTS."`.`name`, `".SCH."`.`schedule_id`, `".SCH."`.`install_time`, `".SCH."`.`cancelled` FROM `".QUOTE_RESPONSES."` INNER JOIN `".QUOTE_ITEMS."` ON `".QUOTE_ITEMS."`.`response_id` = `".QUOTE_RESPONSES."`.`id` INNER JOIN `".PRODUCTS."` ON `".PRODUCTS."`.`id` = `".QUOTE_ITEMS."`.`product_id` INNER JOIN `".QUOTE_REQUESTS."` ON `".QUOTE_REQUESTS."`.`id` = `".QUOTE_RESPONSES."`.`request_id` ".VEHICLE_JOIN." LEFT JOIN `".QUOTE_DEPOSITS."` ON `".QUOTE_DEPOSITS."`.`q_id` = `".QUOTE_RESPONSES."`.`id` LEFT JOIN `".QUOTE_DEP_RESP."` ON `".QUOTE_DEP_RESP."`.`deposit_id` = `".QUOTE_DEPOSITS."`.`id` LEFT JOIN `".SCH."` ON `".SCH."`.`deposit_id` = `".QUOTE_DEPOSITS."`.`id` WHERE `".QUOTE_RESPONSES."`.`id`=$id AND `code`= ?"); $get->execute(array($code)); return $get->fetchAll(); } // Validates the quote public function processQuote() { //diagDiv($_POST); $qi = new QuoteItems; $i = new Input; $resp_id = $i->get('response-id', '', 'int'); $q_id = $i->post('quote_id', '', 'int'); $name = $i->post('name', TRUE); $car_name = $i->post('vehicle_make_name', TRUE); $car_model = $i->post('vehicle_model_name', TRUE); $make_id = $i->post('make_id', '', 'int'); $model_id = $i->post('model_id', '', 'int'); $year = $i->post('year', '', 'int'); $car_sufix = $i->post('vehicle_sufix', TRUE); $ebody = $i->post('email_body', TRUE); $sig = $i->post('signature'); $unit = $i->post('units'); $notes = $i->post('notes', TRUE); $email = $i->post('email', TRUE); $code = $i->post('code', TRUE); $sms = ($i->post('send_sms', '', 'int') == 1) ? TRUE : FALSE; $phone = $i->post('phone', TRUE); //$bypass = (isset($_POST['bypass'])) ? sanitize($_POST['bypass']) : ''; $fields = array('name' => $name, 'vehicle_make_name' => $car_name, 'vehicle_model_name' => $car_model, 'vehicle_sufix' => $car_sufix, 'email_body' => $ebody, 'signature' => $sig, 'units' => $unit, 'notes' => $notes, 'email' => $email, "code" => $code, "quote_id" => $q_id, 'send_sms' => $sms, 'phone' => $phone, 'vehicle_make_id' => $make_id, 'vehicle_model_id' => $model_id, 'vehicle_year_id' => $year); $notes = escape($notes); $required = array("name", "email_body", "email", "make_id", "model_id", "year"); requiredFields($i->all('post'), $required); if(empty($resp_id)) { $check = $this->checkQuoteExists($q_id); if($check->rowCount() > 0) { Errors::set('A Quote has already been made for this request.'); } } if(Errors::has()){} else { nameLength($name, 2, 45); //maxStringLength($car, 100, 'The vehicle cannot exceed 100 characters.'); minStringLength($ebody, 2, 'The email body must be at least 2 characters in length.'); //minStringLength($sig, 2, 'The signature must be at least 2 characters in length.'); validEmail($email); $email_units=''; foreach($unit as $key => $val) { if(!empty($val['price'])) { $diff = $val['original_price'] - $val['sale_price']; $email_units .= $key.' - $'.number_format($val['price'], 2); $email_units .= ($val['on_sale'] == TRUE) ? ' (while on sale, add $'.$diff.' after sale ends)' : ''; $email_units .= ' +tax'; $email_units .= (!empty($val['note'])) ? " (".$val['note'].")\r\n" : "\r\n"; } } if(empty($email_units)) { Errors::set('Please select products for the quote.'); } } if(Errors::has()) { echo Errors::output(); } else { $now = time(); $units_text = "Prices include all parts and labor:\r\n".$email_units; $where = ''; $date_sent = ''; $date_modified = NULL; // INSERT/UPDATE QUOTE_RESPONSES $params = [ 'request_id' => [$q_id, 'INT'], /*'name' => $name,*/ /*'vehicle' => $car,*/ /*'vehicle_sufix' => $car_sufix,*/ 'date_modified' => NULL, 'body' => $ebody, //'signature' => $sig, 'code' => $code, 'notes' => $notes, 'unit_pricing' => $units_text ]; if($i->get('action') == "add") { $params['code'] = randomCode(20); $code = $params['code']; $set = $this->db->insert(QUOTE_RESPONSES, $params); } elseif($i->get('action') == "edit") { $params['date_modified'] = date("Y-m-d H:i:s"); $set = $this->db->update(QUOTE_RESPONSES, $params, '`id` = '.$resp_id, 1); } $last_id = ($i->get('action') == "add") ? $set->lastInsertId() : $resp_id; ///////////// END /////////////////////////////////// // UPDATE REFERRALS if($i->get('action') == "add") { (new QuoteReferral)->setQuoteId($last_id, $q_id); } //////////// END ////////////////////// // Clear QUOTE_ITEMS if($i->get('action') == "edit") { $qi->deleteQuoteItems($resp_id); } /////////// END ////////////////////// // UPDATE QUOTE_REQUESTS with posted vehicle info. $params = [ 'vehicle_make_id' => [$make_id, 'INT'], 'vehicle_model_id' => [$model_id, 'INT'], 'vehicle_year_id' => [$year, 'INT'], 'vehicle_sufix' => $car_sufix ]; (new QuoteRequest)->updateById($params, $q_id); ///////// END ////////////////////////////////////////// // SET new QUOTE_ITEMS foreach($unit as $key => $val) { $params = []; if(!empty($val['price'])) { $note = (!empty($val['note'])) ? sanitize($val['note']) : ''; $unit_price = addSalesTax($val['price'], Config::get('tax_rate')); $add_amt = ($val['on_sale'] == TRUE) ? (int)$val['price'] - (int)$val['sale_price'] : (int)$val['price'] - (int)$val['original_price']; $params = [ 'item' => $key, 'quote_price' => [$val['price'], 'INT'], 'response_id' => [$last_id, 'INT'], 'product_id' => [$val['product_id'], 'INT'], 'item_note' => $note, 'add_amt' => [$add_amt, 'INT'] ]; $qi->insertQuoteItems($params); } } ////////// END /////////////////////////////// if($i->get('action') == "add") { // Build Email to customer and admin // OLD EMAIL FORMAT ////////////////////////////////////////////////////////////////// /*$ebody .= $units_text; $link = "If this link is not clickable please copy and paste it into your browser address bar to confirm you have received your quote and to make your deposit.\r\n"; $link_url = 'http://remotelystartedmn.com/quotes.php?quote-id='.$last_id.'&c='.$code; $sig .= "\r\n\r\n".$link.$link_url.Config::get('quote_signature_part2'); */ ////////////////////////////////////////////////////////////////////////////////////// // OLD Signature storage, now signature is built in the composeQuote() /*$link = "Please visit the link below to see your pricing options. If the link is not clickable please copy and paste it into your browser address bar.\r\n"; $link_url = 'http://remotelystartedmn.com/quotes.php?quote-id='.$last_id.'&c='.$code; $email_link_url = $link_url.'&e=1'; $signature = $link.$email_link_url."\r\n\r\n".$sig.Config::get('quote_signature_part2');*/ $link_url = 'http://remotelystartedmn.com/quotes.php?quote-id='.$last_id.'&c='.$code.'&direct'; $email_link_url = $link_url.'&e=1'; //$body = 'Hello '.$name.','; //$body .= "\r\n".$ebody."\r\n".$sig; // <--- OLD EMAIL FORMAT // //$body .= "\r\n".$ebody."\r\n".$signature.thanksSignature(); $set = $this->db->update(QUOTE_RESPONSES, [/*'signature' => $signature, */'quote_link' => $email_link_url], '`id`= '.$last_id); //$set->execute(array($sig)); // <--- OLD EMAIL FORMAT // //$set->execute(array($signature)); $qid = $i->get('quote-id', '', 'int'); (new QuoteRequest)->updateResponseType($qid); // Attempt to send the quote email $send = $this->composeQuote($last_id); if($send === TRUE) { $message = 'Email Sent'; $sms_response = TRUE; if($sms === TRUE && !empty($phone)) { $args = array('username' => Config::get('ez_sms_username'), 'password' => Config::get('ez_sms_password'), 'subject' => '', 'message' => "Remote start quote is ready! ".$link_url."&t=1 Reply texts won't be received", 'phone' => $phone); $sms_response = sendSMS($args); $message .= '<br>Text Message Sent'; } if($sms_response === TRUE){ echo formComplete($message, TRUE); } else{ echo 'Text Message Failed:<br>'.$sms_response; } } elseif($send === FALSE) { formErrors(array('Something went wrong.')); } /////////////////////////////////////////////// } elseif($i->get('action') == "edit") { echo formComplete('Quote Updated', TRUE); } unset($_SESSION['quote_original_info']); $fields=''; } return $fields; } // Updates the purchase status for each posted public function changePurchase($tbl) { $key=""; foreach(Input::val('bought|p') as $c[$key] => $value) { $id = (int)$c[$key]; $this->db->query("UPDATE `".$tbl."` SET `purchased` = 1 WHERE `id` = '".$id."'"); if(isset($_POST['miles'][$id]) && $_POST['miles'][$id] > 0) { $miles = (float)$_POST['miles'][$id]; (new MilesDriven)->setMiles($id, $miles); } // Send completed email if(Config::get('send_email_when_completed') === TRUE) { $get = $this->db->query(" SELECT `".QUOTE_REQUESTS."`.`name`, `".QUOTE_REQUESTS."`.`email`, `".QUOTE_REQUESTS."`.`gift_date`, `".QUOTE_REQUESTS."`.`gift_name`, `".QUOTE_REQUESTS."`.`gift_email`, ".CONCAT_VEHICLE." AS `vehicle`, `".QUOTE_REQUESTS."`.`vehicle_sufix`, qr1.video, qr1.screen_shot, qr1.description, qr2.video as `specific_video`, qr2.screen_shot as `specific_screen_shot`, qr2.description as `specific_description`, qr3.video as `non_specific_video`, qr3.screen_shot as `non_specific_screen_shot`, qr3.description as `non_specific_description` FROM `".QUOTE_RESPONSES."` INNER JOIN `".QUOTE_REQUESTS."` ON `".QUOTE_REQUESTS."`.`id` = `".QUOTE_RESPONSES."`.`request_id` INNER JOIN `".QUOTE_DEPOSITS."` ON `".QUOTE_DEPOSITS."`.`q_id` = `".QUOTE_RESPONSES."`.`id` INNER JOIN `".PRODUCTS."` ON `".PRODUCTS."`.`id` = `".QUOTE_DEPOSITS."`.`product_id` ".VEHICLE_JOIN." LEFT JOIN `".VIDEOS."` qr1 ON qr1.`id` = `".PRODUCTS."`.`video_id` LEFT JOIN `".VIDEOS."` qr2 ON qr2.`specific_to` = CONCAT(`".QUOTE_REQUESTS."`.`trans`, ' ', `".QUOTE_REQUESTS."`.`key_type`) LEFT JOIN `".VIDEOS."` qr3 ON qr3.`specific_to` = 'All' WHERE `".QUOTE_RESPONSES."`.`id` = $id ")->fetch(); $videos = []; $body2 = ''; if(!empty($get['video']) || !empty($get['specific_video']) || !empty($get['non_specific_video'])) { $videos[] = [ 'video' => $get['video'], 'desc' => $get['description'], 'shot' => $get['screen_shot'] ]; $videos[] = [ 'video' => $get['specific_video'], 'desc' => $get['specific_description'], 'shot' => $get['specific_screen_shot'] ]; $videos[] = [ 'video' => $get['non_specific_video'], 'desc' => $get['non_specific_description'], 'shot' => $get['non_specific_screen_shot'] ]; $count = 0; foreach($videos as $v) { $count = (!empty($v['video'])) ? $count + 1 : $count + 0; } $video_text = ($count == 1) ? 'a video that has' : $count.' videos that have'; $video_text2 = ($count == 1) ? 'this video is' : 'these videos are'; $body2 = "If you are a first time remote start owner, we understand that it can be confusing learning how to use your remote start. We have provided ".$video_text." valuable information on how to use your remote start. Please understand that ".$video_text2." somewhat generalized to your product and even possibly your car, so it's possible that not all apsects of the video will apply. Please try to remember any specifics we discussed about your install while watching the video and understand that the video may not 100% match the information we discussed. ".ucfirst($video_text2)." provided by the manufacturer as a general guide."; } $body = "Thank you very much for your purchase. Our business thrives on referrals from customers like you. We hope we have gained your trust with our services, so much so that we hope you would refer any friends, family or co-workers our way. We do have a little incentive for you, it's as easy as 123.<br><br>1. Give the Referral Code below to anyone you're sending our way.<br>There is a spot at the bottom of the quote request form to put that number.<br>2. The person you referred makes a purchase.<br>3. We contact you for an address and send you a Target Gift Card as a thank you for referring a customer to us.<br><br>Below is a picture of where to put the referral code. You can show anyone that picture so they know what to look for. Your code can be used as many times as you like, season after season. Each referred purchase gains you a gift card."; // Start building the email template $e = new QuoteEmailTemplate; $data = [ 'name' => $get['name'], 'body' => [$body, TRUE], 'body2' => [$body2, TRUE], 'videos' => [$videos, FALSE], 'referral_id' => $id, 'signature' => thanksSignature(TRUE, TRUE) ]; $e->data($data); $e->load('completed'); $send_html = TRUE; $em_body = $e->getHtmlString(); $em_alt_body = $e->getTextString(); if(Config::get('html_emails') === FALSE) { $send_html = FALSE; $em_body = $em_alt_body; $em_alt_body = ''; } $subject = "Thank you for your purchase at ".Settings::get('site_name'); $diff_ok = (!empty($r['gift_date'])) ? determineDateDiff(TODAY, $r['gift_date'], -1) : FALSE; $send_cc = (Config::get('send_gift_cc_email') === TRUE && !empty($r['gift_email']) && $diff_ok === TRUE) ? TRUE : FALSE; // Setup mailer array $em = array(); $em['body'] = $em_body; $em['alt_body'] = $em_alt_body; $em['subject'] = $subject; $em['to'] = $get['email'] /*SECONDARY_EMAIL*/; $em['to_name'] = $get['name']; $em['smtp'] = FALSE; $em['html'] = $send_html; //echo $reminder_body.'<br>'; //print_r($em); buildPhpMailerEmail($em); if($send_cc === TRUE) { $em = array(); $em['body'] = $em_body; $em['alt_body'] = $em_alt_body; $em['subject'] = $subject; $em['to'] = $get['gift_email'] /*SECONDARY_EMAIL*/; $em['to_name'] = $get['gift_name']; $em['smtp'] = FALSE; $em['html'] = $send_html; buildPhpMailerEmail($em); } } } } // Gets all quotes responses in the db public function allQuoteResponses($start) { $get = $this->db->query("SELECT SQL_CALC_FOUND_ROWS * FROM `".QUOTE_RESPONSES."` ORDER BY `id` DESC LIMIT $start, ".Config::get('quote_requests_per_page').""); $reqs = $get->fetchAll(); (!empty($reqs)) ? $reqs[] = $get->foundRows() : ''; $this->results = $reqs; return $this; } // Gets the quoted response for the given quote-id in the url function selectResponse($id, $edit = FALSE) { $id = (int)$id; $sql1 = ", `".QUOTE_REQUESTS."`.`options`, `".QUOTE_REQUESTS."`.`units`, `".QUOTE_REQUESTS."`.`comments`, `".QUOTE_REQUESTS."`.`key_type`, `".QUOTE_REQUESTS."`.`key_id`, `".QUOTE_REQUESTS."`.`trans`, `".QUOTE_REQUESTS."`.`id` AS `quote_id`, `".QUOTE_REQUESTS."`.`engine`, `".QUOTE_REQUESTS."`.`gift_name`, `".QUOTE_REQUESTS."`.`gift_phone`, `".QUOTE_REQUESTS."`.`gift_email`, `".QUOTE_REQUESTS."`.`gift_date`, `".QUOTE_REQUESTS."`.`vehicle_make_id`, `".QUOTE_REQUESTS."`.`vehicle_model_id`, `".QUOTE_REQUESTS."`.`vehicle_year_id`, `".QUOTE_REQUESTS."`.`key_image_upload`"; if($edit === FALSE){ $sql1 = ''; } $sql = "SELECT `".QUOTE_RESPONSES."`.*, `".QUOTE_REQUESTS."`.`email`, ".CONCAT_VEHICLE." AS `vehicle`, `".QUOTE_REQUESTS."`.`name`, `".QUOTE_REQUESTS."`.`vehicle_sufix`, ".VEHICLE_NAME_PARTS." $sql1 FROM `".QUOTE_RESPONSES."` INNER JOIN `".QUOTE_REQUESTS."` ON `".QUOTE_REQUESTS."`.`id` = `".QUOTE_RESPONSES."`.`request_id` ".VEHICLE_JOIN." WHERE `".QUOTE_RESPONSES."`.`id`='$id'"; $get = $this->db->query($sql); return $get->fetch(); } // Re-sends a email quote. public function resendQuote() { $id = (int)Input::val('id|p'); return $this->composeQuote($id); } //Builds a Compose Button for quotes public function composeQuote($id) { $info = $this->selectResponse($id); $signature = Config::get('quote_signature').Config::get('quote_signature_part2').thanksSignature(TRUE); $e = new QuoteEmailTemplate; $data = [ 'name' => $info['name'], 'quote_link' => $info['quote_link'], 'signature' => [$signature, TRUE] ]; $e->data($data); $e->load('quote'); $send_html = TRUE; $em_body = $e->getHtmlString(); $em_alt_body = $e->getTextString(); if(Config::get('html_emails') === FALSE) { $send_html = FALSE; $em_body = $em_alt_body; $em_alt_body = ''; } // Setup mailer array $em['body'] = $em_body; $em['alt_body'] = $em_alt_body; $em['subject'] = 'Remote Start Quote '.$info['name'].' - '.$info['vehicle'].' '.$info['vehicle_sufix']; $em['to'] = $info['email']; $em['to_name'] = $info['name']; $em['smtp'] = FALSE; $em['html'] = $send_html; $em['bcc_to'] = ''; $em['bcc_name'] = ''; return buildPhpMailerEmail($em); ?> <!--<script> $('#send').click(function() { window.open('<?php echo 'https://mail.google.com/mail/?view=cm&fs=1&to='.urlencode($quote['email']).'&su=Remote Start Quote '.urlencode($quote['name']).' - '.urlencode($quote['vehicle']); ?>','_blank'); }); </script>--> <?php } public function getQuoteMenuInfo() { $code = sanitize(Input::val('rsmn_quote_code|c')); $get = $this->db->prepare("SELECT `".QUOTE_RESPONSES."`.*, `".QUOTE_REQUESTS."`.`cookie_code` FROM `".QUOTE_REQUESTS."` INNER JOIN `".QUOTE_RESPONSES."` ON `".QUOTE_RESPONSES."`.`request_id` = `".QUOTE_REQUESTS."`.`id` WHERE `".QUOTE_REQUESTS."`.`cookie_code` = ?"); $get->execute(array($code)); return $get->fetch(); } function updateQuoteRead($id) { $type = ''; $now = time(); if(Input::exists('t|g')) { $type = ", `viewed_by_txt` = 1"; } elseif(Input::exists('e|g')) { $type = ", `viewed_by_email` = 1"; } $this->db->query("UPDATE `".QUOTE_RESPONSES."` SET `date_read_quote` = NOW(), `read_quote` = 1".$type." WHERE `id` = ".$id); } } QuoteSystem.class.php <?php class QuoteSystem { protected $db; public function __construct() { $this->db = DB::getInstance(); } public function results() { return $this->results; } // Updates the response type for each quote posted public function changeResponseType($tbl) { $key=""; foreach(Input::val('iemailed|p') as $c["$key"] => $value) { $this->db->query("UPDATE `".$tbl."` SET `response` = 'Emailed' WHERE `id` = '".(int)$c[$key]."'"); } } // Searches the db for matching results for the given search criteria public function searchQuote($start) { $field = Input::val('tbl_field|g'); $srch = Input::val('searched|g'); $join = "LEFT JOIN `".QUOTE_RESPONSES."` ON `".QUOTE_RESPONSES."`.`request_id` = `".QUOTE_REQUESTS."`.`id` LEFT JOIN `".QUOTE_DEPOSITS."` ON `".QUOTE_DEPOSITS."`.`q_id` = `".QUOTE_RESPONSES."`.`id` LEFT JOIN `".QUOTE_DEP_RESP."` ON `".QUOTE_DEP_RESP."`.`quote_id` = `".QUOTE_RESPONSES."`.`id` LEFT JOIN `".SCH."` ON `".SCH."`.`deposit_id` = `".QUOTE_DEPOSITS."`.`id` ".VEHICLE_JOIN; $orderby = "`".QUOTE_REQUESTS."`.`name` ASC"; switch($field) { case "Name": $where = "WHERE `".QUOTE_REQUESTS."`.`name` LIKE :s "; break; case "Vehicle": $where = "WHERE `".QUOTE_REQUESTS."`.`vehicle` LIKE :s "; break; case "Vehicle Sufix": $where = "WHERE `".QUOTE_REQUESTS."`.`vehicle_sufix` LIKE :s "; break; case "Phone": $where = "WHERE `".QUOTE_REQUESTS."`.`phone` LIKE :s "; break; case "Date": $srch = explode("-", $srch); $srch = $srch[2].'-'.$srch[0].'-'.$srch[1]; $old = strtotime("-4 days", strtotime($srch)); $ahead = strtotime("+5 days", strtotime($srch)); $where = "WHERE `".QUOTE_REQUESTS."`.`date_sent` >= '$old' AND `".QUOTE_REQUESTS."`.`date_sent` <= '$ahead'"; $orderby = "`".QUOTE_REQUESTS."`.`date_sent` ASC"; break; case "Quote Id": $srch = (int)$srch; $where = "WHERE `".QUOTE_RESPONSES."`.`id` = $srch "; break; case "Email": $where = "WHERE `".QUOTE_REQUESTS."`.`email` LIKE :s "; break; case "Schedule": $srch = explode("-", $srch); $srch = $srch[2].'-'.$srch[0].'-'.$srch[1]; $old = date("Y-m-d", strtotime("-1 day", strtotime($srch))); $ahead = date("Y-m-d", strtotime("+2 day", strtotime($srch))); $where = "WHERE `".SCH."`.`install_time` BETWEEN '$old' AND '$ahead'"; $orderby = "`".SCH."`.`install_time` ASC"; break; case "Read": $srch = (int)$srch; $where = "WHERE `".QUOTE_RESPONSES."`.`read_quote` = $srch"; $orderby = "`".QUOTE_RESPONSES."`.`date_sent` DESC"; break; case "WHERE": $srch = str_replace('!gt!', '>', $srch); $srch = str_replace('!lt!', '>', $srch); $where = "WHERE ".$srch; break; } $sql = "SELECT `".QUOTE_REQUESTS."`.`id`, `".QUOTE_REQUESTS."`.`email`, `".QUOTE_REQUESTS."`.`name`, `".QUOTE_REQUESTS."`.`response`, `".QUOTE_REQUESTS."`.`date_sent` AS `request_sent`, `".QUOTE_REQUESTS."`.`vehicle` AS `car_requested`, `".QUOTE_REQUESTS."`.`vehicle_sufix`, `".QUOTE_RESPONSES."`.`quote_active`, `".QUOTE_RESPONSES."`.`id` AS `response_id`, `".QUOTE_RESPONSES."`.`date_sent` AS `quote_date_sent`, `".QUOTE_RESPONSES."`.`purchased`, ".CONCAT_VEHICLE." AS `vehicle`, `".QUOTE_RESPONSES."`.`read_quote` AS `read`, `".SCH."`.`install_time`, `".SCH."`.`cancelled`, `".SCH."`.`schedule_id`, `".SCH."`.`sch_notes`, `".QUOTE_DEP_RESP."`.`id` AS `dep_resp_id`, `".QUOTE_DEPOSITS."`.`part_num` AS `dep_part_num`, `".QUOTE_DEPOSITS."`.`id` AS `deposit_id`, `".QUOTE_DEPOSITS."`.`product_id`, `".QUOTE_DEPOSITS."`.`response` AS `dep_type` "; $sql .= "FROM `".QUOTE_REQUESTS."` "; $sql .= $join .' '. $where; $sql .= " ORDER BY ".$orderby." "; /*$sql .= "LIMIT $start, ".Config::get('quote_requests_per_page');*/ $int_fields = array('Quote Id', 'Date', 'Schedule', 'Read'); $like_fields = array('Name', 'Email', 'Vehicle', 'Vehicle Sufix', 'Phone'); $where_fields = array('WHERE'); if(in_array($field, $like_fields)) { $param = '%'.$srch.'%'; $get = $this->db->prepare($sql); $get->bind(':s', $param); $get->execute() /**/; } elseif(in_array($field, $int_fields)) { $get = $this->db->query($sql) /**/; } elseif(in_array($field, $where_fields)) { $get = $this->db->query($sql) ; } //echo $get->printSql().'<br><br>'; //echo $get->errorReason(); $this->results = $get->fetchAll(); return $this; } } Any advice or guidance is appreciated.
  19. Does your DB wrapper class have a mysql_error() function it can return the error for you? I appears the first query on the download page is failing or the query on the timer page. It's hard to tell cause you have EXPIRED echo out in 2 places in the scripts so I don't know which page the query is failing from.
  20. If that link is what the client clicks on to download the file, then it's what I said, there isn't a $_GET['code'] in that link.
  21. How about a quote items reference table. Just store the quote_id, product_id and quoted_price. All of which you should have the data for when submitting the quote. Then you don't have duplicated table data with the products and you just display the quoted price later if you need to view it.
  22. You would need to show us the code that is making the download link itself. Based on what your download script needs, sounds like it's not getting a "code" in the url, simple guess without the rest of your code. Or this is failing too $rs = $Core->DB->query('SELECT * FROM uploads WHERE id='.intval($row['fid']).' LIMIT 1'); So the browser doesn't know to send it to the download screen popup
  23. Thinking, I believe it won't echo anything out cause with a fatal error, the parser stops immediately when the error happens. So it can't output anything after that point, it can perform some other things, but output is a no go.
  24. Couple things. First these lines $Year = $_POST["Year"]; if ($Year= 2015) Should be this $Year = (int)$_POST["Year"]; // Cast to an integer for security and proper comparison below. if ($Year == 2015) // Missing a = But the bigger issue is that your DB structure looks very flawed. You basically have 2 tables that are identical in what they store but you named the columns slightly different. This is a huge waste of time and goes totally against proper db relationships. It would be way way better to have just one table with a timestamp column that would have a value of whatever year you needed. Then you only need one query that checks just the one column using the DATE() and possibly YEAR() in mysql to find the rows you need.
  25. You're not incrementing $i anywhere. You have a for() but you don't have any code in it to build the links properly. Check out the first link in my signature and got to the code snippets tab, you'll find something helpful there.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.