Smarty Date to use on TPL file - smarty

I have an announcement to make till some date, so I created a time variable as
$announcedate = strtotime('+6 day');
$now = "1382960040";
$smarty->assign('announcedate', $announcedate);
$smarty->assign('now', $now);
And included on tpl file as
{if $now > $announcedate}My Announcement{/if}
I want to be sure before using this and end the announcement specifically after 6th day.
is this the correct way? Or any other guidance?

In short: This will work as you intend it.
However, I'd like to add a few suggestions:
strtotime() returns an integer, and you compare it with a string. This doesn't necessary lead to problems in your use case, but should be improved anyway. A simple update like this changes that:
$announcedate = strtotime('+6 day');
$now = strtotime('now');
Your solution works for your specific task, but isn't very general. If you want to reuse this code for other purposes (other announcements for example) you'll most likely have to adapt the logic. For those reasons, and to keep as much logic away from your display layer smarty, I would check for the announcements only in my php code.
This would look something like this:
php (pseudo code, the idea is, function myAnncouncements() retrieves the announcements you need for a specific timeframe or whatever):
$smarty->assign('announcements', myAnncouncements());
smarty template:
{if isset($announcements)}
{foreach $announcements as $item}
// whatever is needed in here....
{/foreach}
{/if}

Related

Functionality of likes using cookies

Let's say I have a like field in my model, now I want to make the functionality of adding a like using Cookie. For example, we have an article ID, we check in cookies, if there is no data, then we add like and set the time for 10 hours, for example, and so on, 10 hours pass, we check and again we can add like and set this time again. If the data is already there, then we do not add like and do not update the time.
Can anyone see some examples of this? Or where to start and how to implement it?
I read the documentation but did not quite understand how it should work
Let's get a value with a like field
$likes = Request::cookie('like');
Choosing the time
$minutes = 600;
And what's next, how can I make a check to add a like?
If your updated_at column is not updated automatically on update (Eloquent do this by default), you need to do it, so the query can filter the row with correct time for update. You can use Carbon for easy time calculations.
$likes = Request::cookie('like');
$hours = 10;
if($likes) {
# Eloquent way
Article::find($id)
->where('updated_at', '<', Carbon::now()->subHours($hours)->toDateTimeString())
->increment('like');
}
If you want Query Builder way use this syntax:
# Query Builder way
DB::table('articles')
->where('id', $id)
->where('updated_at', '<', Carbon::now()->subHours($hours)->toDateTimeString())
->increment('like');
Not tested.

Two models, two fields, return preferred if present

Been struggling with how to do this the most optimized way possible...
I have two models: Catalog and Application.
Catalog has a field called name.
Application has a field called name.
Both have a relationship with each other.
I am struggling to find a way to create a function i could use across my Laravel application which i would pass application.id to it and it would return a $app->name value based on the following logic:
if $application->name exists, use this value as the $app->name for the $application object
otherwise, get the $catalog->name value and use it as the $app->name
Note that I would like to create a component #application() where i can simply pass the $application->id and build the display logic (theming/styling) into it.
Since i display this $app->name in many places, i would like to make it as lightweight as possible to avoid unnecessary queries.
I hope this makes sense! There are probably so many ways to go with it, i am lost at figuring out the way way to do this :(
I'm not completely sure to understand your model/DB design, but you could use a custom Helper to use that function through the whole app.
For that, you can create a simple PHP class Helper.php file in app/Http/Helpers folder or whatever location you want. Something like:
<?php
use App\Catalog;
use App\Application;
if (! function_exists('getAppName')) {
function getAppName($id){
// Do your logic here to return the name
$catalog = Catalog::find($id);
return $catalog->name;
}
}
?>
Then in any controller or view, you just do
getAppName($application->id)
Do no forget to add your helpers file to the composer autoload. So in composer.json in Laravel's root folder, add the helper path to the autoload array:
"files": [
"app/Http/Helpers/helpers.php"
],
Last but not least, run the following command:
composer dump-autoload
Please note that function logic is just for sample purposes since I don't know your model structure.
In my opinion, I care about the database cost.
Use ternary expression will be elegant. But it took two times IO costs from database if application name is empty.
$app_name = Application::find($id)->name;
$app_name = empty($app_name) ? Catalog::where('application_id', $id)->first()->name;
And this will more complicated, but the catalog_query only execute when application.name is empty, it execute in database and the result is taken out only once;
And Database will only find the name from one table or two table.
Something like this:
$catalog_query = Catalog::where('catalogs.application_id', $id)->select('catalogs.name')->groupBy('catalogs.name');
// if catalogs and applications relationship is 1:1, use ->limit(1) or remove groupBy('name') is better.
Application::where("applications.id", $id)
->selectRaw("IF(application.name IS NULL OR application.name = '', (" . $catalog_query->toSql() ."), applications.name ) AS app_name")
->mergeBindings($catalog_query->getQuery())
->first()
->app_name;
Hope this will help you.

Laravel 5.5 where condition

I have problem in searching, I am using Laravel 5.5 version, the situation like this: I have groups which study during some period of time. On filtering page, Admin enters study starting date and ending date, the result must show all groups which studied or studying between given time period. A comparing in simple way is not working, I would like to use strtotime function, but when I use:
->where(strtotime('edu_ending_date'),'=<',strtotime($edu_ending_date));
the eloquent is saying there is not such a column name ...
if(!empty($input['daterange']))
{
$q->where(function($query)use($edu_starting_date,$edu_ending_date){
$query->where('edu_starting_date', '>=', "$edu_starting_date")
->where('edu_ending_date','=<',"$edu_ending_date");
});
}
if you need to use dates in your where clauses I might want to have a look at this article and this section of laravel docs where they mention additional where clauses which include also whereDate, whereDay, etc. Might come in handy. In your case I would suggest you to do two whereDate conditions to act as between:
$query->whereDate('edu_starting_date', '>=', $edu_starting_date)
->whereDate('edu_ending_date', '=<', $edu_ending_date)
Note that $edu_starting_date and $edu_ending_date are recommended to be a Carbon object or output of PHP's date function. If you want to use strings according to the Laravel docs it should be possible. Hopefully this helps you :)
You can use
$q->whereBetween('edu_starting_date', [$edu_starting_date,$edu_ending_date])
try this:
if(!empty($input['daterange']))
{
$q->where(function($query)use($edu_starting_date,$edu_ending_date){
$query->where('edu_starting_date', '>=', $edu_starting_date)
->where('edu_ending_date','=<',$edu_ending_date);
});
}
The date is saved as a string in my database, is that ok, that is why I would like to use
something like this:
->where(strtotime('edu_ending_date'),'=<',strtotime($edu_ending_date));
You can use DB::raw
->where(DB::raw("strtotime('edu_ending_date')"),'=<',strtotime($edu_ending_date));
Thank you guys, I found my stupid mistake, I stored date as a string.

prevent duplicate value using ajax in sugar crm

i have create module using module builder , now i am having a field called as book Name
now if i give same book name 2 time t is accepting .
i don't want to use and plug in for checking duplicate value because i want to learn the customization through code .
so i can call ajax and check in data base weather the same book name is exist in db or not but i don't know how controller works in sugar crm . and how to call ajax in sugar crm .
can any one guide me , your help is much appreciated .
If you really want to accomplish this using ajax then I'd recommend an entryPoint as the way to go. This customization will require a couple of simple things. First you'll write a little bit of javascript to perform the actual ajax call. That ajax call will post to the entryPoint you write. The entryPoint will run the query for you and return a response to you in the edit view. So lets get started by writing the entryPoint first.
First, open the file custom/include/MVC/Controller/entry_point_registry.php. If the folder structure and file do not exist yet, go ahead and create them.
Add the following code to the entry_point_registry.php file:
$entry_point_registry['test'] = array('file' => 'custom/test.php', 'auth' => true);
Some quick explanation about that line:
The index value of test can be changed to whatever you like. Perhaps 'unique_book_value' makes more sense in your case. You'll see how this value is used in a minute.
The file value in the array points to where you're gonna put your actual code. You should also give this a more meaningful name. It does NOT need to match the array key mentioned above.
The 'auth' => true part determines whether or not the browser needs to have an active logged in session with SugarCRM or not. In this case (and almost all) I'd suggest keeping this to true.
Now lets look at the code that will go in custom/test.php (or in your case unique_book_name.php):
/* disclaimer: we are not gonna get all crazy with using PDO and parameterized queries at this point,
but be aware that there is potential for sql injection here. The auth => true will help
mitigate that somewhat, but you're never supposed to trust any input, blah blah blah. */
global $db; // load the global sugarcrm database object for your query
$book_name = urldecode($_REQUEST['book_name']); // we are gonna start with $_REQUEST to make this easier to test, but consider changing to $_POST when confirmed working as expected
$book_id = urldecode($_REQUEST['book_id']); // need to make sure this still works as expected when editing an existing record
// the $db->quote is an alias for mysql_real_escape_string() It still does not protect you completely from sql injection, but is better than not using it...
$sql = "SELECT id FROM book_module_table_name WHERE deleted = 0 AND name = '".$db->quote($book_name)."' AND id <> '".$db->quote($book_id)."'";
$res = $db->query($sql);
if ($db->getRowCount($res) > 0) {
echo 'exists';
}
else {
echo 'unique';
}
A note about using direct database queries: There are api methods you can use to accomplish this. (hint: $bean->retrieve_by_string_fields() - check out this article if you wanna go that route: http://developer.sugarcrm.com/2012/03/23/howto-using-the-bean-instead-of-sql-all-the-time/) However, I find the api to be rather slow and ajax should be as fast as possible. If a client asked me to provide this functionality there's a 99% chance I'd use a direct db query. Might use PDO and parameterized query if I'm feeling fancy that day, but it's your call.
Using the above code you should be able to navigate to https://crm.yourdomain.com/index.php?entryPoint=test and run the code we just wrote.
However at this point all you're gonna get is a white screen. If you modify the url to include the entryPoint part and it loads your home page or does NOT go to a white screen there are 3 potential causes:
You put something different for $entry_point_registry['test']. If so change the url to read index.php?entryPoint=whatever_you_put_as_the_array_key
You have sugar in a folder or something on your domain so instead of crm.yourdomain.com it is located somewhere ugly and stupid like yourdomain.com/sugarcrm/ if this is the case just make sure that your are modifying the url such that the actual domain portion is preserved. Okay I'll spell it out for you... https://yourdomain.com/sugarcrm/index.php?entryPoint=test
This is more rare, but for some reason that I cannot figure out apache sometimes needs to be reloaded when adding a new entrypoint. If you have shell access a quick /etc/init.d/apache2 reload should do the trick. If you don't have shell access you may need to open a ticket with your hosting provider (or get a fricking vps where you have some control!!!, c'mon man!)
Still not working? Did you notice the "s" in https? Try http instead and buy a fricking $9 ssl cert, geez man!
Okay moving on. Let's test out the entryPoint a bit. Add a record to the book module. Let's add the book "War of Art" (no, not Art of War, although you should give that a read too).
Now in the url add this: index.php?entryPoint=test&book_name=Art%20of%20War
Oh gawd that url encoding is hideous right! Don't worry about it.
You should hopefully get an ugly white screen with the text "exists". If you do let's make sure it also works the other way. Add a 2 to the book name in the url and hopefully it will now say "unique".
Quick note: if you're using Sugar you're probably also using mysql which is case insensitive when searching on strings. If you really need case sensitivity check out this SO article:
How can I make SQL case sensitive string comparison on MySQL?
Okay so now we have our entryPoint working and we can move on to the fun part of making everything all ajaxical. There are a couple ways to go about this, but rather than going the most basic route I'm gonna show you what I've found to be the most reliable route.
You probably will need to create the following file: custom/modules/CUSTOM_BOOK_MODULE/views/view.edit.php (I hope by now I don't need to point out changing that path to use your module name...
Assuming this file did not exist and we are starting from scratch here is what it will need to look like:
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class CUSTOM_BOOK_MODULEViewEdit extends ViewEdit
{
public function display()
{
// make sure it works in the subpanel too
$this->useForSubpanel = true;
// make the name value available in the tpl file
$this->ss->assign('name_value', $this->bean->name);
// load the parsed contents of the tpl into this var
$name_input_code = $this->ss->fetch('custom/modules/CUSTOM_BOOK_MODULE/tpls/unique_book_checker.tpl.js');
// pass the parsed contents down into the editviewdefs
$this->ss->assign('custom_name_code', $name_input_code);
// definitely need to call the parent method
parent::display();
}
}
Things are looking good. Now we gotta write the code in this file: custom/modules/CUSTOM_BOOK_MODULE/tpls/unique_book_checker.tpl.js
First a couple of assumptions:
We're going to expect that this is Sugar 6.5+ and jquery is already available. If you're on an earlier version you'll need to manually include jquery.
We're going to put the event listener on the name field. If the book name value that you want to check is actually a different field name then simply adjust that in the javascript below.
Here is the code for custom/modules/CUSTOM_BOOK_MODULE/unique_book_checker.tpl.js:
<input type="text" name="name" id="name" maxlength="255" value="{$name_value}" />
<span id="book_unique_result"></span>
{literal}
<script type="text/javascript">
$(document).ready(function() {
$('#name').blur(function(){
$('#book_unique_result').html('<strong> checking name...</strong>');
$.post('index.php?entryPoint=test', {book_name: $('#name').val(), book_id: $('[name="record"]').val()}, function(data){
if (data == 'exists') {
removeFromValidate('EditView', 'name');
addToValidate('EditView', 'name', 'float', true, 'Book Name Must be Unique.');
$('#book_unique_result').html('<strong style="color:red;"> ✗</strong>');
}
else if (data == 'unique') {
removeFromValidate('EditView', 'name');
addToValidate('EditView', 'name', '', true, 'Name Required');
$('#book_unique_result').html('<strong style="color:green;"> ✓</strong>');
}
else {
// uh oh! maybe you have php display errors on?
}
});
});
});
</script>
{/literal}
Another Note: When the code detects that the name already exists we get a little hacky and use Sugar's built in validation stuff to prevent the record from saving. Basically, we are saying that if the name already exists then the name value MUST be a float. I figured this is pretty unlikely and will do the trick. However if you have a book named 3.14 or something like that and you try to create a duplicate this code will NOT prevent the save. It will tell you that a duplicate was found, but it will not prevent the save.
Phew! Okay last two steps and they are easy.
First, open the file: custom/modules/CUSTOM_BOOK_MODULE/metadata/editviewdefs.php.
Next, find the section that provides the metadata for the name field and add this customCode attribute so that it looks like this:
array (
'name' => 'name',
'customCode' => '{$custom_name_code}',
),
Finally, you'll need to do a quick repair and rebuild for the metadata changes to take effect. Go to Admin > Repair > Quick Repair & Rebuild.
Boom! You should be good to go!

CodeIgniter model not right with where condition

I have this code in my model:
$this->db->where('transaction_income_barcode.barcode_number', $barcode_number);
The value of $barcode_number is 000500007301000005304778
So I compare using PHP it is the correct value:
if($_POST['barcode_number'] == '000500007301000005304778')
but somehow via the model it is not working correctly.
Any ideas?
Forget all the chatter of var_dump() or complicated last_query(), simply follow the CI process of profiling your code and add:
$this->output->enable_profiler(TRUE);
In your controller after the active call. This will show you your FULL SQL QUERY (actually, all queries on that page).
Cleanest way to go about it, my suspicion is that your value is being converted to a int and it STRIPS out the leading 000's
Take care of that by doing a cast:
$this->db->where('transaction_income_barcode.barcode_number', (string)$barcode_number );
As a side note:
Don't use $_POST['barcode_number'] instead be safe with CI's $this->input->post('barcode_number');

Resources