Jump to content
Larry Ullman's Book Forums

Antonio Conte

Members
  • Posts

    1084
  • Joined

  • Last visited

  • Days Won

    126

Everything posted by Antonio Conte

  1. It depends. More often than not, application breaking errors should throw exception. As an example, an invalid date, improper email addresses or bad zip codes could benefit from throwing exceptions. The reason for that is data integrity. A class/function could very well be dependent of having valid data on a special format to be able to perform actions/calculations of it. You'll often see people defining their own exceptions like so. In this example we have a example class for sending email. It's no point sending an email to "111lol!", so then it's good practice to throw an exception. ( class Email { public function send( $email ) { if (! filter_var($email, FILTER_VALIDATE_EMAIL)) { throw new InvalidEmailAddressException("Invalid email adress provided."); } } // Email exception class InvalidEmailAddressException extends Exception { public function __construct($message) { parent::__construct($message); } } Hope that gives you a general idea. Short answer would be this: for "checking values", use return values. User::add() could return true/false on how the adding went. For invalid values that could break classes/methods, throw exceptions.
  2. I don't think those values make sense as they are perfectly legal values that COULD point to a horse. I don't think there's a need to use different values eighter. Use null, -1 or 0 as they won't appear as keys. As I said, could you provide simple data for 10-20 horses? It would make it much easier to confirm we have the right algorithm. Now, I have to create example data by myself. It would sure be easier to work with some real data. Just do a print_r() on the result from a query, and you'll have those example for us. I think we could make this work pretty quick.
  3. Yeah, I figured that out. My problem what not really the solution, but the structure of the solution. The logic was more cumbersome than it needed to be. When a user struggles to follow the logic, and it's easy fixable, I would argue that it is bad code. While my code did not use the error codes, it was easier to read and understand. It's really all preference, but simple code is often good code. I think you've improved the login code, but it could be even simpler. I don't like long if-statements and I don't like else when dealing with return values. I would argue this is very easy to read and understand public function login() { if($this->_identity !== null) { return; } // User already logged in // Authenticate credentials $this->_identity = new UserIdentity($this->username, $this->password); $this->_identity->authenticate(); // Check authenticate response if($this->_identity->errorCode === UserIdentity::ERROR_NONE) { $duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days Yii::app()->user->login($this->_identity, $duration); // User was successfully logged in! return true; } // Wrong username/password-combo return false; } Regarding your activation codes, you could optimally create a model for handling that logic, but I think that code looks good enough really. Great progress, Edward. You've come an incredibly long way since you started posting here. Keep it going!
  4. Very good. Thanks for providing some context here. That you want a reversed order starting with the latest child is important. Without that, it's hard to provide data. Considering that, the OLDEST generation need to reflect that in the DB. I'll assume you use NULL on father_id and mother_id for that generation. (Or 0, -1, "" or some other value) Starting with Child X, we need to find father X and mother X and repeat (until the father/mother is null). This sounds like a binary tree. Solutions here requires a good algorithm not be very slow. We therefor need to make sure of your needs first. My question is: What are you going to use this tree for? Do you only need to print the generations from newest to oldest, on something like this form: Last Child Father of child Mother of child Father of father of child Mother of father of child Father of mother of child Mother of mother of child Father of father of fater of child Mother of father of fater of child Father of father of mother of child Mother of father of mother of child Father of mother of fater of child Father of mother of mother of child etc.... ? I need to be able to visualize what you want to do determine how to solve this. If you have some data in your database, could you attach that here as well?
  5. Pretty much impossible to follow your logic without some example data. I'm not a horse expert and don't intend to become one. Secondly, how will you display it? Printing it to a div instead of an unordered list tells me exactly nothing about what you want. I don't even have any code to judge this by, so I can basically do nothing more for you than teaching you recursion theory, which Larry already does brilliantly in the book. Sorry for being a bit direct here, but there's literally nothing anyone can do to help you by looking at your post. Try again. Explain the problem not using horse terminology, provide example data, provide code and provide an explanation of what you need to do to explain everything as intended.
  6. Good guy Jon here. Nice gesture. Marie: Get a nice IDE. It will help you a lot. Those syntax errors will be highlighted and easy to spot. I can recommend Eclipse or Netbeans. Besides having "Projects", an IDE is really only a powerful text editor specialized for coding. A project is simply something used to organize your code with. Create a new "Marie's website" project, move your files into the folder created, and you are ready to go. Both are free. You should figure it out quickly, and never look back. The benefits are so great that you should switch instantly. Don't remember a function name? Start typing, and it will suggest for you. Don't remember variable names? Ide will keep track. Errors in code? IDE will tell. Download Eclipse here (Download links to the right)
  7. I think you should scrap the whole idea of a form function for creating the HTML. It just makes thing to complicated. There two flaws in your code. First, your textarea has a name attribute, but no id. Inside the JS function, you try to get the element by ID, not by name. Secondly, the line with "countRemains" needs to be closed with a semi-colon. The function will not work because of that. I would recommend you looking at a plugin for your browser called "firebug". It can spot JS errors for you, and you can debug JS values by using console.log() with variables. It will help you a lot.
  8. You have basic syntax errors here, Marie. The single quotes in 'thats all folks' is regarded as PHP because you use echo above
  9. Looking at the manual, the CAssetManager is not intended for the purposes you describe here. The class is for handling site asset management, not for working with user assets. I would instead look at this wiki entry. I would look into creating a model with a belongs_to relationship to the Campaigns. That way, you can define logic for creating/removing folders and handle file management inside the class, using information like campaignName for the Campaign model. Just my two cents as this was urgent. I know something like this would be easy to implement. I must admit I've never worked with YII myself, only reading about the framework.
  10. Hey, folks. Kind of curios here. Most of the people here work with PHP, some daily. We all know the language is not perfect by any stretch of the imagination. We still kind of love it regarding all it flaws and quirks. The topic here is to provide your stories about bad encounters you've had with PHP. Weird bugs you have experienced, weird checks you've had to perform, problems with type casting, etc. This is friendly bashing As we love PHP, the point here is not to hate to hard on PHP. It's meant as a fun and informational topic. Keep in mind, though; If your love for PHP is really strong, something said here might hurt a little. The goal is not to get people to switch to other languages or start a flame war. It's all fun and games. To provide some context, there are tons of articles bashing PHP. Some of them are totally missing the point, some are written by fanboys of other languages, but you'll find some traces of truth in these articles. As much as PHP might be the perfect tool for web development, it obviously has its share of flaws. Why PHP is good It gets the job done. It's possible to find good and affordable hosting. It has a large and helpful community. There's a ton of books and tutorials for the language. The learning curve is not to steep. It's possible to create great application if you know the language. PHP has lots of frameworks that helps remove the quirks. There's ton of reasons why Python (Django), Ruby (Rails), ASP(.net) or Java (Play!) is not the most widespread languages used on the web, and most of them stem from this reason: PHP does what it's created for rather brilliantly. (At least recent versions) Things are moving in the right direction for the language, though. It's important to know about PHPs weak spots to be able to work with the language. Providing such information is important to help the language grow and inform people about the quirks. So. Tell us your stories. Tell us why you like PHP. Tell us why is sometimes s*****.
  11. The most important thing is to be consistent. Without concistency, things might get confusing. PHPs core functions is a horrible example of this. Chaos. The next thing is conventions. You should strive to follow them, at least closely. Use camelcase for YII attributes and underscores for database tables and names. The most important reason for this is because others can easily identify when you work with YII and when you use Active Recors for DB manipulation. It's important to tell those apart quickly for several reasons. Coding style is subjective, and you'll find a lot of strong opinions on this. I think the most important thing regarding coding style is making code readable/scannable. We are not machines, so strive for readability, define good function names, and write good documentation. If a variable will make your code easier to understand, then use it. I actually adopted my code style on a collaboration project last year. As it was his projects, I followed his code style. The main reason was consistency, as inconsistence code is bad code in my opinion. I really liked his style, so I started using a modified style daily. Here's some things I like to focus on when I write code: - Write readable, simple and elegant code. I like my methods when they can almost be read like normal english. - I think a lot before I start coding. I like to have a clear layout in my mind about the end result. - Use time finding good method names. They should be clear and consistent - I use longer, more describing names for private methods - Responsibility. Try to make sure one method performs one task. This may not be optimal in all cases, but generally will. Db::connectAndQuery($query), User::authenticateThenLogin() or File::uploadIfValid($file) are examples of methods that do to much. - Identify the exceptions. Throw exceptions early on to not waste resources. - Don't nest if statements to deep. I try to never nest more than one if, but I will break this rule for readability. A lot of nested ifs-else can often be solved differently, and will be more readable. - Identify code duplication and split those into new (often) private methods. - Offer methods that will cut down on application logic. e.x hasNext(), resultsExits(), or even isValid() (that may be a terrible name in some cases) These are my personal rules. They are breakable, as the goal is good code, not the rules themselves. My favorite type of data structures are tree structures. They can be very clear and simple, elegant and done with small amounts of code. Unfortunately, PHP code can never look as beautiful as a strongly typed language, but It can at least be readable. Cool topic, Edward. I love such topics for several reasons.
  12. No, sorry. Only for Norway. You have a point, but there are strict but simple rules for normalization. Figuring out when to denormalize is much more tricky, but should also be possible to set general rules for. As Larry has done this for a while, I'm guessing he can identify cases where both practices would make sense. You also need to remember I'm a student. What's good enough for my personal projects might not be good enough for large systems developed by a company. Having some general ideas on when to denormalize could therefor be important. You should never stop learning new things. I'm not asking this to go denormalize projects that already work.
  13. Thanks for a great answer. I tend to be rather strict about normalization, mainly because I have little experience breaking the normalization rules. I can definitely see the benefit in doing so, but I guess rules for when to break the rules is hard to determine. Figuring out when to apply it is rather tricky. Do you have a rule for that yourself? As an simple example, could you identify when it would be ok to denormalize the table Postal and when it would not? Again. This is mainly curiosity on my part.
  14. This is why I ask. You have five times my experience, so maybe I'm missing something here. I might be confused by the two terms "belongs to" and "has one". Having some experience with normalization, I would rather stick to the term "one-to-one relationship" instead. I'll instead give you some examples, so you can judge my reasoning. 1) Person and Country: The Person has one nationality, and in this situation, dual citizenships are ignored. Person ( id, firstname, lastname, country_iso*, .... ) Country ( iso, country, .... ) 2) Customer, Postal and Province: Customer has an address located at a postal code, located in a province. Customer ( id, name, postal_id*, address, ... ) Postal ( postal_id, postal_name, province_id* ) Province ( province_id, province_name ) Bold : Primary key Astrix: Foreign key --------------------------------------- Would you agree with such structures, or would you normalize them differently? Hope you can clear up some confusion here. Long explanations not needed though. I know you are a busy man.
  15. Looks very good. Looked some at the API. Found that there: "For models with autogenerated primary keys, the value of $this->id is available while afterSave() is running." Maybe you can let the models handle all this. That would be sweet.
  16. I save them in a table with ISO code as the primary key, so that's the same approach. I think it should be stored in the DB, though.
  17. This can absolutely be done via GET. What you would do is using IDs as the get value. Save the filenames to an array on the form ID => "name". You then build links the same way, but with ?remove=$ID. You cast $_GET['id'] to an integer, find the filename in array by using the ID, build a full path where you add the filename, then use unlink() to delete the file. An easy way to do this would be something like: $handle = ""; // open file $file_array = array(); // The file names while ( ($file = readdir($handle)) !== false ) { if ($entry != "." && $entry != "..") { $file_array[] = $file; } // Read files to array } // Simple delete if ( ! empty($_GET) ) { $upload_dir = "uploadsDirectoryHere/"; // Upload dir $file_id = (int) $_GET['delete']; // File_array ID // Make sure file is found if ( array_key_exists($file_id, $file_array) ) { $delete_file = $upload_dir . $file_array[$file_id]; // Make sure file exists if ( file_exists($delete_file) ) { unset(file_array[$file_id]); // Remove from file array unlink($delete_file); // Actually delete file here } } // Print out file names and links for deleting them foreach ( $file_array as $id => $filename ) { echo $filename . '<a href="page.php?delete='.$id.'">Delete file</a>; } Not tested, but that should be the basic idea. Sorry about errors/etc. Beginning to get tired here.
  18. I can assure you it would generally be an even bigger pain in the butt. I see that YII allows to to define a HAS_MANY relationship in your models "relations()" method. That way, you don't need something like a "UserFile" model you would else need. I'm guessing there's some kind of automagic done to each models (User and File) save method. That's pretty much a straight guess from my side, but I at least hope YII has implemented that. I'm just guessing you need to set the foreign key to a value, call save(), then let YII handle the rest. What I did in codeIgniter, was to define that said "userFile" model. On insert/update, two calls where applied with some transactions involved. On Read, simple joins. On deletes, only the files where affected. Btw: Larry. Don't agree with what you said about the has one relationship. If you want your tables to be boyce-codd/ENF3, those are mandatory. Postal numbers, country codes, favorite movie... One to one is mandatory in all these situation. I know you are completely aware of this. (as you've written about Normalization before) I'm wondering how I'm misinterpreting you here, or how I'm missing parts of the full picture.
  19. I would guess you just got to replace the old one. I'm betting there's not really any "update functionality" here.
  20. A private array is fine. It could even be static. About the restricted words, I would place that in a config file and pass that array into the function from there. That way, It's a lot simpler to change.
  21. Uploading images is not really the problem. I have solved that already. I went with a standard single file upload operation here. The audience is car retail dealers, and trust me, you'll find a lof of IE6, 7 or 8 there. In other words, not really any need for anything fancy. If I should rephrase that, I would say it's not really a priority at this point. I will definitely look at improving that later on though, so thank you very much for providing tips in that regard. What I try to do here is to attach/detach already uploaded images, identified by a primary key in the file table, to a car offer. This is what I tried to demonstrate by the $_POST key "attachments". As you can see, the "+"-button will add an image ID to a hidden input. This comma-separated String should then be used to add attachments to a table of this form: offer_attachments( attachment_id, user_id, file_id, offer_id ) I will set file_id and offer_id to unique, so the DB will prevent duplicates in practice. The current solution, as shown in my script, is not that good though. I'm stuggling with building attachment lists, add operations for detaching files, and for messages when an image is removed. Long story short. I think a JS array approach, where the array is converted to a comma-seperated String at submit, would be the best approach. This will allow me to push values to the array (and hopefully prevent duplication) on adding, popping the value from the attachment array on detachment (delete) and so forth. With these new information, I'm betting you can identify a simple way to do this. My problem is lack of experience with JS. I can't really identify a good approach for doing this. Edit: Updated post.
  22. It's for speed. If certain combinations are commonly looked up, assigning an index will speed up that lookup. It has no other functionality than that.
  23. As I said, you know how to do that: // Place this where the page requires admin level if ( ! isset($_SESSION['user_level'] or $_SESSION['user_level'] != 1 ) { header("Location: login-page.php"); exit(); } // Place this where the page requires user level if ( ! isset($_SESSION['user_level'] or $_SESSION['user_level'] != 2 ) { header("Location: login-page.php"); exit(); } Just think about what values the session holds. You can of course utilize that in several ways with very, very little logic.
  24. MySQL ties in perfectly with desktop applications. I've never done in Visual Basic per se, but I've done this in Java. A quick online search tells me you need to download the MySQL connector/Net 5.2 from MySQL. This is a driver that will let you connect to a MySQL database. You import this driver into your project, and add a connection function approximately as shown below: Public Sub TestConnection() Try Dim connStr As String = "Database=world;" & _ "Data Source=YOUR_MYSQL_HOST;" & _ "User Id=YOUR_MYSQL_USER;Password=YOUR_MYSQL_PASSWORD" Dim connection As New MySqlConnection(connStr) connection.Open() connection.Close() MsgBox("Connection is okay.") Catch ex As Exception MsgBox(ex.Message) End Try End Sub Switch out the uppercased words with your connect info, just like with PHP. In other words, It's your Mysql host, username, and password. Call the TestConnection() function to perform a connection. Now you can run normal SQL queries against this DB.
  25. Ok, Jon. I went with that approach. I've not really gotten it to work that great yet, but it does work according to functionality. I need a little help with formating/restrictions and user feedback, though. This is what I've done: - Added files uploaded by the user to a select element as options. - The option values holds the file_ids from the DB rows. - I use span to "add" attachments. This add button has a JS event handler listening to .click. - When .click fires, I take the option value and add it to a hidden input field. - Next add concatenates a new ID to the hidden input with comma-separation. - I toggle a success message telling the file was added. What I need to improve: - The same ID can be added multiple times. - How can I delete values from this String using the "[X]" elements? I'm blank here... - How do I get the file names? I want to show the file names inside the add/remove (bootstrap-) alert boxes. Some thoughts: - I think a JS array would be easier to add/remove IDs from. I just don't know how do that in a POST-friendly manner. If that's possible, then sure, let's go. - Maybe I should remove the select options already added by the user? That's a possible solution The option value is set to file_ids. I'm then using a span button to add these ID's to a comma-separated string. The string is then added to a hidden input field that will hold all files attached to the offer. This way, I can add these IDs to the offers_attachment table. I have tried to explain how this should work graphically in the file below. It's JQuery and bootstrap CDN'd, so it should work out of the box. Here's the file <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>File Attachments Bootstrap</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <!-- Le styles --> <style type="text/css"> body {padding-top: 20px;padding-bottom: 40px;} /* Custom container */ .container-narrow {margin: 0 auto;max-width: 700px;} .container-narrow>hr {margin: 30px 0;} /* Supporting marketing content */ .marketing {margin: 60px 0;} .marketing p+h4 {margin-top: 28px;} .hide { display: none; } </style> <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet"> <script src="http://code.jquery.com/jquery.min.js"></script> </head> <body> <div class="container-narrow"> <div class="masthead"> <ul class="nav nav-pills pull-right"> <li class="active"><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> <h3 class="muted">Attachment test</h3> </div> <hr> <div class="row-fluid form-horizontal"> <form action="" method="post" class="form form-horizontal"> <h3 class="controls">Attach files <small><a href="#">Upload new files</a></small></h3> <div class="controls"> <div class="input-append"> <!-- Users uploaded files from the DB --> <select name="files" id="files" class="input-xlarge"> <option value="16">Brazil.png</option> <option value="17">China.png</option> <option value="18">tsl_1.jpg</option> <option value="19">tsl2.jpg</option> </select> <!-- Add files to attachment via this --> <span class="add-on btn btn-success" id="add-file"> + </span> </div> <!-- Hidden input holding file IDs --> <input type="hidden" name="attachments" id="attachments" value=""> <p id="attachment-str"><p> </div> <br> <div class="controls alert alert-success" id="add-message"> <button type="button" class="close" data-dismiss="alert">×</button> <p>The file <strong>{filename}.{ext}</strong> added successfully!</p> </div> <hr> <!-- List of attached files with remove option --> <div class="controls"> <h4>Files attached:</h4> <ul id="filelist"> <li>Filename.png <a href="#"><i class="icon-remove"></i></a></li> <li>Filename.png <a href="#"><i class="icon-remove"></i></a></li> <li>Filename.png <a href="#"><i class="icon-remove"></i></a></li> </ul> </div> <div class="controls alert alert-error" id="delete-message"> <button type="button" class="close" data-dismiss="alert">×</button> <p>The file <strong>{filename}.{ext}</strong> was successfully removed!</p> </div> <div class="control-group"> <div class="controls"> <h3>Save offer</h3> <button class="btn btn-success" name="save" value="save" type="submit"> <i class="icon-ok-sign icon-white"></i> Save and Publish </button> <button class="btn" name="save" value="draft" type="submit">Save draft</button> </div> </div> <hr> <?php if ( ! empty($_POST) ) { unset($_POST['files']); unset($_POST['save']); // Remove keys not needed // Debug array echo '<h5>POST DATA</h5><pre>' , print_r($_POST) , '</pre>'; } ?> </form> </div> <hr> <div class="footer"> <p>© Company 2012</p> </div> </div> <!-- /container --> <script> $(document).ready(function() { $("#add-message").hide(); // On click, add select value to hidden input $('#add-file').click(function() { var file = $("#files").val(); // Get select value var files = $("#attachments").val(); // Get current input value var str = ( files.length > 0 ) ? files+", "+file : file; // Add int to String // Assign string to input $("#attachments").val(str); // Toggle file added message $("#add-message").show(500).delay(800).queue(function(next){ $(this).hide(500); next(); }); }); }); </script> <!-- Le javascript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script> </body> </html> Thanks in advance to anyone helping.
×
×
  • Create New...