Jump to content

MindFull

Members
  • Posts

    106
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by MindFull

  1. You could also turn on mySQL's general_log and then tail -f the log file while you step through your code during debug.
  2. Yeah, answers will vary depending on your page and template structures. If there is a city template (each city has it's own unique page), then you could pull all or some of the cities using something $pages->find("template=cities") and then just echo out that city's url using a foreach loop. I believe the skyscrapers profile has a pretty good example of that. Otherwise, you could use the good ol' switch statement instead of a bunch of if/elses. Give us more details and we'll be able to help you further.
  3. It sounds to me like your code is iterating through the $products (pages found by some selector I'm assuming) but some of those pages don't have the images field filled with anything, resulting in your error. Try to validate $img_src like this: foreach($products as $product){ $img_src = $product->images->first(); if($img_src) { // Check $img_src echo $img_src; echo $img_src->url; echo $img_src->size(300, 300)->url; } /** Let's see what pages don't have the images field set to anything **/ else{ echo "<br/> The page " . $product->name . " doesn't have the images field set to anything. <br/>"; } }
  4. For me, it looks more like this: I get asked if I can build a site I make an offer and they accept it After that I write the bill, and they pay Now I begin building I upload a beta on my server and we put content in and do changes until it's ready I move it to the client's server (if they already have one) or recommend a hoster (sometimes with a little provision) Now we're done My approach used to be a lot like yours but I've learned to take this approach throughout the years because too many times I've had clients decide at the last possible moment that our initial agreement was out of their budget or that the site wasn't as important to their business model as they initially anticipated. The company I work for doesn't write a single line of anything unless the client has agreed both on paper and with their payment that the work should commence. No partial payment, no half now and half later. I've followed their lead in my independent work and it's worked out much better for me since I started doing this. I ensure clients get what they are asking for and work with them every step of the way until it's done. As far as offering maintenance, I only offer what's needed and what I have the time to do. I offer small packages based on my hourly rate, with a little discount. This way, if they need something like a new template file, pages added, database backup, etc., they don't have to pay me a-la-carte, it's all inclusive up to the agreed number of hours and the hours don't roll over into the next month. Sometimes, with certain sites, I don't offer this at all because of the site would need a more dedicated schedule to maintain it properly. These things are usually discussed at the onset of development, to give them a clear picture of where I'll be after the completion of the project. I used to resell web hosting, I stopped after sites would slow dramatically due to resources not being available (being oversold, even on VPS) or server halts. I don't like being in a situation where people are looking at me to do something about their site being down and them losing money when I don't have any control over the hardware. All you can do in that situation is call whoever your provider is and complain - but that doesn't help your client feel any better! I like being responsible for what I can readily address, not for things out of my hands.
  5. My goodness, I was so caught up in the db side of things that I completely forgot to think about approaching this through the API!! This alleviates having to keep track of the auto increments in mySql - awesome! I love this forum and this API! Thanks for your input sforsman! I feel much more confident with this approach than my previous ideas. Very simple and elegant, no wonder I overlooked it! I have a tendency of doing things the hard way, . I'm going to write the hooks for this tomorrow when I'm back @ work and see how things pan out. BTW, have you had the opportunity to try both Tungsten and Symmetricds? What's your opinion on Tungsten in comparison to Symmetricds?
  6. @sforsman Templates and modules will be included when a separate set of sync triggers are turned on in the config of Symmetricds. Typically, they won't be part of everyday syncing as they won't be changing or being added very often and only the corporate office will have permissions to add/edit/remove fields, templates, and modules. Yes, the changes will be pushed from corporate to all the branches. There might be a separate table to handle some possible infinite row data that we will be writing a separate class for to handle querying its contents. All other pages will be batched and channeled according to their relation to one another. There will be rows that will be exempt from updates after initial insert, like the page created timestamp and some other template defined ones. But, for the most part, most of the front-end submitted data will be subject to sync. On average, there will be about 300 writes daily in each branch office. There are 3 full time shifts taking up all 24 hrs of the day. As far as preventing branch writes, it just can't be allowed. The employees collect client data on a frequent basis and need to be able to store it immediately or they risk forgetting the details as the day goes on. That's the company's initial reasoning to having the local DB: VPN goes down, they have can keep going with the bulk of their work which is data collection of their clients locally. Tomorrow I begin planning the data flow and transformation charts and I'm not particularly thrilled about that part of this project - lol, I hate diagramming in UML!!!! BTW: Thanks for taking the time sforsman!
  7. Edited - sforsman beat me to it
  8. @sforsman The VPN shouldn't be down often. The only time it realistically should be offline is when there are problems with the ISP or internal networking issues. Maybe even for the split moment that new certs/keys are issued and updated. So the anticipation is that we maintain on online average of 99% or better throughout the year. Even still, that is about 87 hours of anticipated downtime. The corporate node will be scheduled to pull every 10 minutes or sooner. It's very probable that the company will have more than 9 offices in the next 2 years, they have 6 already. I'm sorry, I meant to put that in the paragraph below it where I said I would write custom definitions to handle the page indexes. Symmetricds was selected because the company already uses it for its existing databases and I have familiarity with it (though not in an all-master topology). I'm not biased and open to using different software as long as the learning curve isn't mountain steep; time is of the essence. I have never used Tungsten, though I have read a number of articles that referred to it and it seems much along the lines of how Symmetricds functions. Any advantages of using Tungsten vs Symmetricds would be appreciated. Thanks for the link. I've never read it before but it is quite informative and a great refresher. I like #5, "make the triggers harmless...". That should be fun to work through when I begin testing. I'll be keeping the original .sql file on hand for immediate importing.
  9. Ok, so I have a new project that has PW as the selected framework of choice. Here are some of the constraints I'm working with: 1) The corporate database will replicate all the other branches data. 2) Each branch will have it's own web and database servers, thus run their own instance of ProcessWire and all data will be saved within the intranet. 3) Each branch will be able to access the other branches install via VPN. The web servers/code base will be synced using Git. 4) Each branch's database server will have a Symmetricds node installed. Via VPN, each node will push/pull to the corporate node, keeping the databases synced. Symmetricds allows for table and column specific updates so the whole db won't be getting replicated on each pass. 5) The database sync needs to be bidirectional, as in Multiple Master Replication. Reason being, the company plans on having certain departments add pages directly to the corporate account that will affect the other branches. For instance, the Human Resource department will handle adding/removing users and maintaining records on them. Each user created by HR will need to be able to access any branch's data when on the VPN. So user pages would need to be pushed to the branch db's. Here's what it would look like: // Inside Branch 1's Building: Client 1------via intranet---------------Web Server 1-----DB Server 1 // Connecting to remote Branch 2 from Branch 1 Client 1------via internet (VPN)------Web Server 2-----DB Server 2 // Database syncing DB 1-------------via VPN-------Corporate DB 1 and vise versa (bidirectional) DB 2-------------via VPN-------Corporate DB 2 The schema between all databases will be exactly the same. So, initially, my game plan was to change mySQL's auto_increment_increment and auto_increment_offset on each db instance, keeping the different branches on separate indexes when pages and fields are stored. Hopefully, this would cause a mostly conflict free environment. Also, this limits my approach on dealing with expansion. Once 9 offices are established, I'm going to have to start getting creative with the increment patterns. I suggested a cloud based approach but they insist on using their current infrastructure. My other idea was to write transaction and conflict rules into Symmetricds and allow it to make changes to page ids, etc and any references to such in the db. The real danger is when there is a mass building of pages when the VPN is not available, like an internet outage. Once the internet is back online, there could be a lot of pages that need to be replicated; with the likelihood that many pages end up with the same exact page id's, etc. Anyway, does anyone here have any advice as to what they would do? I'm open to hear opinions of what others have done in this same sort of scenario before I choose my path.
  10. Fixed it so it won't confuse others
  11. @Muzzer - Nope, that line was a stray, lol. I was eating Capt'n Crunch, thinking, and typing all at once. Glad the rest of it was of use though!
  12. Did you try what Diogo mentioned about the looping of the pages? foreach($matches as $m) { $out .= " <div class='media col-md-3'> <a href='{$m->url}' class='list-group-item'> <h5 class='list-group-item-heading'>{$m->title}</h4>"; foreach($m->food_types as $ft){ // Iterate through the pages here $out .= "<h5 class='list-group-item'>Type:{$ft->title} </h5>"; // Output the title here } $out .= " <p class='list-group-item-text'>{$m->body}</p> </a> </div>"; }
  13. Sure, you can do whatever you want with PW! Put something like this in your template file, or change it to extend the WireArray class if you'd like // Adding the method "suhosinRandomTimed to the WireArray class $wire->addHook('WireArray::suhosinRandomTimed',null,'suhosinRandomTimed'); // Define the method, I added $num and $seed to make this easy to demonstrate function suhosinRandomTimed($event, $num = 2, $seed = 'Ymd') { $pages = $event->object; // This is the WireArray object, more than likely will be pages if(is_string($seed)) $seed = crc32(date($seed)); srand($seed); $keys = $pages->getKeys(); // changed all instances of $this to $pages since I'm not defining within class $items = $pages->makeNew(); while(count($keys) > 0 && count($items) < $num) { $index = rand(0, count($keys)-1); $key = $keys[$index]; $items->add($pages->get($key)); array_splice($keys, $index, 1); } $event->return = $items; // return the pages } $p = $pages->find("template=someTemplate")->suhosinRandomTimed(); // Call the method on the results of $pages->find echo $p->render(); Just change the function's body to do whatever you need it to be and you should be good.
  14. Makes me want to brew some coffee right now...
  15. Not sure if you actually need a deep copy with what you're doing but you can also get a deep copy by overriding the __clone method in PHP within a class of your own. See here for details http://php.net/manual/en/language.oop5.cloning.php
  16. Because PHP will assign an object pointer to a variable when trying to use the = operator to duplicate an object. It's passed by reference, so to say, though I don't like to define it like that. $config_tmp = $config; // $config_tmp points to $config echo $config_tmp->dbName . '<br>'; // says current_db_name include("../../site-xy/config.php"); // you overwrite $config here, but $config_tmp still points to it echo $config->dbName . '<br>'; // says remote_db_name, because you overwrote $config with the include $config = $config_tmp; // $config now points to $config_tmp, which still points at $config, which was overwritten with new values from the include ($config points to an object pointer that points to an object) echo $config->dbName . '<br>'; // says remote_db_name -----------> why? -- See above What you need to do is either clone $config, which will give you a shallow copy or serialize then deserialize the object to achieve a deep copy. ie $config_tmp = unserialize(serialize($config)); // Getting deep copy of $config OR $config_tmp = clone($config); // Getting shallow copy of $config echo $config_tmp->dbName . '<br/>'; // says current_db_name include("../../site-xy/config.php"); // original $config gets overwritten echo $config->dbName . '<br/>'; // says remote_db_name $config = $config_tmp; // $config is now pointing to the deep/shallow copy you made echo $config->dbName . '<br/>'; // should say current config_db_name now
  17. Short answer: do what your site/application requires and whatever is within the limit of your server's resources. My 2 cents: One question I always ask myself when dealing with session data is whether or not I want that data to reflect the same exact information that I saw while visiting the page the next time I visit. If I revisit the page after I log out, close the browser, or hit the back button, what should that data look like? Typically, if (other) users, applications, functions, methods, etc. need to modify this data, then a session variable is out of the question for me. But if I want this data to be the same after I enter it, (ie: shopping cart information that I have added a shirt to when at work that I want to review when I get home) then that information might be alright for me to use in a session. Nonetheless, I still prefer to store only enough information concerning the session. I usually reserve session variables to hold information (user name, id, department, specific date of something important - maybe sale end date, shirt item number, etc) directly related to the user, application, or page that is being served. Then, based on those parameters, I make Processwire fetch the needed page(s) information (cost of the shirt, quantity remaining, etc) because these things are subject to change.
  18. So, does the client have to log in in order to view the page? If a page is unpublished, or its template can only be viewed/edited by a certain role, than an unauthorized user would get the 404 page. Unpublished pages won't remain hidden from the superuser/admin, so it makes sense that if you log in you can view it. Ensure that the client has the appropriate template permissions set. Also, I had a similar situation when I was testing the page flags in the template file. Setting/unsetting the hidden and unpublished flags from the API resulted in the appropriate flags being set, but they would not reflect in the admin view for some reason. Selecting the unpublished box, saving, and then unselecting and saving it fixed my mysterious 404.
  19. Weird. The only way I see this happening is if you are formatting the output of the date/time field to H:i:s or H:i but not setting the input formatting to something other than 'none', which is the default for input. Then it makes sense that PW will always format it to zero. I've found the auto-formatting of output for the date/time fieldtype to be a timesaver - less interaction with the date() function. If you need help clarifying its usage, let me know and I'll post an example or two.
  20. I guess the approach would depend on the actual time constraint requirements. If you needed an allowed range of time (ie: between 1pm and 2pm) you could write a simple php function that pulls the current time and tests to see if you're within the specified range. // 130000 == 1:00:00 pm, 140000 == 2:00:00 pm function testTheTime($startTime=130000, $endTime=140000){ $currentTime = (int) date('Gis'); if ($currentTime > $startTime && $currentTime < $endTime ){ return true; } else{ return false; } } $inRange = testTheTime(); // do something with it The $page->created property comes in the form of a Unix timestamp, so you could format it with PHP's date() function however you need. Obviously, you could throw that into the mix of the above function and do what you needed with just a function. If you want a hook you could do something like: // add a method called "test" wire()->addHook('Page::test',null,'lockPage'); // function evaluates the created time of the page, and compares it to specified start and end times function testTheTime($createdTime, $startTime, $endTime){ $createdTime = (int) date('Gis'); if ( ($createdTime > $startTime) && ($createdTime < $endTime) ){ return true; } else{ return false; } } function lockPage(HookEvent $event){ $page = $event->object; //grab the page instance $createdTime = $page->created; //grab the created timestamp $lock = testTheTime($createdTime,130000,140000); //pass it along $event->return = $lock; //returns the value } if($page->test()){ throw new Wire404Exception; //if the created time is within 1pm or 2pm, throw a 404 } I know, I know, it's a crappy example of a use case but you get the idea of where you could take it (sorry, I'm that that imaginative when at work). BTW, the above is for using within a template file, you could easily make a module and not make your template file so ugly.
  21. For the login, you would create a login form and based on who they are, direct them to the appropriate landing page. This can be tricky to update if you're hardcoding all the partner companies into your script (don't do that). Instead, for each company, create a user. Then, based on the users role, they can access pages that they are allowed to manage. You might find the Page Edit Per User module handy http://modules.processwire.com/modules/page-edit-per-user/ Or the Page Edit Per Role module http://modules.processwire.com/modules/page-edit-field-permission/ . I am actually working on a front end admin for users of a company intranet and that's along the lines of how I do it.
  22. I Googled "alternative to _____" - I can't remember which bloated CMS I put in that line but that's about as useful as Joomla/Wordpress/Drupal has ever been for me. I had been sick of these CMS's for quite some time and PW instantly became a breath of fresh air. PW is great, but this forum is also incredibly inviting and polite which made making my mind up an even easier thing to do. Reading through the explanations and posts of one member helping another made me realize that there was something different (besides being awesome to use) about PW. Thank you Ryan and contributors!
×
×
  • Create New...