Couple of random items

edited February 2011 in Bug Reports
A couple of items and only the first one is a bug or at least seems to be.

Two things happen in the asset upload area.

1. The index.html file which I think is to not allow direct access to the folder is showing up in the list of assets which means a client can delete it and thus expose the directory.

2. If you delete all the files in a asset directory including the index.html the directory is deleted as well.


As for the non bug items, I am preparing to build a site with Fuel and there are a few features I am needing pointers on. I would know how to do these in a plain CodeIgniter install but am struggling with the best approach with Fuel.

1. I have a set of pages on the front end of the site that I need to secure with a username a password. I may need an admin feature for administering these accounts as well.

2. I need a text search of the site for both secure and non secure pages.

Both of these sound like modules to me is that correct? Also, would you recommend a simple of advanced modules? Do I need to write my own controllers for these?

Also, the client is planning on uploading media such mp3s and video. I tested Fuel's upload capability on my test site and it seems to be fine, it uploaded a 75MB file just fine but it did look like it was just sitting there. I was wondering is Fuel's upload ability dependent on the servers php settings? Also, I was wondering if you have used anything like http://www.uploadify.com/ with file uploading in Fuel before? If so any pointers on how to best implement something like that?

Thank you in advance for any assistance you can provide.

Comments

  • edited 3:03PM
    1. The index.html files were actually put in place so that git would recognize those folders since they had no contents (git will ignore empty folders... but I've seen other ways around this in git). The no folder access should probably be done at the Apache or .htaccess level just to be safe although I do see your point.

    2. The deletion of the folder was put in place to cleanup empty directories when assets are deleted. Is this causing issues on your end?

    With regards to your questions, I would maybe suggest doing it how you know best using CodeIgniter first and extracting your database functionality into FUEL models that you could leverage as modules later on. For example, you could create your accounts_model.php and get that working with your controllers and views on the front end like you would normally in CI, then you could create a simple module based on that model which can be administered in the FUEL admin. You could also, import those view files as pages if you wanted to make them editable later on. Does that make sense?

    With regards to the text search, this may be a bit trickier depending on how you are indexing the pages for searching (we've been looking into creating a good module for this too). If the administration functionality needed to manage the search isn't based on single model (table) and requires it's own form options, then that would probably need to be it's own module with views, controllers, etc.

    I tend to use "advanced" modules when a specific controller is needed or multiple models are needed for administering the backend (e.g. blog) and "simple" modules when it is more table focused.

    With regards to file uploading, FUEL is limited by server settings as well as $config['assets_upload_max_size'] option you can set in the FUEL configuration.(http://www.getfuelcms.com/user_guide/general/configuration). We actually haven't looked at uploadify.com (looks interesting), however, we do have on the list, ways to better support multiple file uploads, in particular, when you can select multiple files at once from the file upload window (Safari let's you do this). The $_FILES array for that is slightly different and FUEL currently doesn't properly upload files like that.

    Let me know if this helps.
  • edited March 2011
    Finally getting around to working on some these items and I have some questions. I think to keep it easier I will just focus on one area at a time. The first area of focus is securing a set of pages on a site with a session based login. These are all sub pages under one parent page. I have created a simple model for administering accounts and that works great. For the front end of the web site site I need to display a login form on the parent page if they are not signed in and redirect anyone to this page if they try to access the subpages. On the parent page I need to handle the form submission and then log the user in their login is successful. What is best practice here. In CI I would have created a controller to handle the form and session process. In fuel should I create a controller in the application directory? Or is better for me to take my simple model along with the created controller and create a module. Any input would be much appreciated. Also, which of these methods require adjustments to the routes file. Oh also, should I use the simple model for the function for I use to validate the users sign in credentials or should I create a separate model for that?
  • edited 3:03PM
    I tend to create modules when it's code that can be reused elsewhere or may need to be logically separated. What I would do is first start using a CI Controller and then once you get it working that way, you can always extract it out into a module later. With regards to the validation function, that seems like it may be something you can do in the controller or an authentication library class. You can validate models, but that's for saving data and in this case, you are just logging someone in. Hope that helps
  • Yes that makes sense. I guess where I am getting stuck is I have CI controller but I loose everything from the page router. I would like all of the cms features which are being pulled from the database an just add the addition of the sign in form probably below the content and the session check on all the sub pages. Do I extend the page router? Or does this dictate that I do everything in the views?
  • Ok I think I answered my own question ... can you affirm that this is what I need to do in my controller to get the pages from the cms working correctly within my controller?

    $this->load->module_library(FUEL_FOLDER, 'fuel_page'); $config = array(); $config['location'] = uri_path(); $config['render_mode'] = 'auto'; $this->fuel_page->initialize($config); $this->fuel_page->render();
  • edited 3:03PM
    That appears correct.
  • Thanks for all the help! One more question concerning this is do I use add_variables() on the fuel_page to pass additional data to the view?
  • edited 3:03PM
    Yeah. As an FYI, the contact controller on the new demo branch that was posted today with the new 0.9.3 version, has an example as well:
    https://github.com/daylightstudio/FUEL-CMS/tree/demo
  • Awesome got everything working cleanly, thanks for the pointers! One other thing I am working on is a search like you have for the blog but is for the blog and layout sections like page title, body, etc. Any pointers on how to approach this?
  • edited 3:03PM
    Pages are a little tricky because unlike the blog that has a single column to do a like search on, it can have any number of fields for a page that you may need to search on. Perhaps the easiest way would be to do a search on the fuel_pagevars table where the variable name is "body" since that usually holds the bulk of the content. The value will most likely have HTML, which can complicate the search (there is no strip_tags MySQL equivalent function that I know of). You may need to do some processing with PHP (not sure if it can all be done with a query). We get around this issue for the blog by saving the raw post's data in a separate field so we can search on it.

    Another method may be to periodically build a search index. You can grab a list of the pages (there is a method on the pages_model to do this), and use curl to parse the page contents. You could perhaps put in some sort of comment or markup trigger in the HTML to identify a part you want searchable so it doesn't index the whole page.

    We've actually thought about implementing a site search module, but haven't had the time to really flesh it out. So I'd be interested how things work out.
  • Ok working on this now and will let you know how it goes. Just trying to get a basic search nothing fancy for now. I will drop in what I come up with and then maybe it can help you going forward. Anyway, I think I found a bug. I was doing the following

    $this->load->module_model(FUEL_FOLDER, 'pagevariables_model');

    but when I would use the object I was getting db errors. I added this to the model constructor after line 10 and that seems to have fixed the issue.

    $CI->config->module_load(FUEL_FOLDER, 'fuel', TRUE);

    does that make sense and seem right?
  • edited 3:03PM
    What was the error message?
  • $this->load->module_model(FUEL_FOLDER, 'pagevariables_model'); $pages = $this->pagevariables_model->find_all_by_location('home');

    Produces:

    A Database Error Occurred

    Error Number: 1064

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.`page_id` WHERE `.`location` = 'home'' at line 3

    SELECT `pagevariables_model`.* FROM (`pagevariables_model`) LEFT JOIN ` ON `.`id` = .`page_id` WHERE `.`location` = 'home'

    Filename: core/MY_Model.php

    Line Number: 260
  • edited 3:03PM
    That looks like it is a bug. If you are using it outside of the FUEL admin, then that config may not be loaded.
  • edited 3:03PM
    I've pushed a fix for that to GitHub
  • Awesome thanks so much!
  • Alright so I just needed a down and dirty simple search solution and am only worried about the database on this site, no content in view files so I created a model file and controller. Here is what I have ... hopefully this can provide some help or at least a start. Also, I was wondering if you have a recommendation on getting blog "pages/posts" to show in the sitemap.xml?

    <?php if (!defined('BASEPATH')) exit('No direct script access allowed'); class Search_model extends MY_Model { private $_tables; function __construct() { $CI =& get_instance(); $CI->config->module_load(FUEL_FOLDER, 'fuel', TRUE); $this->_tables = $CI->config->item('tables', 'fuel'); $CI->config->module_load('blog', 'blog'); $this->_tables = array_merge($this->_tables, $CI->config->item('tables')); parent::__construct(); } function search($keywords = '') { $keywords = ($keywords != '') ? '%' . $this->db->escape_str($keywords) . '%' : '%'; // search blog posts $select_params_a = array(); $select_params_a[] = $this->_tables['blog_posts'] . ".permalink AS permalink"; $select_params_a[] = $this->_tables['blog_posts'] . ".title AS title"; $select_params_a[] = "'' AS page_id"; $select_params_a[] = "'' AS location"; $select_params_a[] = $this->_tables['blog_posts'] . ".date_added AS sort_date"; $from_params_a = array(); $from_params_a[] = $this->_tables['blog_posts']; $where_params_a = array(); $where_params_a[] = $this->_tables['blog_posts'] . ".title LIKE '" . $keywords . "'"; $where_params_a[] = $this->_tables['blog_posts'] . ".content LIKE '" . $keywords . "'"; $where_params_a[] = $this->_tables['blog_posts'] . ".content_filtered LIKE '" . $keywords . "'"; $sql_a = "SELECT " . implode(', ', $select_params_a) . " FROM " . implode(', ', $from_params_a) . " WHERE (" . $this->_tables['blog_posts'] . ".published = 'yes') AND (" . implode(' OR ', $where_params_a) . ")"; // search page variables $select_params_b = array(); $select_params_b[] = "'' AS permalink"; $select_params_b[] = "'' AS title"; $select_params_b[] = $this->_tables['pagevars'] . ".page_id AS page_id"; $select_params_b[] = $this->_tables['pages'] . ".location AS location"; $select_params_b[] = $this->_tables['pages'] . ".last_modified AS sort_date"; $from_params_b = array(); $from_params_b[] = $this->_tables['pages']; $from_params_b[] = $this->_tables['pagevars']; $where_params_b = array(); $where_params_b[] = $this->_tables['pages'] . ".id = " . $this->_tables['pagevars'] . ".page_id"; $where_params_b[] = $this->_tables['pages'] . ".published = 'yes'"; $where_params_b[] = $this->_tables['pages'] . ".location != 'sitemap.xml'"; $where_params_b[] = $this->_tables['pages'] . ".location != 'search'"; $where_params_b[] = $this->_tables['pagevars'] . ".active = 'yes'"; $where_params_b[] = $this->_tables['pagevars'] . ".name != 'copy'"; $where_params_b[] = $this->_tables['pagevars'] . ".name != 'section_header'"; $where_params_b[] = $this->_tables['pagevars'] . ".value LIKE '" . $keywords . "'"; $sql_b = "SELECT " . implode(', ', $select_params_b) . " FROM " . implode(', ', $from_params_b) . " WHERE " . implode(' AND ', $where_params_b) . " GROUP BY page_id"; // union queries $sql = "(" . $sql_a . ") UNION (" . $sql_b . ") ORDER BY sort_date desc"; $query = $this->db->query($sql); <?php class Search extends CI_Controller { function __construct() { parent::__construct(); } function _remap() { $this->load->helper('inflector'); $this->load->model('search_model'); $this->load->module_library(FUEL_FOLDER, 'fuel_page'); $keywords = ($this->input->post('keywords') == FALSE) ? '' : $this->input->post('keywords'); $results = $this->search_model->search($keywords); $search_results = array(); foreach ($results as $result) { if ($result['permalink'] != '') { $year = date('Y', strtotime($result['sort_date'])); $month = date('m', strtotime($result['sort_date'])); $day = date('d', strtotime($result['sort_date'])); $url = 'news/' . $year . '/' . $month . '/' . $day . '/' . $result['permalink']; $search_results[] = '<li>' . anchor($url, $result['title']) . '</li>'; } else { $search_results[] = '<li>' . anchor($result['location'], humanize(str_replace("/", " - ", $result['location']))) . '</li>'; } } if (!empty($search_results)) { $variable = array('section_interactive' => '<ol>' . implode('', $search_results) . '</ol>'); } else { $variable = array('section_interactive' => '<em>No results were found using the keywords you entered, please try again.</em>'); } $this->fuel_page->add_variables($variable); $config = array(); $config['location'] = uri_path(); $config['render_mode'] = 'auto'; $this->fuel_page->initialize($config); $this->fuel_page->render(); } }
  • edited 3:03PM
    Thanks for posting...

    With regards to the blog posts showing up in the sitemap.xml, try adding this to the file:
    /*************************************************************** Add any dynamic pages and associate them to the $nav array here: **************************************************************/ $CI->load->module_library(BLOG_FOLDER, 'fuel_blog'); $posts = $CI->fuel_blog->get_posts(); // add project pages foreach($posts as $post) { $key = 'blog/'.$post->get_url(FALSE); $nav[$key] = array('location' => $key); }
  • Thanks ... that got me pointed in the right direction!
  • edited 3:03PM
    I have also some problems with the routing. I'm using a controller for the page "activities". The views are coming from the CMS. The page www.site.com/activities is just working but when I'm trying to open the page www.site.com/activities/activity it craches.

    I tried to use the code example of thisisflashpoint:
    $this->load->module_library(FUEL_FOLDER, 'fuel_page'); $config = array(); $config['location'] = uri_path(); $config['render_mode'] = 'auto'; $this->fuel_page->initialize($config); $this->fuel_page->render();

    I also tried to route the location to the right position like: $route['activities/(:any)'] = "activities/subpage"; but this is also not working.
    I know its mapping to the subpage method because I can echo text. But it's not showing my template and text from the CMS.

    Maby it's a simple thing. But I'm not seeing it.
  • edited 3:03PM
    A couple questions:

    1. What do you mean by it "crashes"?
    2. What is uri_path() echoing out (e.g. 'activities/activity')?
    2. What is your controller's name and what is the methods on it that you are trying to use (e.g. controller name is 'activities' and a method name of 'activity')?
  • edited 3:03PM
    I found out how I can solve this.

    My controller name is Activities. So when I visit www.site.com/activities then it loading the index(). the problem was that the uri segments were coming from the CMS. So when you visit www.site.com/activities/contact you need to have the method contact() in de activities controller. But because it's dynamic this is not possible.

    But I found the solution. Now I use _remap() as a method in the activities controller. And that's working great!
  • edited 3:03PM
    Just on the search, pages are tricky..

    I modified the model from 'thisisflashpoint' to suit my needs (no blog, individual terms), maybe helps someone else..

    function search($keywords) { # Key words $keywords = explode(' ', $keywords); # Short cuts $pages = $this->_tables['pages']; $page_vars = $this->_tables['pagevars']; # Select $select = array( $page_vars.'.page_id AS page_id', $pages.'.location AS location', $pages.'.last_modified AS sort_date', 'fpv.value AS title', 'fpv1.value AS body' ); # From $from = array($pages, $page_vars); # Where $where = array( $pages.'.id = '.$page_vars.'.page_id', $pages.'.published = "yes"', $pages.'.location != "sitemap.xml"', $pages.'.location != "search"', $page_vars.'.active = "yes"', $page_vars.'.name != "copy"', $page_vars.'.name = "body"' ); # Build like $str = '('; foreach ($keywords as $keyword) { $str .= $page_vars.'.value LIKE "%'.$this->db->escape_str($keyword).'%" OR '; } # Remove last OR $where[] = substr($str, 0, -4).')'; $sql = "SELECT ".implode(', ', $select). " FROM ".implode(', ', $from). " JOIN ".$page_vars." fpv ON (fpv.page_id = ".$page_vars.".page_id AND fpv.name = 'h1')". " JOIN ".$page_vars." fpv1 ON (fpv1.page_id = ".$page_vars.".page_id AND fpv1.name = 'body')". " WHERE ".implode(' AND ', $where); return $this->db->query($sql)->result_array(); }

    Outputs a query like
    SELECT fuel_page_variables.page_id AS page_id , fuel_pages.location AS location , fuel_pages.last_modified AS sort_date , fpv.value AS title , fpv1.value AS body FROM fuel_pages , fuel_page_variables JOIN fuel_page_variables fpv ON ( fpv.page_id = fuel_page_variables.page_id AND fpv.name = 'h1' ) JOIN fuel_page_variables fpv1 ON ( fpv1.page_id = fuel_page_variables.page_id AND fpv1.name = 'body' ) WHERE fuel_pages.id = fuel_page_variables.page_id AND fuel_pages.published = "yes" AND fuel_pages.location != "sitemap.xml" AND fuel_pages.location != "search" AND fuel_page_variables.active = "yes" AND fuel_page_variables.name != "copy" AND fuel_page_variables.name = "body" AND ( fuel_page_variables.value LIKE "%the%" OR fuel_page_variables.value LIKE "%and%" )



    Heh, that's some sweet indenting..
Sign In or Register to comment.