Laravel - how much time passed since cache - caching

Lets say I use remember function to store the data in cache.
And when user is in the site, I want him to be able to know how old the data is which he see. And so he will have option to get fresh data if he does not like old.
One thing - I could try to check the cached file date, but I am not sure how the folder structure and file names are made. Could try to understand by checking how cache works, but maybe there is something done with this? I did not find.

/**
* Get the full path for the given cache key.
*
* #param string $key
* #return string
*/
protected function path($key)
{
$parts = array_slice(str_split($hash = md5($key), 2), 0, 2);
//return $this->directory.'/'.join('/', $parts).'/'.$hash;
return Config::get('cache.path') .'/'.join('/', $parts).'/'.$hash;
}
public function getTest() {
$users = DB::table('shops')->remember(1, 'key')->get();
echo 'Now: ' . date('H:i:s') . '<br>';
echo 'Cache saved at: ' . date('H:i:s', filemtime($this->path('key'))) . '<br>';
}
THe path() function is copied and edited from FileStore.php file. I better way would be to extend this but I am not sure how. So would be good if someone tell.

For Laravel 5:
$parts = array_slice(str_split($hash = sha1($cacheKey), 2), 0, 2);
$path = storage_path('framework/cache/data').'/'.implode('/', $parts).'/'.$hash;

Related

CodeIgniter escaping table

I know CodeIgniter automatically escapes values being sent to say an insert or update query e.g. $bar, but will it also escape $table if table is being received from say a post or get? I couldn't find any documentation on that.
$this->db->insert($table, array('foo' => $bar));
if you look at CodeIgniter's 2.x system/database/drivers/DB_driver.php near line 902
or
at CodeIgniters 3.x system/database/DB_driver near line 1365
you'll find a function called insert_string() which looks like this:
/**
* Generate an insert string
*
* #access public
* #param string the table upon which the query will be performed
* #param array an associative array data of key/values
* #return string
*/
function insert_string($table, $data)
{
$fields = array();
$values = array();
foreach ($data as $key => $val)
{
$fields[] = $this->_escape_identifiers($key);
$values[] = $this->escape($val);
}
return $this->_insert($this->_protect_identifiers($table, TRUE, NULL, FALSE), $fields, $values);
}
then follow-up function _protect_identifiers() near line 1246 (CI 2.x) or near line 1729 (CI 3.0) which says:
* Since the column name can include up to four segments (host, DB, table, column)
* or also have an alias prefix, we need to do a bit of work to figure this out and
* insert the table prefix (if it exists) in the proper position, and escape only
* the correct identifiers.
so the answer is YES.
in case of doubt you can always use this: echo ($this->db->last_query());die(); which prints out your last query performed what could look like this:
INSERT INTO `googlemaps_marker` (`descr`, `Lat`, `Lng`, `pretty_url`, `ID`, `zone_ID`, `kind`, `author_id`, `author`, `date_updated`) VALUES ('sasasasdas', '41.27780646738183', '-7.437744140625', 'sasasasdas', 4, 4, 1, '1', 'Admini Istrator', '2017-07-15 18:20:40')

Merging multiple objects which uses same id

I'm trying to merge multiple objects (like Receipts, Reports, etc) with Collection->merge().
This is the code I used:
$receipts = Receipt::all();
$reports = Report::all();
$collection = $receipts->merge($reports);
This is the result:
The above screenshot shows two elements, but the third element is missing because it has the same id (id: "1") as the first one. What I'm trying to achieve is to display all three of them as a collection.
EDIT:
I need the result to be objects (collection) because I also use the code on my view, where I check the class to determine what to display. Also, I use this function to sort the objects in the collection.
$collection->sort(function($a, $b)
{
$a = $a->created_at;
$b = $b->created_at;
if ($a === $b) {
return 0;
}
return ($a > $b) ? 1 : -1;
});
I know that this is an old question, but I will still provide the answer just in case someone comes here from the search like I did.
If you try to merge two different eloquent collections into one and some objects happen to have the same id, one will overwrite the other. I dunno why it does that and if that's a bug or a feature - more research needed. To fix this just use push() method instead or rethink your approach to the problem to avoid that.
Example of a problem:
$cars = Car::all();
$bikes = Bike::all();
$vehicles = $cars->merge($bikes);
// if there is a car and a bike with the same id, one will overwrite the other
A possible solution:
$collection = collect();
$cars = Car::all();
$bikes = Bike::all();
foreach ($cars as $car)
$collection->push($car);
foreach ($bikes as $bike)
$collection->push($bike);
Source: https://medium.com/#tadaspaplauskas/quick-tip-laravel-eloquent-collections-merge-gotcha-moment-e2a56fc95889
I know i'm bumping a 4 years old thread but i came across this and none of the answers were what i was looking for; so, like #Tadas, i'll leave my answer for people who will come across this. After Looking at the laravel 5.5 documentation thoroughly i found that concat was the go-to method.
So, in the OP's case the correct solution would be:
$receipts = Receipt::all();
$reports = Report::all();
$collection = $receipts->concat($reports);
This way every element in the Report collection will be appended to every element in the Receipts collection, event if some fields are identical.
Eventually you could shuffle it to get a more visual appealing result for e.g. a view:
$collection->shuffle();
Another way to go about it is to convert one of your collections to a base collection with toBase() method. You can find it in Illuminate\Support\Collection
Method definition:
/**
* Get a base Support collection instance from this collection.
*
* #return \Illuminate\Support\Collection
*/
public function toBase()
{
return new self($this);
}
Usage:
$receipts = Receipt::all();
$reports = Report::all();
$collection = $receipts->toBase()->merge($reports);
You could put all collections in an array and use this. Depends on what you want to do with the collection.
$list = array();
$list = array_merge($list, Receipt::all()->toArray());
$list = array_merge($list, Report::all()->toArray());

Array match in while-loop

I am developing a search tool for my project,
My desired output is to get the common value from the different tables. eg) SKR0BP100
How to get this value ??
As i am running the program in for-loop and fetching the values from while-loop, now how to use array_intersect() function? Because for array intersect function, minimum 2 arrays are needed, but i get only one array at a time, as it runs on for-loop. So what should i do ?? Please Help me!
$result = array_intersect($arr1, $arr2);
But i have only one $array (ie, $sid[$i] at a time, as it runs in for-loop.
My program
for($i=0;$i<$cc;$i++)
{
$m1="select * from $u$sc where $b[$i]='$a[$i]' ";
$m2=mysql_query($m1);
echo"$m1<br><br>";
while($we=mysql_fetch_array($m2))
{
$sid[$i]=$we['SI'];
echo"$sid[$i]<br><br>";
}
}
Desired Output = SKR0BP100
// How to get this??
Present output
select * from Studentsc where Zone='East'
SKR0BP100
SKR0BP12
select * from Studentsc where Area='Rural'
SKR0BP129
SKR0BP13
SKR0BP100
select * from Studentsc where Class='12'
SKR0BP100
SKR0BP101
So if you want to create query then try this
$where = array();
for($i=0;$i<$cc;$i++)
{
$where[] = $b[$i]."='".$a[$i]."'";
}
$m1="select * from $u$sc where ".implode(" and ",$where); //If you are sure that atleast one value vomes

TYPO3: Calculate Cache identifier hash value?

In TYPO3 I want to remove a single page from the cache table with some GET values. I haven't found an extension, that will handle that or a TYPO3 method.
Is there a function, that I can hand over a URL or similar, that produces the cache hash identifier or removes the specific data from the caching tables?
If not, does anybody know, what the algorithm is, that calculates the hash identifier or in which file I might find it?
So any help will be appreciated.
My TYPO3 version: 4.5.x
You can create a function which clear the cache of a specified page, following code is needed:
TYPO3 6.0
public function clearCache($cacheCmd) {
/** #var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
$tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("TYPO3\\CMS\\Core\\DataHandling\\DataHandler");
$tce->stripslashes_values = 0;
$tce->start(array(), array());
switch($cacheCmd) {
case 'pages':
case 'all':
$tce->admin = 1;
}
$tce->clear_cacheCmd($cacheCmd);
unset($tce);
}
TYPO3 4.x
public function clearCache($cacheCmd) {
/** #var $tce t3lib_TCEmain */
$tce = t3lib_div::makeInstance("t3lib_TCEmain");
$tce->stripslashes_values = 0;
$tce->start(array(), array());
switch($cacheCmd) {
case 'pages':
case 'all':
$tce->admin = 1;
}
$tce->clear_cacheCmd($cacheCmd);
unset($tce);
}
And $cacheCmd can have following values:
/typo3/sysext/core/Classes/DataHandling/DataHandler.php:clear_cacheCmd (> 6.0) or /t3lib/class.t3lib_tcemain.php (4.x)
/**
* Clears the cache based on the command $cacheCmd.
*
* $cacheCmd='pages': Clears cache for all pages. Requires admin-flag to
* be set for BE_USER.
*
* $cacheCmd='all': Clears all cache_tables. This is necessary if
* templates are updated. Requires admin-flag to be set for BE_USER.
*
* $cacheCmd=[integer]: Clears cache for the page pointed to by $cacheCmd
* (an integer).
*
* $cacheCmd='cacheTag:[string]': Flush page and pagesection cache by given tag
*
* $cacheCmd='cacheId:[string]': Removes cache identifier from page and page section cache
*
* Can call a list of post processing functions as defined in
* $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc']
* (numeric array with values being the function references, called by
* \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction()).
*
* Note: The following cache_* are intentionally not cleared by
* $cacheCmd='all':
*
* - cache_md5params: RDCT redirects.
* - cache_imagesizes: Clearing this table would cause a lot of unneeded
* Imagemagick calls because the size informations have
* to be fetched again after clearing.
*
* #param string $cacheCmd The cache command, see above description
* #return void
*/
Call this with a userFunc if a given parameter is set in typoscript or create a simple extension by your own.
It's like this:
You need a proper TSFE object $GLOBALS['TSFE']
then you need the encryption key from the localconf $TYPO3_CONF_VARS['SYS']['encryptionKey']
and the URL parameters e.g. `tx_ttnews[tt_news]
then these steps
create an (sorted) array with the encryption key and the url parameters
Hand over this array to the property cHash_array of the TSFE object
Get the cHash value from the TSFE's getHash method
$arr = array(
'encryptionKey' => $TYPO3_CONF_VARS['SYS']['encryptionKey'],
'tx_ttnews[tt_news]' => $newsid,
// ...
)
ksort($array);
$GLOBALS['TSFE']->cHash_array = $array;
$chash = $GLOBALS['TSFE']->getHash();

PHP - How to accomplish this if?

I am creating an order cart.
On the page that displays the cart, it checks if a value stored in the session $order corresponds with an id of a row in a mysql table. If this match exists, then the corresponding row is returned.
Within this process, I am trying to retrieve the quantity value stored in the session $quantity that corresponds to the id of the row in the table.
Each value in $order and $quantityis assigned a name, which is the id of the item they were added from.
This is the code that adds the order to the cart:
if (isset($_POST['action']) and $_POST['action'] == 'Order')
{
// Add item to the end of the $_SESSION['order'] array
$_SESSION['order'][$_POST['id']] = $_POST['id'];
$_SESSION['quantity'][$_POST['id']] = $_POST['quantity'];
header('Location: .');
exit();
}
This is the code on the cart page:
foreach ($order as $item)
foreach ($quantity as $amount)
{
mysql_data_seek( $productsSql, 0); //<- this line, to reset the pointer for every EACH.
while($row = mysql_fetch_assoc($productsSql))
{
$itId = $row['id'];
$itDesc = $row['desc'];
$itPrice1 = $row['price1'];
if ($item == $itId)
{
$pageContent .= '
<tr>
<td>'.$itDesc.'</td>
<td>'.if ($item[''.$itId.''] == $amount[''.$itId.'']) {echo $amount}.'</td>
<td>R'.number_format($itPrice1*$amount, 2).'</td>
</tr>
';
}
}
}
This row is producing a syntax error:
<td>'.if ($item[''.$itId.''] == $amount[''.$itId.'']) {echo $amount}.'</td>
What is the problem here for starters?
Secondly, how would I need to do to accomplish the task that I am facing?
Any input on this would be greatly appreciated!
Could you try this?
<td>'.($item[$itId] == $amount[$itId] ? $amount : '').'</td>
This is a ternary operator, look at http://en.wikipedia.org/wiki/Ternary_operation
You can't simply add conditional statements like that while you're building a string.
You can do this, however
<td>' . ($item[$itId] == $amount[$itId]) ? $amount : null . '</td>
but you should use a more legible method.
Another issue you may get is if $amount is an array, you won't be able to print it as a string. If, however, $amount is an object with ArrayAccess interface, you can print it with the __toString() method; but that's another story.
The code for creating the cart page has several issues.
You walk over items and over quantities, which will probably give you duplicate outputs.
$item is a plain string, so I wonder what $item[$itId] is supposed to do?
You walk over your complete result set several times which actually is not necessary. I really hope that "$productSql" isn't a "select * from product", otherwhise this might get REAL slow in production mode.
I suggest creating a good SQL for getting the data and using this as a basis for filling the page:
// note this has SQL-injection issues, so you really need to make sure that $order contains no crap
$productsSql = mysql_query("select * from product where id in (".join($order, ',').")");
// you now have a result set with all products from your order.
while($row = mysql_fetch_assoc($productsSql))
{
$itId = $row['id'];
$itDesc = $row['desc'];
$itPrice1 = $row['price1'];
// session contains the quantity array mapping ID -> Quantity, so grab it from there
$itQuantity = $quantity[$itId];
// finally calculate the price
$itPrice = number_format($itPrice1*$itQuantity, 2);
// now you have all data for your template and can just insert it.
// if you use double quotes you can put the $xyz into the string directly
$pageContent .= "
<tr>
<td>$itDesc</td>
<td>$itQuanty</td>
<td>R $itPrice</td>
</tr>
";
}

Resources