Jump to content

maxxd

Gurus
  • Posts

    1,661
  • Joined

  • Last visited

  • Days Won

    52

Posts posted by maxxd

  1. They may be folders, but in this case you're dealing with namespaces, not folder structure. Assuming everything in Cake is using an autoloader, I would expect to find the namespaces correspond with the directory structure, but it certainly doesn't have to.

  2. True, but then you're repeating that logic every time you need it. A typical routing layer sits in front of the controllers and everything is in one centralized location.

     

    Very true. But if you're only working in the one controller with one action target, you can use the same idea to route the functionality flow throughout that controller. No biggie, just a thing. :)

     

     

    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.

     

    Glad that example made at least a little sense!

  3. I am kinda talking about a Routing system, as scootstah says. However, it's also very possible to use it within the same object from the get-go.

    //none of this is actually used in the code you posted, but I'm leaving it because I have to assume
    //	it's important somewhere
    $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
    ];
    
    //this line becomes a hub of sorts - you can branch the flow anywhere you need to, including
    //	other objects if that works with what you're doing.
    $function = 'do'.ucfirst(strtolower($i->get('action')));
    if(method_exists($this, $function)){
    	$unit = $this->$function($params);
    }
    
    function doAdd(array $params/* any of the other parameters - see the comment */){
    	$params['code'] = randomCode(20);
    	$code = $params['code'];
    	$set = $this->db->insert(QUOTE_RESPONSES, $params);
    	$last_id = $set->lastInsertId();
    
    //things start to get a bit weird here - where in the code you posted are $q_id, $code, and $i defined?
    //	I mean, it really doesn't matter - you may just have to add them as parameters of the doX() methods,
    //	but it is a bit confusing...
    
    //update referrals
    	(new QuoteReferral)->setQuoteId($last_id, $q_id);
    	$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);
    	
    	return $whateverUnitIs;
    }
    
    function doEdit(array $params){
    //again, there are a lot of undefined variables here that I assume are defined elsewhere in the code. So, pass those as
    //	parameters into the doX() methods.
    	$params['date_modified'] = date("Y-m-d H:i:s");
    	$set = $this->db->update(QUOTE_RESPONSES, $params, '`id` = '.$resp_id, 1);
    	$last_id = $resp_id;
    //clear quote items
    	$qi->deleteQuoteItems($resp_id);
    	
    	return $whateverUnitIs;
    	
    }
    
    //Sorry, but I have no idea what this section is doing and what it has to do with the bulk of the code above
    //	so I'm just kinda leaving it here...
    
    // 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 ///////////////////////////////
    

    The nice thing, instead of the 5 or 6 instances of

    if($i->get('action') == ...){
    

    that you have to dig through to figure out which portion of the logic application you're dealing with when something goes wrong with the code, all the functionality for the add action and the edit action are consolidated and completely independent of each other.

  4. The number of times you're running a conditional expression on the value of $i->get() is a definite smell. Personally, I handle this dynamically as so:

    $function = 'do'.ucfirst(strtolower($i->get('action')));
    $response = $this->$function($params);
    

    You can consolidate all of your action-specific code within those methods and avoid not only all the conditional brackets, but confusing variable assignment like this

    $last_id = ($i->get('action') == "add") ? $set->lastInsertId() : $resp_id;
    

    because everything is black-boxed. So, in doAdd() you can refer the variable as $newRecordID and in doEdit() it can be $currentRecordID, improving the readability by specifying the purpose of the variable and the value it contains.

     

    Of course, you'll want to check that the specified method exists in your object before attempting to call it, but that's the basic gist. You'll have functions doAdd() and doEdit() (for your example), but can easily handle other actions by adding doDelete(), doModify(), doMailSomebodySomethingAwesome(), etc.

     

    Hope that made some sort of sense.

  5. In this situation, I'd recommend using a templating system such as Twig. Assuming you have a constant base themes directory, so you can store the current template directory name in the database, grab that value, append it to the base theme directory path, and feed that to the Twig_Loader_Filesystem() constructor for use in rendering.

  6. I want to be able to call init though... Init will end up with a lot more stuff yet.

     

    You'll be able to call anything protected or public in Init() from within Router(). If you don't need to do anything different with a method in the Router() class, don't define it in the Router() class and the call will bubble up to Init() automatically. For instance:

    class ParentClass{
    /**
     *	Runs because the constructor is called on the child class and not intercepted.
     */
    	public function __construct(){
    		print("<p>This is ParentClass() calling!</p>");
    	}
    /**
     *	This is public and can be called from anywhere
     */
    	public function doStuff(){
    		print("<p>Now ParentClass() is doing stuff!</p>");
    	}
    /**
     *	This is protected, so can only be called from the child class. However,
     *	we're doing more with this method by adding another line of output after
     *	calling this method from the child class.
     */
    	protected function polymorphismAtWork(){
    		print("<p>ParentClass() says 'hi!'</p>");
    	}
    /**
     *	Again, this is protected and can only be called from within a child class.
     */
    	protected function protectedFunction(){
    		print("<p>This method is protected!</p>");
    	}
    /**
     *	Not even a child class can call this method.
     */
    	private function privateFunction(){
    		print("<p>Nope. No access, thanks</p>");
    	}
    }
    
    class ChildClass extends ParentClass{
    /**
     *	This is public and can be called from anywhere, yet has nothing to do with the parent class.
     */
    	public function doOtherStuff(){
    		print("<p>This is ChildClass() doing other stuff!</p>");
    	}
    /**
     *	This adds additional functionality to the parent polymorphismAtWork() method.
     *	It can completely replace the parent class method, but here we're doing some
     *	work and passing the call to the parent version for it's own output.
     */
    	public function polymorphismAtWork(){
    		parent::polymorphismAtWork();
    		print("<p>ChildClass intercepts and says 'hello...'</p>");
    	}
    /**
     *	Even though the child method is public, the parent is private. This will throw an
     *	error.
     */
    	public function tryToAccessPrivateMethod(){
    		parent::privateFunction();
    	}
    }
    
    $inst = new ChildClass();		// This is ParentClass() calling!
    $inst->doStuff();			// Now ParentClass() is doing stuff!
    $inst->doOtherStuff();			// This is ChildClass() doing other stuff!
    $inst->polymorphismAtWork();		// ParentClass() says 'hi!' -> ChildClass intercepts and says 'hello...'
    $inst->protectedFunction();		// Fatal error: Call to protected method ParentClass::protectedFunction() from context '' in myExample.php on line xx
    $inst->tryToAccessPrivateMethod();	// Fatal error: Call to private method ParentClass::privateFunction() from context 'ChildClass' in myExample.php on line xx
    

    Output is in the comments.

  7. Don't instantiate Router from Init. Route extends Init, so all the functionality of Init is available to Router. You should be instantiating a Router object, not an Init object. In your Router::__construct() method, call

    parent::__construct();
    

    This will fire the Init object's constructor, and you'll get access to $root and $directorySeparator.

  8. Unless the images are enormous, 9 seconds overall is still a ridiculously long load time.

     

    Also, note that Zane isn't using in_array on a multidimensional array, he's using it on $val['Purposes'], which is a simple indexed array. It just so happens that the indexed array 'Purpose' happens to be contained within another array.

  9. You may want to consider an AJAX-based click event handler.

    $(function(){
    	$('.attack_enemy').on('click', function(e){
    		$.ajax({
    			type:'post',
    			url:'your-processing-script',
    			data:{
    				'username':$(this).attr('data-username'),
    				'attackverify':true,
    			},
    			success:function(data){
    				if(data.status == 'success'){
    					alert('You attacked, homie!');
    				}else{
    					alert('Sorry, looks like you tripped and missed.');
    				}
    			}
    		});
    	});
    });
    

    Of course, the details of your processing script are left out of this, and it's assuming you've added username as a data- attribute to the attack link. This way you're avoiding a page reload, and the data isn't as easily spoofed by the user. Of course, it's certainly not secure or concrete as listed above - you'll need take the proper steps to verify and validate the submitted data in both the JS and php.

  10. @requinix - thank you for your input and help.

     

    I'm not any closer to figuring this out, but digging through the code to scrub it for posting has brought to light some less than obvious things that are happening with regard to data-gathering setup that may be the actual culprit. Until I get a clearer idea of what's actually happening I'm not going to waste anybody else's time - hopefully I'll be able to figure it out on my own by digging further, but I'll certainly post back here f I still can't suss it out once I finally track down what's happening.

     

    Thanks again for taking the time!

  11. Thanks for the help - like I said I'll try to scrub and post the handler code tomorrow morning.

     

    What's strange is the API appears to be returning (I'm paraphrasing here)

    123 My Street
    <br></br>
    
    My Town, ST 12345
    <br></br>
    

    on dev, but

    123 My Street
    
    My Town, ST 12345
    <br></br>
    

    on production when I inspect the element. It's just weird.

  12. There's not - at one point, there's a bit of script that uses regex to remove the line breaks for use in a 'directions' link, but I haven't found anything that inserts a line break anywhere. And the directions link isn't involved in the actual address display - it's injected into a link offsite to Google proper.

     

    I'm at home right now so don't have the actual code to post - I'll try to scrub and post it tomorrow morning. And needless to say, I didn't write the original code, but it doesn't seem too difficult to follow. Of course, I say that rather glibly as I have no idea where the issue is...

  13. Hi y'all.

     

    I'm stumped on this and wondered if anybody had anything they could add or suggest. I've got a development version of a site on one server and the live version on another. Both use the same host, are using the same code, same data, same Google Maps API call, etc - everything is the same so far as I can tell. But, for some odd reason, on the dev site the address is returned with a line break between the street and city in the address. The live version does not have this break. It did until recently (like 2 weeks ago or so, I guess). I can't for the life of me figure out what that's all about, and if anyone's seen anything similar or has any ideas, I'd love to hear them.

  14. OK - I think I see what you're asking. You're going to want a change event handler for the dropdown outside the table that sets the value of the dropdown inside the table, something like this:

    $('#ddOutsideTable').on('change',function(e){
    	var curVal = $(this).val();
    	$('#ddInsideTable').val(val);
    });
    

    Please note this is entirely untested code, so there may be a grammatical or logical err in there.

  15. Example2 doesn't have NumberInput() or NumberOutput() methods, it has numberInput2() and NumberOutput2() methods. In the constructor function, you call and instantiate a new instance of the example() class, but don't actually do anything with it. That's the class that has numberInput() and numberOutput() methods. So, when you call NumberInput() on the example2() object, the magic method __call() is catching that call to a non-existing method. If you look at the description for the __call() magic method, you'll see that the $arguments parameter is an enumerated array, which is the output you're getting.

     

    It looks like what you're attempting to experiment with is class inheritance and polymorphism. Consider the following long-winded and inane example:

    class Example{
    /**
     *	@var	int		An integer
     */
    	protected	$_number;
    /**
     *	Because $this->_number is protected, you can't access it directly from outside this class
     *	This method allows the user to set the value of $this->_number
     *	@param	int		$num		Number
     *	@return	void
     *	@throws	Exception		When the submitted value is not an integer
     */
    	public function setNumber($num){
    		if(!is_int($num)){
    			throw new Exception("That's not a number, you twink!");
    		}
    		$this->_number = $num;
    	}
    /**
     *	Again, $this->_number is inaccessible. This returns the value of $this->_number to
     *	the user.
     *	@return	int
     */
    	public function getNumber(){
    		 return $this->_number;
     	}
    }
    
    class Example2 extends Example{
    /**
     *	@var	 string		A greeting
     */
    	private	$_message;
    /**
     *	This will be called every time you instantiate a new Example2() object.
     *	It sets the value you pass into the class in the private $_message variable.
     *	@param	string	$msg		A greeting
     *	@return	void
     */
    	public function __construct($msg){
    		$this->_message = $msg;
    	}
    /**
     *	This public method will overwrite the parent class's getNumber() method and return the value
     *	of parent::$_number plus 2. Because I felt like adding 2 to it. This is polymorphism - it serves
     *	the same purpose as the parent method, uses the same implicit API, but returns a different value;
     *	the calling code knows it can call this method and get something back that it can work with, but
     *	it really doesn't care *what* it gets back.
     *	@return	int
     */
    	public function getNumber(){
    		return $this->_message." :: ".$parent->_number + 2;
    	}
    }
    
    $class = new Example2('Well hi there! This is a number');
    $class->setNumber(42);
    print("<p>".$class->getNumber()."</p>");
    

    When this is run, it outputs "Well hi there! This is a number :: 44". The call to setNumber() on $class will bubble up to the parent class, where there is a method called setNumber(). Note that the Example2::getNumber() method refers to $parent->_number directly - because $_number is Example is protected, the child classes can do that. If it were private, this would cause an error and the Example2() class would have to use $parent->getNumber() from within it's own getNumber() method.

     

    Hopefully that makes some sort of sense and will help put you onto the right track.

     

    I'd also recommend checking out PHP Objects, Patterns, and Practice by Matt Zandstra - it's well written, clear, and explains a lot. Highly recommended.

  16. You've got issues with the backticks and quotes in your update query.

     

    UPDATE avaliacao SET `nota` = '$nota' , `comentario` = '$comentario' WHERE `íd` = $id

     

    Honestly, you only need backticks when your table or column names are a reserved word, which I don't believe is the case here, so you shouldn't need them at all. All strings have to be enclosed in quotes. I've updated your query in red above.

     

    Of course, the bigger issue is that you've got no validation or sanitization at all.

×
×
  • 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.