How to get disabled entities in TYPO3 8.x extbase? - doctrine

I've set up a simple repository query setting to get certain fe_user in TYPO3 CMS 8.7.22. Without disable this fe_user the repository gives back the expected entity.
But after disable the object again the repository returns null. So why setIgnoreEnableFields and setEnableFieldsToBeIgnored doesn't work anymore?
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$defaultQuerySettings = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
$defaultQuerySettings->setRespectSysLanguage(FALSE);
$defaultQuerySettings->setRespectStoragePage(TRUE);
$defaultQuerySettings->setIgnoreEnableFields(TRUE);
$defaultQuerySettings->setEnableFieldsToBeIgnored(array('disable'));
$someRepository->setDefaultQuerySettings($defaultQuerySettings);
$response = $someRepository->findByIdentifier($fe_user_id);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($response);

It is the findByUid function from the default frontendUserRepsository. There they prevent to get hidden / deleted objects. So I build my own repository function for that case:
public function findHiddenByUid($uid){
$query = $this->createQuery();
$qs = clone($this->defaultQuerySettings);
$qs->setIgnoreEnableFields(TRUE);
$qs->setEnableFieldsToBeIgnored(['disable','hidden','disabled']);
$query->setQuerySettings($qs);
$query->matching($query->equals('uid', $uid));
return $query->execute()->getFirst();
}

Related

Laravel Scout Datatable Updating

I am using Laravel Scout with Algolia for populating a datatable and have this intermittent issue where a record in the table after delete will still be visible. It happens when Algolia's index doesn't update quickly enough and the application fetches the data from Algolia prior to it showing as deleted. After refreshing the page and/or updating another record it shows the correct data. Below is my setup - does anyone have any ideas on how to better set this up so any live update will always have the correct data?
public function deleteSelected()
{
$truckings = Trucking::query()->whereKey($this->selected);
$truckings->each(fn ($trucking) => $trucking->delete());
event(new TruckingCreated);
$this->showDeleteModal = false;
$this->notify('You\'ve deleted ' . collect($this->selected)->count() . ' trucking slips.');
$this->getRowsQueryProperty();
$this->selected = [];
}
As you can see I am calling $this->getRowsQueryProperty(); method after deleting records to force it to update - but there are still instances where this will happen.
Below is that method for reference which fetches the data.
public function getRowsQueryProperty()
{
$query = Trucking::search($this->filters['search'],
function (SearchIndex $algolia, string $query, array $options) {
$options['filters'] = $this->algoliaFilters();
return $algolia->search($query, $options);
});
return $this->applySorting($query);
}
Thank you for any help or advice.
It is because you're missing the get call from your query. Using each without get first chunks the results and runs a mass delete query, bypassing model events, thus not deleting indexes.
$truckings = Trucking::query()->whereKey($this->selected)->get();
$truckings->each(fn ($trucking) => $trucking->delete());

Contentful/Laravel Delivery API setInclude does not work as expected

While using the contentful laravel sdk the set include is not fetching any of the assets that belong to the entries I fetch. The code below (mine):
public function index()
{
$query = $this->query
->setContentType('gallery')
->setInclude(10);
$entry = $this->client->getEntries($query);
if (!$entry) {
abort(404);
}
$data = ['galleries' => $entry];
return view('welcome', ['data' => $data]);
}
The contenful example:
// contentful.php 3.0
$client = new Contentful\Delivery\Client(
'<content_delivery_api_key>',
'<space_id>',
'<environment_id>' // Defaults to "master" if ommitted
);
$query = (new Contentful\Delivery\Query())
->setInclude(2);
$entries = $client->getEntries($query);
my results:
[]
I expect for the previewImage and Images array to include the 'fields' that contain the location of the file. I only get 'sys'. I can't see why the include is not fetching this data. If i set setInclude to 20, over the limit i get an error. Below
What should i do differently? I achieved the desired results in a javascript frontend project, but with laravel i get nothing.
The include is actually working fine. Internally, linked entries/assets are represented using a Link object, which is resolved to an actual entry/asset as soon as you access the field (in your case, that's done with $entry->getPreviewImage(), which will return the Asset object that was loaded in your previous query).
This means that if you dump the entry you won't see the actual object you're expecting in the previewImage field, but everything will work fine if in regular use.

Laravel controller and adding to the result set

I've checked the Q&A about this and can't find anything, so thought i'd ask.
I have a very simple Laravel controller returning all results from a table as below via the 'Name model'. There is then also a further call to my controller, via the model to count the rows and all works and sends to the result set fine...
// All results from my 'Name' model:
$results = $this->name->getAllResults(); // All works fine.
// I then use my controller again, count the rows via the model and add them to $results:
$results['count'] = $this->countNames(); // Again fine
BUT, when i try to add a string to the $results array before i pass it off to th view, as in:
$results['test'] = 'Test'; // This fails in the view
$results['test'] = 124; // But this passes in the view and renders.
It only seems to allow me to add an INT to my result set array. as $results['test'] = 124 also fails.
I then finally, have this sending to my view via:
return view('names', compact('results')); // And that works fine.
Can anyone see what it is I am missing and why integer added to $results works and not a string?. Many thanks in advance.
You are updating collection data. The following line will give collection of models.
$results = $this->name->getAllResults(); // This may give collection of the model
And below, you are updating the collection object.
$results['count'] = $this->countNames();
You can do the following to safely send data to view, without modifying any.
$results = $this->name->getAllResults();
$count = $this->countNames();
$test = 'Test';
$test2 = 124;
return view('names', compact('results','count','test','test2'));

Symfony 1.4 functional test not displaying new data

I'm running a functional test against my Symfony 1.4 project and it keeps failing because it doesn't fetch the latest data.
The test makes up a new site entry, then a survey at the site, then adds data to the survey. Each of these are on separate pages and each work. The data is definitely present in the database. After saving the last form, the survey_data, it returns to the survey page where it should get the survey details and a list of all the data items added to it. This works in dev and prod environments but in my functional tests the survey_data list is empty. Looking through the logs it doesn't try to fetch the data from the database (Doctrine & Postgres). But if I manually load the page in a browser just seconds later the list is there, and if I run a test that goes directly to the page (without clearing the database) the list is there, so the test login has the rights to see that page and the contents, but won't show it at first, as if it has cached the page survey page before the survey_data was added.
So my question is, how can I ensure my functional tests get the latest data from the DB or how can I refresh the local data object cache after saving a new item to the database?
Additional:
My functional tests extend sfPHPUnitBaseFunctionalTestCase and I use the sfBrowser class to check the contents of the pages and navigate through them
The issue appears to be with Doctrine caching any objects it updates for the duration of the execution. This gets cleared out after each web request in a production environment - one request per execution - but in the test environment it appears to persist between requests as they're all happening in the same execution.
It becomes troublesome when testing the process of, say, adding a new Item to a List - the List is in memory (test browser has been to its page before), the new Item gets created, saved but the link between them isn't formed in-memory.
Targeted refreshing of related objects
If you know what object you're looking to forcibly refresh you can:
$SomeDoctrineRecordObject->refreshRelated(); // for all relationships
$SomeDoctrineRecordObject->refreshRelated($relation); // for a specific one
( for the above List and Item example, you'd $list->refreshRelated('item') )
This is only useful if you're using the Doctrine object already, else you have to go pull it out of the route or database each time you need to refresh it. A more general approach is to extend the sfTestFunctional class and override the methods which might result in a relationship change and thus need to trigger a refresh.
General refreshing of all objects
The code to clear out Doctrine's object cache:
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$tables = $connection->getTables();
foreach ( $tables as $table ) {
$table->clear();
}
And an example of how to hook it into a custom functional test object:
class myTestFunctional extends sfTestFunctional
{
public function get( $uri, $parameters = array(), $changeStack = true )
{
$this->clearEntityCache();
return parent::get( $uri, $parameters, $changeStack );
}
public function click( $name, $arguments = array(), $options = array() )
{
$this->clearEntityCache();
return parent::click( $name, $arguments, $options );
}
protected function clearEntityCache()
{
$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$tables = $connection->getTables();
foreach ( $tables as $table ) {
$table->clear();
}
}
}
Thus every time myTestFunctional gets a url or clicks to change page it clears out any Doctrine objects stored in memory. Not subtle, but effective and doesn't make the tests themselves more labourious to write!

Codeigniter global_xss_filtering

In my codeigniter config I have $config['global_xss_filtering'] = TRUE;. In my admin section I have a ckeditor which generates the frontend content.
Everything that is typed and placed inside the editor works fine, images are displayed nice, html is working. All except flash. Whenever I switch to html mode and paste a youtube code piece it is escaped and the code is visible on the frontpage instead of showing a youtube movie.
If I set $config['global_xss_filtering'] = FALSE; the youtube code is passed like it should. This is because 'object', 'embed' etc are flagged as "naughty" by CI and thus escaped.
How can I bypass the xss filtering for this one controller method?
Turn it off by default then enable it for places that really need it.
For example, I have it turned off for all my controllers, then enable it for comments, pages, etc.
One thing you can do is create a MY_Input (or MY_Security in CI 2) like the one in PyroCMS and override the xss_clean method with an exact copy, minus the object|embed| part of the regex.
http://github.com/pyrocms/pyrocms/blob/master/system/pyrocms/libraries/MY_Security.php
It's one hell of a long way around, but it works.
Perhaps we could create a config option could be created listing the bad elements for 2.0?
My case was that I wanted global_xss_filtering to be on by default but sometimes I needed the $_POST (pst you can do this to any global php array e.g. $_GET...) data to be raw as send from the browser, so my solution was to:
open index.php in root folder of the project
added the following line of code $unsanitized_post = $_POST; after $application_folder = 'application'; (line #92)
then whenever I needed the raw $_POST I would do the following:
global $unsanitized_post;
print_r($unsanitized_post);
In CodeIgniter 2.0 the best thing to do is to override the xss_clean on the core CI library, using MY_Security.php put this on application/core folder then using /application/config.php
$config['xss_exclude_uris'] = array('controller/method');
here's the MY_Security.php https://gist.github.com/slick2/39f54a5310e29c5a8387:
<?php
/**
* CodeIgniter version 2
* Note: Put this on your application/core folder
*/
class MY_Security extends CI_Security {
/**
* Method: __construct();
* magic
*/
function __construct()
{
parent::__construct();
}
function xss_clean($str, $is_image = FALSE)
{
$bypass = FALSE;
/**
* By pass controllers set in /application/config/config.php
* config.php
* $config['xss_exclude_uris'] = array('controller/method')
*/
$config = new CI_Config;
$uri = new CI_URI;
$uri->_fetch_uri_string();
$uri->_explode_segments();
$controllers_list = $config->item('xss_exclude_uris');
// we need controller class and method only
if (!empty($controllers_list))
{
$segments = array(0 => NULL, 1 => NULL);
$segments = $uri->segment_array();
if (!empty($segments))
{
if (!empty($segments[1]))
{
$action = $segments[0] . '/' . $segments[1];
}
else
{
$action = $segments[0];
}
if (in_array($action, $controllers_list))
{
$bypass = TRUE;
}
}
// we unset the variable
unset($config);
unset($uri);
}
if ($bypass)
{
return $str;
}
else
{
return parent::xss_clean($str, $is_image);
}
}
}
Simple do the following on the views when displaying embedded object code like from YouTube and etc:
echo str_replace(array('<', '>'), array('<', '>'), $embed_filed);
The global XSS Filtering is only escaping (or converting) certain "dangerous" html tags like <html>
Simple Workaround:
Set $config['global_xss_filtering'] = TRUE;
Run your POST data through HTMLPurifier to remove any nasty <script> tags or javascript.
HTMLPurifier Docs
HTMLPurifier Codeigniter Integration
On the page where you receive the forms POST data use html_entity_decode() to undo what XSS filtering did.
//by decoding first, we remove everything that XSS filter did
//then we encode all characters equally.
$content = html_entity_decode($this->input->post('template_content'))
Then immediately run it through htmlentities()
$content = htmlentities($content);
Store as a Blob in MySQL database
When you want to display the
information to the user for editing run html_entity_decode()
This is how I did it. If anyone knows of a major flaw in what I did, please tell me. It seems to be working fine for me. Haven't had any unexpected errors.

Resources