Typo3 11: Using QueryBuilder with REGEX_REPLACE - mysql

I have implemented a simple searchbar for my frontend plugin.
Now the text I am searching for is a rich text and contains html Tags inside the database field.
I found out that with a simple query condition like this, I can ignore the HTML tags and filter the text correctly:
WHERE REGEXP_REPLACE(a.content, '<[^>]*>', '') LIKE '%my search word%'
However, I didn't find an option for Typo3 Querybuilder and Expressionbuilder to do anything like this.
I tried to use REGEXP_REPLACE like this with the QueryBuilder:
)->orWhere(
$queryBuilder->expr()->like(
$queryBuilder->expr()->literal("REGEXP_REPLACE(a.content, '<[^>]*>', '')", 0),
$queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($searchWord) . '%')
)
)
The query generated part by Typo3 looks like:
WHERE (`'REGEXP_REPLACE(a`.`content, \'<[^>]*>\', \'\')'` LIKE ?))
And this results in an unknown column error.

Take a look at the add() method of the QueryBuilder:
https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Database/QueryBuilder/Index.html#add
Your code should use:
$queryBuilder->add('where', 'REGEXP_REPLACE(a.content, \'<[^>]*>\', \'\') LIKE \'%my search word%\'')

Related

Xpath text() returning no text

I'm trying to restaurant names from Tripadvisor with Python 3 & lxml. The text i'm trying to retrieve is in the following element and is named 'Al Fresco's in this case.
<a target="_blank" href="/Restaurant_Review-g293925-d8327527-Reviews-
Al_Fresco_s-Ho_Chi_Minh_City.html" class="property_title"
onclick="ta.restaurant_list_tracking.clickDetailTitle('/Restaurant_Review-
g293925-d8327527-Reviews-Al_Fresco_s-
Ho_Chi_Minh_City.html','tags_category_tag_restaurants','8327527','1','0');">
Al Fresco's
</a>
The Xpath reference to this element:
//*[#id="eatery_8327527"]/div[2]/div[1]/div[1]/a
I use the following simple code to retrieve the text in this element:
from lxml import html
import requests
page = requests.get('https://www.tripadvisor.nl/Restaurants-g293925-
Ho_Chi_Minh_City.html')
tree = html.fromstring(page.content)
#This will create a list of Names:
Name = tree.xpath('//*[#id="eatery_8327527"]/div[2]/div[1]/div[1]/a/text()')
print ('Name: ', Name)
This returns me an empty array: Name: []
How do I get the text I want?
Without having a look at the actual page your Xpath is probably too strict. Try something like this:
//a[contains(#href,"Restaurant_Review")]/text()
If that yields too many results try adding the parent in front.
Hope that helps.
UPDATE:
After having a look at the actual page, this i probably what you are looking for:
//a[contains(#class,"property_title")]/text()

Bolt CMS: Can contenttype title be generated based on other field values?

I would like to create a contenttype that has select fields for things like 'month of year' and 'type of product' and have the title field be auto generated based on the values of these two fields.
This is because the two select field values are descriptive enough, and I would like to reduce the amount of repetitive typing of the same information the end user of the CMS may have to do to make a title show up in the admin interface instead of (no content …) or (no title …) due to no title or excerpt.
I have tried using a hidden field for the title with a default option and a uses option like for slug but couldn't make it work.
Is there a way to achieve a dynamically generated title based on other field values?
Solved using the title_format option like title_format: [month, type] in the contenttype definition.

Recommendations for populating formatted content pages from the database

I'm working on my first laravel project- a family tree website. Everything's going great with the normal models/controllers/views, but I've gotten to a special case that I'm not sure how to approach. I have about a dozen auxiliary stories that go along with specific people or families- this is extra stuff that most records don't have.
In my previous incarnation of this site, I had a stories table with a headline, source for the material, and a slug, I made an html page for each story, and then I'd link to that page using the slug value.
In Laravel this seems like a really clunky way to go about it (especially as I add more stories), because it's messy to have to make a new route/controller/view for each one.
So I've made a general StoryController and view in hopes of reusing that to display the contents of any story. I've added a 'text' column into my stories table for those contents, and I've copied the HTML (with the problematic characters escaped). But of course when I display this story text on the view, I see all the markup tags displayed themselves (instead of helping to render the actual text in paragraphs, etc).
So two questions: is there a way to treat the field as html itself (instead of a string)? And is my approach off-base and I should do this a different way?
Thanks in advance for any help!
Update: thanks to The Happy Mamba, it works if I call to another function for html_entity_decode and echo out the results, but weirdly it DOESN'T work if I 'return' the results (or do it in the same function). It didn't render the tags until I did it like so (in StoryController):
public function convert($string)
{
echo (html_entity_decode($string));
}
public function show($id)
{
$story = Story::find($id);
$content = StoryController::convert($story->text);
return view ('story/show', compact('story', 'content'));
}
The snag there is that because it's using echo, that field is displayed first no matter what.... so if I can't get around that I'll need to conversion in and out of the database as suggested (still need to get the Connection string working)- but this is a great step forward!
Have you tried pulling it out of the database and then sending the text to htmlentities?
Here's some code to test it. Examples are in postgresql but should work the same with PDO/laravel specific functions:
<?php
$conn = pg_connect('db connection string here');
$text = pg_escape_literal( $conn, htmlentities( '<html><head></head><body><em>test</em></body></html>' ) );
pg_query( $conn, 'TRUNCATE TABLE test' );
pg_query( $conn, "INSERT INTO test VALUES ( {$text} )" );
$result = pg_query( $conn, 'SELECT * FROM test' );
$row = pg_fetch_row( $result );
pg_close( $conn );
$string = $row[0];
echo html_entity_decode($string);
?>
Result:
bolded "test" in browser.
After trying a few things, the solution I like best is to make a partial for each story, and then dynamically include the correct one based on the story.slug. (This way I still need only one story route/show function/view, and I can update the content much more easily than if I'm cramming html into the database)

Is there anyway that I can display SQL query in html?

I'm curious if there's any way to display SQL query(Just the statement itself, not the result) with proper format in HTML document. I'm using it for documentation/demo purpose.
For example here you can display a SQL query like this(with gray background):
SELECT *
FROM USERS
The only thing I came close is using Wells from Bootstrap(which looks very similar to above). But I'm wondering if there's any other way of doing it. If it has functionality of syntax highlighting too, that would be great.
$query = "SELECT * FROM USERS";
<code><?php echo $query; ?></code>
<pre><?php echo $query; ?></pre>

Get tabledata from html, JSOUP

What is the best way to extract data from a table from an url?
In short I need to get the actual data from the these 2 tables at: http://www.oddsportal.com/sure-bets/
In this example the data would be "Paddy power" and "3.50"
See this image:
(Sorry for posting image like this, but I still need reputation, i will edit later)
http://img837.imageshack.us/img837/3219/odds2.png
I have tried with Jsoup, but i dont know if this is the best way?
And I can't seem to navigate correctly down the tables, I have tried things like this:
tables = doc.getElementsByAttributeValueStarting("class", "center");
link = doc.select("div#col-content > title").first();
String text1 = doc.select("div.odd").text();
The tables thing seem to get some data, but doesn't include the text in the table
Sorry, man. The second field you want to retrieve is filled by JavaScript. Jsoup does not execute JavaScript.
To select title of first row you can use:
Document doc = Jsoup.connect("http://www.oddsportal.com/sure-bets/").get();
Elements tables = doc.select("table.table-main").select("tr:eq(2)").select("td:eq(2)");
System.out.println(tables.select("a").attr("title"));
Chain selects used for visualization.