Jump to content
Larry Ullman's Book Forums


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Stuart

  1. After posting I decided to stop reading forums and the docs and jump into the source code. You simply have to set the captchaAction using a route: $this->widget('CCaptcha', array('captchaAction'=>'feedback/captcha')); This wasn't that apparent to me when reading the docs but the source code comments provide an explicit example. So now I can render the CAPTCHA widget in the main.php and it works great! Sorry for wasting people's time who read this... its been a long few days
  2. Hi, Not been on here in a while! Doing lots of Yii work though so should be able to start helping people out now the books out. Bought a copy last week - only had chance to browse and already looks like it explains concepts far better than the other Yii book I have! I want to render a form inside a modal window that is part of the main.php layout file. The form needs a CAPTCHA which is where my problems start. Adding a CAPTCHA directly to an action's view works fine but as soon as I try and do it from main.php I'm running into all kinds of problems. It seems unless I'm on the page the form points to I have to enter the CAPTCHA twice - some issue where the value must be getting set twice/overwritten? At the moment I've had to add the action and access filter to all of my controllers (which I know is disgusting) but I can't see how to make this work? Thanks Stuart
  3. I don't have a copy of this book and you haven't posted any of the relevant code so it's difficult to say for sure. Looking at the code from the downloads section I suspect that's coming from the else clause of: if (mysqli_affected_rows($dbc) == 1) { // If it ran OK. This means that your database INSERT query is failing - possible causes: Database user doesn't have INSERT privileges Table structures does not match that at localhost causing a syntax error In the else clause where you have: trigger_error('You could not be registered due to a system error. We apologize for any inconvenience.'); Add a call to: echo mysqli_error($dbc); This will return more information about your specific database error.
  4. Thanks for your replies guys. Indeed Antonio the apps will be storing the primary key in their local storage and passing this up during any updates - deletes handled simply by their lack of presence in the uploaded data. As tempting as a NoSQL solution is in terms of the coding elegance of simply storing the objects I don't feel I know enough about NoSQL solutions in terms of security to ensure the protection of millions of people's data at this time. Some of the security features are either not present in NoSQL solutions or would require rolling my own versions. So for now at least I'm sticking with a the more mature MySQL database (time permitting I might build both to see which produces the best product in terms of security, scalability and elegance. Thanks again for your input.
  5. In a current project I have a large database that basically holds people and their personal information e.g. each contact can have multiple phone numbers, email addresses, residential addresses etc... As a result data security and integrity are very important. I started of sketching out the database schema and it seems fairly straight-forward. I'd create a people table which contains the individual people and then a series of other tables to hold their personal information each in a one-to-many relationship. E.g. Each person can have multiple phone numbers. All seemed fine until I started thinking through the use cases. If someone updates their mobile number and saves their details I would essentially have to delete all their numbers and then add them all again because you can't easily tell if details were deleted, updated or inserted to the contact. I think any effort to package the existing ID with each number would simply be messy. So first, is there anything wrong with deleting and re-inserting all one-to-many relationships? It will lead to big gaps in the primary key which I guess can be fixed by calling something like repair etc... For reference this database will have several million users. This seemed messy so I considered storing the one-to-many relationships as serialised objects within a single table because then I wouldn't have to worry about maintaining FK relationships and having large gaps in the primary keys. This led me to looking at NoSQL solutions as this seems to be basically what they do. I read the mogoDB article from Larry's newsletter and thought it might be worth considering. Any thoughts? PS. In general I only have to update or fetch the objects I don't have to search based on a phone number etc...
  6. Been thinking about this again tonight... is there any need to create a filter - couldn't I just customise the actionCreate method? Or is that bad practice?
  7. I know this issue is kind of cleared up but just explain a little more if you're interested. Your first example and second example are not the same - there are subtle nuances between the two. The first is considered in ECMA script as a function declaration while the second is considered a function expression. The differences are explained in the ECMA script spec. Basically (as you've described above) function declarations are parsed and evaluated before any other expressions are - irrespective of where that declaration is positioned in the source code. Another interesting point I found out today is that a function declaration cannot appear 'in block' e.g. within IF conditionals or any loops. Although they may work their implementation cross browser is not guaranteed in accordance with ECMAScript - this is where function expressions should be used. So not a quirk of the JS engine but intentional apparently.
  8. I'm starting to get to grips with Yii at last and am finding making progress slow. I've offered to build a forum for a network of local sports teams to let me dabble in Yii with no deadline pressures. I've read most of Agile Web Application Development endorsed by Yii and your blog articles on it but am still struggling. I used the forum schema from PHP 5 and MySQL 6 ed 3 adding a clubs model which sits above the users model and made a few adjustments to fields. I've used Gii to create models and CRUD functionality. In the forum chapter of your book you basically accept a post and then check for a thread/topic ID - if it's not present you create one. I can't quite get my head round how to achieve this. My best guess so far is to add a property to the PostsController called $_topic and then create a filter inside the PostsController that's called prior to the actionCreate method. In there I'd check for a topic ID in the POST array - if it exists assign it to the property if not do something like: $topic = new Topics; $topic->topic_title=$_POST['title']; if($topic->save()){ $this->_topic = $topic->getPrimaryKey(); } else { // Throw exception } Is that along the right lines? Any general pointers on what I need to do to create a forum greatly appreciated too. The book isn't the best (how long until your Yii book will be done Larry?) and the docs are only useful once you've got a little more experience. Thanks
  9. Prepending an IF statement with ! flips the value of the variable. So if $live is set to FALSE then: if(!$live) { //show the error in the browser Returns TRUE meaning the next code block is executed. So when the $live flag is set to FALSE the following code is executed: echo'<div class="error">'.nl2br($message).'</div>'; However when you change the value to TRUE the IF statement evaluates to FALSE meaning the ELSE block gets executed: //send the error in an email; error_log($message,1,$contact_email,'From:admin@example.com'); //only print an error message in the browser, if the error isn't a notice. if($e_number != E_NOTICE) { echo'<div class="error">A system error occurred. We apologize for the inconvenience.</div>'; }
  10. The password policy enforced by Larry's scripts via the REGEX only allow for letters, numbers and the underscore. Not sure if there's a technical reason for not allowing spaces in passwords but if you want to remove trim then you might aswel alter the REGEX also to allow for spaces. A lot of sites I can think of don't allow spaces in the password - presumably there's some reason for this. If you want to create more secure passwords enforce the use of upper and lowercase characters, numbers and symbols and a minimum length of say 8.
  11. You don't have the CURL extension enabled - run phpinfo() to clarify.
  12. Pretty sure you could use strftime() and set the locale to something like ar_SA.UTF-8 using setlocale().
  13. Never used stored procedures but it looks fairly straight forward that the SP select_products already exists. If you want to re-create it again: DROP PROCEDURE IF EXISTS select_products; Then run your code again.
  14. Common reasons for you not seeing step 2 here might be: Error in your query syntax but error reporting is not turned on e.g. column name mismatch Password column is defined as CHAR(32) it should be CHAR(40) You have more than 1 row with the same content e.g. Duplicate entries The password was originally stored in plain text not SHA1 hashed See if any of those apply.
  15. Well based on your last post the problem is that SHA1 produces a 40 character string (MD5 produces a 32 character string) so change password to CHAR(40), recreate the account and it should work fine.
  16. It's not, what you're doing here is creating an array of products where the key is the SKU and the value is the quantity. In HTML if you specify a name appended with [] it produces an array when submitted to the server. Hence this line: foreach ($_POST['quantity'] as $sku => $qty) { It doesn't the name of the array is quantity and the key is the value of sku not actually 'sku' as a string. Not sure how clear I've made that so here's what the POST array might look like on submission for these products: Toy Car SKU: 14 Quantity: 5 Boomerange SKU: 12 Quantity: 1 POST array would look like: $_POST['quantity'][14] = 5; $_POST['quantity'][12] = 1; So when you loop through the key identifies the product by SKU and the value represents the quantity of that product. Hope that makes things clear.
  17. If you're receiving: It's the num_rows check that's failing (difficult to see, wrap your code in code tags in future) so easiest thing to do is echo out the value of $q (don't just assume you know what's being run) and run that directly in PHP MyAdmin to see what MySQL related issues are occurring. It could be that you actually have 2 rows with the same details and hence it doesn't equal 1 but 2 etc... Let us know the outcome of that
  18. Also just a note to Paul HAVING clauses are used to essentially replace WHERE clauses for the reasons you posted. They only work for grouping functions like SUM(), COUNT(), MAX(), MIN() etc...
  19. I'm on a train using my phone so no idea how accurate this code will be but this is the basic premise (might need to play around with brackets etc...) $q = "SELECT store_id, subselect.distance, FROM (SELECT store_id, latitude, longitude, ((DEGREES(ACOS(SIN(RADIANS($latitude)) * SIN(RADIANS(latitude)) + COS(RADIANS($latitude)) * COS(RADIANS(latitude)) * COS(RADIANS($longitude - longitude))))) * 69.09) AS distance FROM table) AS subselect WHERE subselect.distance < 1 ORDER BY subselect.distance ASC LIMIT 10"; From your previous posts I seem to remember the dataset is quite extensive. If performance becomes an issue I'd recommend dynamically creating a smaller dataset each time based on a bounding box. E.g 10 miles from the current location as a square - this allows you to eliminate most of the irrelevant datapoints and only query against decimal numbers e.g. latitude BETWEEN 39.00 AND 41.00 (numbers from thin air btw). Then run the full query to get accurate values. Let me know how you get on.
  20. What debugging steps have you taken so far? What versions of PHP and MySQL are you running? Things to consider are: 1) Are you logging in from http://domain.com and being redirected to http://www.domain.com? If so it's classed as a new domain and a new session will be started. Could check this also by echo'ing out sessIon_id() on both pages. 2) Try using print_r($_SESSION) to see what data is being stored, if any. Also in general you should check the index exists using isset() first before trying to access a variable. Let us know how you get on - and post more detail so we can give better help.
  21. I'm not sure why I didn't pick up on that before I did this exact same thing about a year ago and had the same problem. I'm not sure a HAVING clause will work (I may be wrong) I know at the time I used a sub-select/query to achieve the desired effect.
  22. This seems a little strange... so after the PHP error gets thrown call: mysqli_error($dbc); to get the actual MySQL error - I doubt it will be particularly useful. Or if you run it directly in PHPMyAdmin what is the result/feedback? Also can you echo out the actual queries I appreciate you've only changed that one line but I find it's always best to be methodical when debugging something. p.s. where abouts in the UK are you based?
  23. This has been reported as a bug on php.net in the past and I haven't read it fully but detailed somewhere in RFC3696/RFC5322 a domain omitting the TLD is valid as mail() can be used to send local network mail to an email omitting the TLD. Quote from Rasmus on the bug report: It's something I wasn't aware of so thanks for bringing it up - as this local network issue will never be relevant I may now move to a REGEX method using FILTER_VALIDATE_REGEXP. A regex doesn't stop people putting in fake emails though so you should still send a validation email - but it does catch most typos.
  24. Hi Matt, That's the correct behaviour the request being made will always be set e.g. one of: GET, HEAD, POST or PUT. When you access a page normally the request type is GET irrespective of whether any parameters are actually passed in the URL. So it shouldn't be FALSE it will be TRUE unless you're making a POST, PUT or HEAD request. Rather than removing && isset($_GET['p']) instead remove: ($_SERVER['REQUEST_METHOD'] == 'GET') && And then just leave the rest of the else statement alone and it should work fine.
  • Create New...