I'm building a Joomla module that can get an array of all articles on the site -- regardless of category -- then identify the category, retrieve intro text and title, and display the titles, categories, and intro text of the most recent two articles in each category in a tiled layout. I have the layout done, but I don't know where to start on the rest. Is it possible?
I'm not averse to getting the articles from category blogs, but I'm not sure if that's possible.
There is the best way to retrieve the articles:
$jcontent=JControllerLegacy::getInstance('Content');
$jarticles=$jcontent->getModel('Articles');
$jarticles->getState();
$jarticles->setState('filter.article_id', $ids);
$jarticles->setState('list.limit', count($ids));
$jarticles->setState('filter.published', 1);
$articles=$jarticles->getItems();
This code was tested and, as for me, this is the best way - it uses Joomla abstractions to retrieve the articles, it uses Joomla caching and is not dependent on database structure.
This is code is not tested, you may need to check and make minor modifications.
Method 1: In this you need to query the category details again from the category id you get inside the loop.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('*');
$query->from('#__content');
$db->setQuery((string)$query);
$res = $db->loadObjectList();
foreach($res as $r){
//query category details also here
echo '<h3>'.$r->title.'</h3>';
echo $r->introtext;
}
Method 2: In this method you are supposed to get both content and category details in one query. In the select query you need to include the field names which you need.
$db = JFactory::getDbo();
$db->setQuery('SELECT #__content.title as contentTitle, #__categories.title as catTitle FROM #__content, #__categories WHERE #__content.catid = #__categories.id');
$details = $db->loadObjectList();
print_r(details);
Related
I have a php website. The first page contains a list of products and I'm currently passing the ID (picked up from mysql database) for the product within the URL to the items page i.e. localhost/item.php?4
I don't want to show any parameters in the URL so have investigated another option which is using a session.
The issue with this is that the link to each of my items is in a while loop retrieving ID and product name from the database so I'm having issues making the session mirror the ID when an item/link has been clicked.
Here's a snippet of my code (I've removed the session code):
$stmt = $con->prepare("SELECT pid, product_name FROM persons where deleted = ? order by order_age desc");
$stmt->bind_param("i", $del);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo '<tr><td>';
$phn = $row["pid"];
echo "<span><a class='storage' href='item.php'>" . $rows["product_name"] . "</a></span>";
}
echo "</td></tr>";
}
I guess I have two questions:
Is it possible to achieve what I need to do
What is the correct way of achieving this
Thanks in advance,
Pete
Options, briefly
You could first load /item.php?id=4 then redirect to /item-hidden.php & use $_SERVER['HTTP_REFERER'] & parse_url & process the GET portion of the referrer url.
You could also use session for this. Set the session variables when the page loads to the long-url, then redirect to the short url, load the session & clear the session.
If you just want to shorten the url, then you could use uniqid() And put the unique id in the url & save the paramaters to a session variable with that unique id.
You could use a pre-made url shortener.
You could roll your own url shortener using a reference file that holds an array or a database.
There are surely other creative solutions that I haven't thought of
My thoughts:
Hiding the url altogether will make for a poor user experience - inability to bookmark, using the back-button will be funky, hard to share an item on social media or a blog
Shortening the url is nice but not necessary
Depending on the options you're working with, you might be able to create shorthands that are more friendly to look at in the url bar or db-references for sets of options that are extremely common
What you're trying to do seems like a great learning project - learn about sessions, http_referer, databasing & whatnot. I think by doing what you're wanting, you'll learn that you don't really like how it feels - or you might come up with a clever way to make your URLs prettier & make the UX really nice.
After creating my Moodle newmodule, I want to be able to select from the list of current users in the system and assign them some other data. It looks like the following:
Add user manually
User [CHOOSE]
Car hire station [text field]
Car type [textfield]
Price per day [list of prices available]
I builded the database, added the textfields, the forms for them and the button for choosing the users, but how to build the functionality for getting the users's list and add the chosen user?
I did not find such example in Moodle in order use it.
If you anticipate a lot of users in the system then extend the user_selector_base class
https://docs.moodle.org/dev/Ajax_user_selector
From the information given, I think what you're looking for is a way to filter against a user ID to save your custom information against that user.
There is a widget that you might find useful called single_select, which creates a drop-down menu that sends POST data when the selected value is changed.
For example:
global $DB, $OUTPUT;
$posturl = new moodle_url('/local/newmodule');
$options = $DB->get_records_menu('user', array(), '', "id, CONCAT(firstname, ' ', lastname)");
$singleselect = new single_select($posturl, 'userid', $options);
echo $OUTPUT->render($singleselect);
That will output the drop down box and send 'userid' to the page when it reloads. You can then grab that user ID:
$userid = optional_param('userid', 0, PARAM_INT);
And use that when you retrieve the data from your form to save the data.
if ($data = $myform->get_data()) {
$data->userid = $userid;
$DB->update('mytable', $data);
}
The project consists of a lateral menu, which contains all my blog entries.
In theory, the menu works this way: I get the <h1> title of each of my blog documents and his corresponding href, using php.
So each time i add a new blog entry, it appears in the menu automatically,
i did this using fopen and fread and saving the contents of each php document of my blog in a variable called $leer.
Then, i used Preg_match_all to search the title of each blog entry and display it on the menu. With this I can make the menu without having to add the links manually, also using scandir get the url.
The problem is that, when using preg_match_all in the array, gives me many incorrect results, obtaining the same <h1> title four times without explanation.
Here is the code:
$escanear = scandir ("/home/sites/thetoptenweb.com/public_html/post");
$tamanoArray = count($escanear);
So first, as you can see, i´m using scandir and count to get the number of pages.
for($i=2;$i<=$tamanoArray-3;$i++){
$abrirFichero = fopen($escanear[$i],"r");
$leer=fread($abrirFichero, filesize($escanear[$i]));
fclose($abrirFichero);
}
Then, i use a for loop and fread to read all my documents.
The loop is made to "scan" only the selected files between the second and the last-3, because those are my blog entries.
preg_match_all('%<h1>(.*)</h1>%', $leer, $arrayMaches);
So, with the preg_match_all function i get the Title of my documents in a multi-dimensional array, that array is giving me problems i think, because i tryed to read each result with foreach loops, but there are some blank results and i don´t know why this happens.
foreach ($arrayMaches as $result) {
foreach ($result as $key) {
}
}
$cortado=preg_split('%</?h1>%', $key);
echo "<li>".$cortado[0]."</li><hr>";
Finally, i used foreach loops to access to the multi-dimensional array of the preg_match_all. Then, i preg_splited the results to get the text without html tags and after that, displayed the results with echo.
Hope someone helps me recognizing the problem and, if possible, an explanation to the preg_match_all array because i don´t understand how it´s created. Suggestions admited.
If you know a better way to do this, i´ll happy to read it.
This is the entire code:
<?php
$escanear = scandir ("/home/sites/thetoptenweb.com/public_html/post");
$tamanoArray = count($escanear);
for($i=2;$i<=$tamanoArray-3;$i++){
$abrirFichero = fopen($escanear[$i],"r");
$leer=fread($abrirFichero, filesize($escanear[$i]));
fclose($abrirFichero);
preg_match_all('%<h1>(.*)</h1>%', $leer, $arrayMaches);
foreach ($arrayMaches as $result) {
foreach ($result as $key) {
}
}
$cortado=preg_split('%</?h1>%', $key);
echo "<li>".$cortado[0]."</li><hr>";
}
?>
Thanks.
Just use the DOM... you'll save yourself some trouble.
$menuData = array();
$iter = new DirectoryIterator('/home/sites/thetoptenweb.com/public_html/post');
foreach ($iter as $file) {
if ($file->isFile()) {
$filename = $file->getFilename();
$path = $file->getPathname();
$dom = new DOMDocument();
$dom->loadHtmlFile($path);
$titleNode = $dom->getElementsByTagname('h1')->item(0);
if ($titleNode) {
$title = $titleNode->nodeValue;
$menuData[$filename] = $title;
}
}
}
Now you have all the stuff in $menuData you can just loop over it and output the links, assuming that the filename is the appropriate URL. Alternatively, you could output the links in the loop directly but it's wiser to separate things. Create a function to get the data you need, and then use that data to output.
But an even better solution would be to pick a blog platform and use that, then spend your time writing an importer and adjusting look and feel to suit.
I have a rather simple DHTMLX page that I'm working on. I managed to load data from a database and display it in a DHTMLXGrid. However, when I change data in the grid, the data is not saved to the database and is therefore lost when the page is reloaded.
The database in question is three tables: users, shows and watching. watching is the only one that needs updating (right now at least) and I just can't seem to get it to work.
This is my "connector.php" file
<?php
require("codebase/connector/grid_connector.php");
require("codebase/connector/db_mysqli.php");
$servername = "nope";
$username = "nope";
$password = "nope";
$databaseName = "nope";
$conn = new mysqli($servername, $username, $password,$databaseName);
$query = "SELECT watching.user_ID, watching.show_ID,shows.name, watching.episodeswatched, shows.episodes, (shows.episodes - watching.episodeswatched) AS episodesremaining, watching.dropped, watching.waiting FROM watching INNER JOIN shows ON watching.show_ID = shows.ID INNER JOIN users ON watching.user_ID=users.ID";
$gridConnector = new GridConnector($conn, "MySQLi");
if($gridConnector->is_select_mode())
$gridConnector->render_complex_sql($query,"ID","name,episodeswatched,episodes,episodesremaining,dropped,waiting","user_ID,show_ID");
else
{
$gridConnector->render_table("watching","ID", "episodeswatched,dropped,waiting","user_ID,show_ID");
}
?>
And the relevant parts of the Javascript to make the processor and DHTMLXGrid
showsGrid.init();
showsGrid.load("connector.php");
var myDP = new dataProcessor("connector.php")
myDP.enableDataNames(true);
myDP.init(showsGrid);
I tried using the same line for fetching data and updating (render_complex_sqlquery) but that does nothing but paint the row in question red. At least with this method the row stays black.
Am I missing something? Am I doing something completely wrong? I've been completely stuck here for way too long and I'm admitting defeat. I've looked at every sample and tutorial I could find, scoured the documentation and found no help for this.
Forgot the GitHub link: https://github.com/lightspeed1001/dhtmlxdemo
You need to remove the "myDP.enableDataNames(true);" line
This command can be used with custom backend, but while you are using connector on server side you must use the default data sending mode.
I updated the connector.js and some other things, also messed with the names for the cells a bit and now it works.
You can view the diff on the github page for details.
Also, I needed to have datanames enabled, because of how many values I have and they aren't always in the same order when recieving and sending data.
I have a large database of 10,000 addresses and 5,000 people.
I want to let users search the database for either an address or a user. I'd like to use Twitter's typeahead to suggest results as they enter text.
See the NBA example here: http://twitter.github.io/typeahead.js/examples.
I understand that prefetching 15,000 items would not be optimal from a speed and load standpoint. What would be a better way to try and achieve this?
Since no one made any answer, I will go ahead with my suggestion then.
I think the best fit for your big database is using remote with typeahead.js. Quick example:
$('#user-search').typeahead({
name: 'user-search',
remote: '/search.php?query=%QUERY' // you can change anything but %QUERY
});
What it does is when you type characters in the input#user-search it will send AJAX request to the page search.php with query as the content of the input.
On search.php you can catch this query and look it up in your DB:
$query = $_GET['query'].'%'; // add % for LIKE query later
// do query
$stmt = $dbh->prepare('SELECT username FROM users WHERE username LIKE = :query');
$stmt->bindParam(':query', $query, PDO::PARAM_STR);
$stmt->execute();
// populate results
$results = array();
foreach ($stmt->fetchAll(PDO::FETCH_COLUMN) as $row) {
$results[] = $row;
}
// and return to typeahead
return json_encode($results);
Of course since your DB is quite big, you should optimize your SQL query to query faster, maybe cache the result, etc.
On the typeahead side, to reduce load to query DB, you can specify minLength or limit:
$('#user-search').typeahead({
name: 'user-search',
remote: '/search.php?query=%QUERY',
minLength: 3, // send AJAX request only after user type in at least 3 characters
limit: 10 // limit to show only 10 results
});
So it doesn't really matter how big your DB is, this approach should work nicely.
This is an example in PHP but of course it should be the same for whatever backend you have. Hope you get the basic idea.