I have a Yii dropdown which loads a table of cities, states, zipcodes, lat and lon. When loading the state dropdown, it takes forever. Is there a way to speed up the query to cut down on pageload time? I've included my view:
echo $form->dropDownList($model,'State', CHtml::listData(Zipcodes::model()->findAll(),
'State', 'State', 'State'), array('empty'=>'-- Choose State --'));
The table is 41,000 entries. Setting the $groupField in listData() didn't seem to give any noticeable improvements.
I think you can have two ways:
1) Use cache (with long or no expiration time, because this data you have are not dynamic).
First time your loading time will not change, but after that, it will bee much, much faster, because cache will be already saved.
http://www.yiiframework.com/doc/guide/1.1/en/caching.data#query-caching
$zipcodes = Zipcodes::model()->cache(3600*24*7)->findAll(); //cache for a week
Using cache you need to edit your config/main.php file
//...
'components' => array(
//...
'cache'=>array(
'class'=>'system.caching.CFileCache',
//'class'=>'system.caching.CDummyCache',
//other cache class
),
//...
),
//...
2) Maybe consider to try CJuiAutoComplete
http://www.yiiframework.com/doc/api/1.1/CJuiAutoComplete/
It will give you results only on typing and matching your interested data.
Not loading 41k entries and placing them in HTML <option> tags seems to be a very good start... :-)
Only load those you need using AJAX.
Is the state drop-down culling unique states from that table, i.e., you end up with 50-ish results? You might want to construct the query manually and see where the bottleneck is. For complex queries, this is often dramatically faster than using AR, which I'm assuming you are using to create the model. I'm also assuming you are not trying to load 41k records into a drop-down.
We might need a bit more detail about the structure of the table, how you are creating the model, etc.
Using CDbCriteria, I set the "GROUP BY" for the query:
$stateGroupBy = new CDbCriteria; // i got that bitch criteria. bitches love criteria!
$stateGroupBy->group = 'State'; // group by state
echo $form->dropDownList($model, 'State', CHtml::listData(Zipcodes::model()->findAll($stateGroupBy), 'State', 'State'),
array('ajax' =>
array(
'type'=>'POST', //request type
'url'=>CController::createUrl('search/dynamiccities'), #we don't have to use search/, we could just say dynamiccities
'update'=>'#Zipcodes_City',
/*'data'=>'js:jQuery(this).serialize()'*/
),
'empty'=>'-- Choose State --')
);
I flaked out in getting back to this, but this cut down on the load significantly.
Related
I have a slider in the index page, which has 3 pictures and this pictures has links. What is the best way to change pictures and links: make db table sliders:
id
pic
link
and work with it, or make in config->settings.php something like this:
<?php
return [
'new_products_count' => 6,
'popular_products_count' => 6,
'paginate' => 20,
'admin_paginate' => 10,
'slider'=>[
1=>['img'=>'1.jpg','link'=>'www1'],
2=>['img'=>'2.jpg','link'=>'www2'],
3=>['img'=>'3.jpg','link'=>'www3']
]
];
and work with it like this:
Config::set('settings.slider[1]['img']=>'newimg.jpg')
Config::set('settings.slider[1]['link']=>'newWWW')
?
Would be safer to keep in the database for a couple of reasons.
1- If you cache your configuration, it may sometimes behave like a buggy application. I mean after changing an image and coming back, you may see the previous image displaying again. Because what you change at runtime is not persisted. Try to update a config option, e.g:
config(['database.connections.sqlite.driver' => 'fake']);
Then go check the file. tadaaa... the file didn't change.
2- You database is unlimited. YOu can add an infinite number of images (links) with much more options. Of course, you can also pass options to config() but using Eloquent or Query builder is more flexible.
Is there anyway to modify the content shown in a SugarCRM Subpanel without relying on Action Hooks?
Right now to edit content for a Subpanel field I have to use the hooks like this...
$hook_array['process_record']
And in the Class method that I assign the Hook to call I can then change a field in the Subpanel like this...
$bean->name = '<a href="/index.php?action=ajaxui#ajaxUILoc=index.php%3Fmodule%3Dproje_Web_Project_Tasks%26action%3DDetailView%26record%3D'
.$bean->id.'" rel="popover" data-content="'
.$bean->description.'" data-original-title="">'.$bean->name.'</a>';
The main and major problem we have with this method is it works great until you do either of these actions....
Add an item using the Quick Create form
Change a page using the Subpanel paging buttons
In either case, it reloads the Subpanel data without running this hook code on the data, so the result is pretty major as the Subpanel fields that you have edited are no longer edited and show up as normal.
Here is a basic example...this shows 2-3 fields that have been edited using the Hook method above...
Now after paging or quick-creating a new record in the Subpanel, it reloads the Subpanel data and does not apply the Hooked code so you can see the result looks like this...
I know that ListView has a much more reliable and flexible method for editing it's content using the get_list_view_data() method I am able to apply the same edits and have them work all the time!
So I am hoping there is a similar method to edit Subpanel data and have it always apply the edits to that data? From what I have seen in my research so far, the only solution that will work as expected all the time, is to make a completely new Custom Field Type!
I am really hoping that is not the ONLY way as that is a major pain to do that for each type of field that I need to edit in the Subpanels and just doesn't feel right when there are easy ways to edit everything else except SubPanel data.
Does anyone have any ideas, suggestions, tips, help, please do share with me on this matter as it is the main problem I have had since I started developing with SugarCRM in the past few months?
You can change the data by writing a custom query to get data for your subpanel.
So inside your bean (this case Contacts) do a functions:
function get_project_list() {
$query = "SELECT project, info, matching, column, names FROM projects WHERE contact_id = '" . $this->id . "' AND deleted = 0"
return $query;
}
and then in subpanel definition set the data source like this:
$layout_defs["Contacts"]["subpanel_setup"]['projects'] = array(
'order' => 10,
'sort_order' => 'desc',
'sort_by' => 'name',
'title_key' => 'LBL_PROJECTS_TITLE',
'subpanel_name' => 'contact_projects',
'module'=>'projects',
'get_subpanel_data' => 'function:get_project_list',
'function_parameters'=>array('type'=>'urgent'), // this is optional if you decide to sent parameters to the function if do this dont forget to define your function with function get_project_list($params)
'top_buttons' => array (... buttons that you need go here..),
);
Since sql is quite powerful you can modify your subpanel data any way you like, well more or less :)
I made a Diary at http://kees.een-site-bouwen.nl/agenda which can have Events for specific dates. You can add an event using the form located here: http://kees.een-site-bouwen.nl/evenementform
As you can see I have 3 fields 'Datum, Van & Tot' (translation: Datum = date, Van = From, Tot = till)
If the time on that specific date expires I would like to run a script which deletes that specific row from the database.
I searched on google and found a few things like MYSQL Trigger and PHP cronjob, but I don't know if there's an easier way to do this? or how to do it exactly.
My database structure looks like this:
agenda // diary
- - - - // not added the whole structure.
idagenda
titel
waar
www
email
activated
....
....
agendadatum // diary dates
- - - - - -
id
datum
van
tot
idagenda
as you can see I'm using a join to add more dates to one event.
How could I trigger the datetime to delete the rows from the db if the date = today?
NOTE: I am using the Codeigniter framework.
You could set a hook. And use a function like
$this->db->where('tot <', date('Y-m-d H:i:s'));
$this->db->delete('agendadatum');
My codeigniter is a bit rusty but that query should remove all "old" entries on EVERY page load. So if you're going for high traffic this will not hold up.
Running a cronjob every hour/day is probably the "cleanest" way. This will require you to set a where condition on all selections of agendadatum that forces the "tot" date to be in the future. Else it's possible you see expired entries.
Edit:
From what I can gather if you define your hook like:
$hook['post_controller_constructor'] = array(
'class' => '',
'function' => 'delete_old_entries',
'filename' => 'agenda.php',
'filepath' => 'hooks',
'params' => array()
);
And create a file named agenda.php in application/hooks which looks like:
<?php
function delete_old_entries() {
$CI =& get_instance();
$CI->load->database();
$query = $CI->db->query(" DELETE FROM agendadatum WHERE tot < NOW(); ");
}
It should work. However this is pieced together from what I could find and untested. So it might work, it might not. But something along these lines should do the trick even if it isn't this.
If I understand correctly:
CREATE TRIGGER deleteRows AFTER UPDATE,INSERT ON myTable
FOR EACH ROW BEGIN
DELETE FROM myTable WHERE Datum = NOW()
END;
MySQL has a built-in Event Scheduler that basically allows you to run arbitrary SQL code at scheduled times. You could purge your database once a day for instance.
However, I know from your other question that you are hosting your project on a shared host, and, unfortunately, shuch hosts often disable the feature. Check out this manual page to find out whether the feature is active on your server.
I'm wondering if there is a technique or function to do this or if I'm just going to have to have a ton of IF statements/arrays here-
I have a page called products.php and a few different filters I add in the query string.
All the filters (if chosen) could look like this:
products.php?cat=chairs&type=pine&search=Vienna+Range
Is there a simple way to build the query for use again?
I'm going to have buttons/a search box to change the filters I'm using, so will I have to build the URL and query up again for each filter?
For example I'd like to have:
Tables
Beds
Chairs
but also build the query so that it remembers my search term, wood type and range; so clicking on "Tables" would take me to
products.php?cat=chairs&type=pine&search=Vienna+Range.
You can write something like:
<?php
$params = array(
'cat' => 'chair',
'type' => 'pine',
'search' => 'Vienna Range',
);
print_r(http_build_query($params) . PHP_EOL);
You'll get this:
cat=chair&type=pine&search=Vienna+Range
I would like to programatically (using php) fill out an existing drupal form to create a content type that is included in a contributed module.
Details: The module is SimpleFeed and the content type is Feed. I would like to call the module's functions to accomplish this. The method I am interested in is hook_insert which appears to require vid and nid which I am unsure what these are.
Any help is appreciated.
can you provide a bit more information (which modules?). generally, i'd probably suggest calling the modules functions to create the content type, instead of trying to pass it through a form programatically. this way you don't have to worry about implementation, and can trust that if the module works, it'll work for your script too :)
of course this does tie your module to theirs, so any changes in their functions could affect yours. (but then again, you run that risk if they update their database structure too)
ex.
// your file.php
function mymodule_do_stuff() {
cck_create_field('something'); // as an example, i doubt this
// is a real CCK function :)
}
edit: vid and nid are node ID's, vid is the revision id, and nid is the primary key of a particular node. because this is an actual node, you may have to do two operations.
programatically create a node
you'll have to reference the database for all the exact fields (tables node and node_revisions), but this should get you a basic working node:
$node = (object) array(
'nid' => '', // empty nid will force a new node to be created
'vid' => '',
'type' => 'simplefeed'. // or whatever this node is actually called
'title' => 'title of node',
'uid' => 1, // your user id
'status' => 1, // make it active
'body' => 'actual content',
'format' => 1,
// these next 3 fields are the simplefeed ones
'url' => 'simplefeed url',
'expires' => 'whatever value',
'refresh' => 'ditto',
);
node_save($node);
now i think it should automatically call simplefeed's hook_insert() at this point. if not, then go on to 2. but i'd check to see if it worked out already.
call it yourself!
simplefeed_insert($node);
edit2: drupal_execute() isn't a bad idea either, as you can get back some validation, but this way you don't have to deal with the forms API if you're not comfortable with it. i'm pretty sure node_save() invokes all hooks anyhow, so you should really only have to do step 1 under this method.
The drupal api provides drupal_execute() to do exactly this. I would suggest you avoid calling the functions directly to create the node (unless there is a performance reason). By using drupal_execute() all the proper hooks in other modules will be called and your code is far more likely to continue to work through future versions of drupal.
Note that a classic bug in using this method is not first calling something like
module_load_include('inc', 'node', 'node.pages')
which will load the code for your node creation form.
Calling node_save directly is generally considered deprecated and could leave you with broken code in future versions of drupal.
There is a nice example at this lullabot post