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();
Related
I noticed this anomaly working with application-settings module on a
nativescript (8.1.2) /angular project.
Having this code:
import { getString} from '#nativescript/core/application-settings';
remove("attribute_name_string")
let attribute_name_string = getString("attribute_name_string","DEFAULT VALUE")
console.log("Print My Local Atribute = " + attribute_name_string)
I was expected the result to be:
Print My Local Atribute = DEFAULT VALUE
but it was
Print My Local Atribute =
The same for setNumber
import { setNumber} from '#nativescript/core/application-settings';
remove("attribute_name_number")
let attribute_name_number = getNumber("attribute_name_number", 121)
console.log("Print My Local Atribute Number = " + attribute_name_number)
I was expected the result to be:
Print My Local Atribute Number = 121
but it was
Print My Local Atribute Number = 0
Two questions here:
Why this strange behaviour (anomaly)?
How can I clear my variables and get the default value afterwards ?
Please take in consideration the official documentation:
A default value can be provided in case there is no existing value.
/**
* Gets a value (if existing) for a key as a String Object.
A default value can be provided in case there is no existing value.
* #param key The key to check for.
* #param defaultValue An optional value to be returned in case there is no existing value.
*/
export function getString(key: string, defaultValue?: string): string;
and
/**
* Removes a value (if existing) for a key.
* #param key The key to check for.
*/
export function remove(key: string): void;
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')
I have two Models that are related to each other:
class Product
{
//...
/**
* #var Collection<Key>
* One Product has Many Keys.
* #ORM\OneToMany(targetEntity="Key", mappedBy="product")
*/
private $keys;
public function getKeyNumber()
{
return count($this->keys);
}
//...
}
class Key
{
//...
/**
* #var Product
*
* Many Keys have One Product.
* #ORM\ManyToOne(targetEntity="Product", inversedBy="keys")
* #ORM\JoinColumn(referencedColumnName="id")
*/
private $product;
/**
* #var int
* #ORM\Column(type="integer")
*/
private $product_id;
//...
}
I am able to get the number of Keys with Product::getKeyNumber(). Now I'd like to use this value for sorting in the query.
I've tried something like that (DQL Query):
SELECT a, COUNT(a.keys) AS keyNumber FROM AppBundle\Entity\Product a ORDER BY keyNumber ASC;
which returns:
[Semantical Error] line 0, col 18 near 'keys) AS keyNumber': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
When I try:
SELECT a FROM AppBundle\Entity\Product a ORDER BY count(a.keys) ASC
it says:
[Syntax Error] line 0, col 50: Error: Expected known function, got 'count'
Any ideas? :)
Thanks.
You can try doing something like this (just an idea, not a verified code)
SELECT a, COUNT(b.id) AS keyNumber FROM AppBundle:Product a JOIN a.keys b ORDER BY keyNumber ASC;
As soon as COUNT() expects single value field you can explicitly join the keys table and count on something in it (I assume it has ID or you can use whatever is there).
I wonder if it has to do with composite keys? I read something about that. I don't know what your key identifier is, but I show a.id below. Can you try this:
SELECT IDENTITY(a.id), a, COUNT(a.keys) AS keyNumber FROM AppBundle:Product a ORDER BY keyNumber ASC
Note, I've reduced AppBundle\Entity\Product to simply AppBundle:Product and got rid of the semicolon at the end.
Let me know if that works, it may not.
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;
I am pretty new to CodeIgniter and PHP in general and have two questions that are somewhat related.
I have a nested category tree with unlimited depth that produces links like myapp.com/language and myapp.com/spanish but I would like to have something like myapp.com/language/spanish.
For reference my model returns an array of arrays like:
[Languages] => Array ( [category_id] => 4 [sub] => Array ( [Japanese] => Array ( [category_id] => 5 ) [Spanish] => Array ( [category_id] => 6 )...
My helper function to create the menu:
function buildMenu($menu_array, $is_sub=FALSE){
/*
* If the supplied array is part of a sub-menu, add the
* sub-menu class instead of the menu ID for CSS styling
*/
$attr = (!$is_sub) ? ' id="menu"' : ' class="submenu"';
$menu = "<ul$attr>\n"; // Open the menu container
/*
* Loop through the array to extract element values
*/
foreach($menu_array as $id => $properties) {
/*
* Because each page element is another array, we
* need to loop again. This time, we save individual
* array elements as variables, using the array key
* as the variable name.
*/
foreach($properties as $key => $val) {
/*
* If the array element contains another array,
* call the buildMenu() function recursively to
* build the sub-menu and store it in $sub
*/
if(is_array($val))
{
$sub = buildMenu($val, TRUE);
}
/*
* Otherwise, set $sub to NULL and store the
* element's value in a variable
*/
else
{
$sub = NULL;
$$key = $val;
}
}
/*
* If no array element had the key 'url', set the
* $url variable equal to the containing element's ID
*/
if(!isset($url)) {
$url = $id;
}
/*
* Use the created variables to output HTML
*/
$menu .= "<li><a href='$url'>$url</a>$sub</li>\n";
/*
* Destroy the variables to ensure they're reset
* on each iteration
*/
unset($url, $display, $sub);
}
return $menu . "</ul>\n";
This leads me to my next problem. How do I get these links to call a dynamic function that can return a list of all posts in that category. I am thinking that if I can get the routes working how I want them above that it will be as easy as having a function like get_cat_posts($cat_id). Am I correct in this assumption? Will having more than one sub-level be a problem?
Sorry for the long post. Thanks for any help.
Well I have given up on trying to make this work. It seems untenable to try using this current function to produces the results that I desire so I have moved on to just using an adjacency list and caching the results. Meh.