Oh no! Where's the JavaScript?
Your Web browser does not have JavaScript enabled or does not support JavaScript. Please enable JavaScript on your Web browser to properly view this Web site, or upgrade to a Web browser that does support JavaScript.
Sign In
Not a member yet? Click here to register.

Enhanced Database layer

Hehe.. about the PDO, it's more like a typo error rather than method error. Silly me. Yes, Domi saved my day.

Quote

But image must be uploaded first nevertheless, because you need to verify whether image exceed size, etc. The path - is dynamic to $album_id.
- by hien

The file will uploaded into the tmp directory of the server and then the size of the file is known before you move it into the final directory.
In fact, we have everything before we move the file into the album.
We could generate the final name of the file and insert the record and create the directory and move the file.

Quote

I will find options anyway.. But see what have been coded 10 years ago...
- by hien

So you had 10 years to learn the good way.

Quote

My problem with form_sanitizer() not uploading is that function image_upload or file_upload have validation there, and returns like 6 streams of different error types. Max size, File type not allowed, etc. I'm just too lazy to ensure consistency over every single one of them. Fix here and broken there, It was very tiring. I had been trying hard to make life easier.

I wrote an uploader some years ago. It worked this way:
CodeDownload  
$uploader = new Uploader();
$uploader->setFolder('...');
$uploader->setInputName('the[name][of][the][input]');
// ...
// other method calls
// ...
if ($uploader->isRequested()) {
    if($uploader->validate()) {
        $uploader->upload();
    } else {
        print_r($uploader->getErrors());
    }
}



It was offtopic, sorry. But the point is we would not need the dbnextid() if we did it better.

Believe me, I had to upload images some days ago into folders like this:
CodeDownload  
$lastInsertedId = 12324;
$path = '123/2/4/12324.jpg';


It is not magic.

Bigger magic to understand the form_sanitizer and other functions that do other than they should.

Of course, it is too later to change everything.

Quote

Got it. http://stackoverflow.com/questions/20992848/how-can-i-fetch-the-next-auto-increment-value-using-php-pdo
Git: https://github.com/php-fusion/PHP-Fusion/commit/7268ceaa80ae3cebbd1d55cee0692020d5c0e731
- by hien


@hien: If you tested the changed codes, you would not say "it is fixed" when it is not :). Your "fixed" dbnextid was wrong. Domi's version is OK.

I am sure the bug which was reported by NetriX was caused by groupaccess(). I have fixed that function. ( and test it :) )
Got it. http://stackoverflow.com/questions/20992848/how-can-i-fetch-the-next-auto-increment-value-using-php-pdo
Git: https://github.com/php-fusion/PHP-Fusion/commit/7268ceaa80ae3cebbd1d55cee0692020d5c0e731
Initially I enabled PDO when installing v9, I assume with the latest git pull I received some PDO installments?

And that would explain why my entire website is now broken?

CodeDownload  
exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') AND news_language='English' ORDER BY ne.news_datestamp DESC LIMIT 3' at line 10' in /var/www/phpfusionmods.org/includes/db_handlers/pdo_functions_include.php:34 Stack trace: #0 /var/www/phpfusionmods.org/includes/db_handlers/pdo_functions_include.php(34): PDO->prepare('SELECT\n\t\t\t\t\tne....') #1 /var/www/phpfusionmods.org/home.php(117): dbquery('SELECT\n\t\t\t\t\tne....') #2 {main}
Fatal error: Call to a member function rowCount() on boolean in /var/www/phpfusionmods.org/includes/db_handlers/pdo_functions_include.php on line 96

The next id is a part of the state of a table. You can get the information but it can be changed by another insert before you actually insert your record.

Yes, might be of a problem. I agree. But image must be uploaded first nevertheless, because you need to verify whether image exceed size, etc. The path - is dynamic to $album_id.

I will find options anyway.. But see what have been coded 10 years ago...

https://github.com/php-fusion/PHP-Fusion/blob/7.02.07/administration/photoalbums.php#L147-L179

Line 147 - Where Nick coded:
CodeDownload  


if (!SAFEMODE && (!isset($_GET['action']) || $_GET['action'] != "edit")) {
$result = dbarray(dbquery("SHOW TABLE STATUS LIKE '".DB_PHOTO_ALBUMS."'"));
$album_id = $result['Auto_increment'];
@mkdir(PHOTOS."album_".$album_id, 0777);
@copy(IMAGES."index.php", PHOTOS."album_".$album_id."/index.php");
}



----

My problem with form_sanitizer() not uploading is that function image_upload or file_upload have validation there, and returns like 6 streams of different error types. Max size, File type not allowed, etc. I'm just too lazy to ensure consistency over every single one of them. Fix here and broken there, It was very tiring. I had been trying hard to make life easier.

These were just plain pain in the butt to correct and diagnose and test..

CodeDownload  

   if (isset($_FILES) && count($_FILES) && is_uploaded_file($_FILES['album_pic_file']['tmp_name'])) {
$album_types = array(".gif",".jpg",".jpeg",".png");
$album_pic = $_FILES['album_pic_file'];
$album_name = stripfilename($album_pic['name']);
$album_name = stripfilename(str_replace(" ", "_", strtolower(substr($album_pic['name'], 0, strrpos($album_pic['name'], ".")))));
$album_ext = strtolower(strrchr($album_pic['name'],"."));
if (!preg_match("/^[-0-9A-Z_\.\[\]\s]+$/i", $album_name)) {
$error = 1;
} elseif ($album_pic['size'] > $settings['photo_max_b']){
$error = 2;
} elseif (!in_array($album_ext, $album_types)) {
$error = 3;
} else {
// @unlink(PHOTOS."temp".$album_ext);
move_uploaded_file($album_pic['tmp_name'], PHOTOS."temp".$album_ext);
chmod(PHOTOS."temp".$album_ext, 0644);
$imagefile = @getimagesize(PHOTOS."temp".$album_ext);
if ($imagefile[0] > $settings['photo_max_w'] || $imagefile[1] > $settings['photo_max_h']) {
$error = 4;
@unlink(PHOTOS."temp".$album_ext);
} else {
$album_thumb = image_exists(PHOTOS, $album_name.$album_ext);
createthumbnail($imagefile[2], PHOTOS."temp".$album_ext, PHOTOS.$album_thumb, $settings['thumb_w'], $settings['thumb_h']);
@unlink(PHOTOS."temp".$album_ext);
}
}
}
if (!$error) {



vs.

CodeDownload  

$upload = form_sanitizer($_FILES['image_name'], '', 'image_name'); // validate, upload if image OR file is perfectly fine.
if ($upload['error'] == 0) {
$image_name = $upload['image_name'];



upload_image() function by Robert -- clearly had been placed there to upload, and handle error. Form_sanitizer is just the same syntax as embedding it. Either way you still need to upload during $_POST['save'], one way or another.

I just thought if Post handling had been done by form_sanitizer(), must as well go all the way keep it simple.

But, nextid -- and which function does the upload is 2 different issue altogether. The mysql version was done by me, tested and working fine as per v7.00 did. The PDO is totally new to me, and I have never used it. So i need the help with the integration of it..
I almost forgot to react to this:

Quote

I am working on Fusion Gallery safe mode off which need to guess the next ID so I can use defender to upload the picture to:
images/photoalbums/album_$nextID/
- by hien

I have been programming for many years but I have never needed a function like this and do not know anyone who needed. It is not a good practice.

The next id is a part of the state of a table. You can get the information but it can be changed by another insert before you actually insert your record.
Getting the last inserted ID is secure because you will get the last inserted ID by the connection.

Quote

BEFORE save happens.

a. $file_upload = form_sanitizer($_FILES['my_file'], '', 'my_file'); <----- this uploads a file.
b. dbquery("INSERT INTO photoalbum Filename = $file_upload['name']... "); <--- this creates a new row.
- by hien


It is the problem and I wrote about it earlier. The form_sanitizer should not upload anything. It is a "sanitizer". Uploading something is not the part of sanitization. The sanitizer calls the upload_image() which calls the filename_exists() which creates a directory, but it should not! It is the job of the uploader function. Since you know everything about the file before uploading, it is possible to insert the new record, get the last inserted id and move the file into its directory.

Quote

I will put it in -- db mysql functions. Someone help with PDO ok.
- by hien

I think nobody helped, because it does not work. Not because of PDO but because of wrong SQL. I have not fixed it because I do not think we really need this function.

Assume that we need it and let's see how it would work using my OOP Database layer.

One new method in AbstractDatabaseDriver:

CodeDownload  
/**
 * Get the next auto_increment id of a table
 *
 * @param string $table
 * @return int|false
 */
public function getNextId($table) {
        $status = $this->fetchAssoc($this->query('SHOW TABLE STATUS LIKE :table', array(':table' => $table)));
        return empty($status) ? false : (int) $status['Auto_increment'];
}



One function in all_functions_include.php

CodeDownload  
/**
 * Get the next auto_increment id of a table
 *
 * @param string $table
 * @return int|false
 */
function dbnextid($table) {
     return dbconnection()->getNextId($table);
}

Oh.. I used short array syntax which is valid only from PHP 5.4. It was not intentional. I just got used to use it. The fixed version is in git and I changed the PHP version of the project to 5.3 in my PHPStorm. I hope I fixed all occurrences.
Just downloaded latest Git and get : Parse error: syntax error, unexpected '[' in includes/classes/PHPFusion/Database/DatabaseFactory.php on line 98
First I must say that it is an very impressive work.
However, I feel that this one really need to perform better than our current handlers if we are going to make a transition to default it.
Nice codes and swift implementations in all honor, for me it does not vouch for an automatic implementation and replacement of the current system. All of these things need to perform as well , if it does we will have a real gain for the system.
Right now I have not seen a single thing that points in that direction, if worst come to worst I will test the performance on it my self with some data when I have the chance, it really boils down to that simple last detail for me.
I am working on Fusion Gallery safe mode off which need to guess the next ID so I can use defender to upload the picture to:
images/photoalbums/album_$nextID/

BEFORE save happens.

a. $file_upload = form_sanitizer($_FILES['my_file'], '', 'my_file'); <----- this uploads a file.
b. dbquery("INSERT INTO photoalbum Filename = $file_upload['name']... "); <--- this creates a new row.

a ID = b ID.

I coded this - in additon to dblastid(). I also need dbnextid()

CodeDownload  

function dbnextid($table_name) {
      $result = mysql_fetch_array(mysql_query("SHOW TABLE STATUS LIKE '".$table_name."'"));
      if (!empty($result)) {
         return $result['Auto_increment'];
      }
      return false;
}



I will put it in -- db mysql functions. Someone help with PDO ok.

Quote

Please enable it so we can test its performance and optimize everything out on the way.

- by hien


I tried, but something had changed because I could not reinstall the fusion. I have test it earlier and worked. I will try it again later.
Kudos for the multi db connections. Amazing work now.

Please enable it so we can test its performance and optimize everything out on the way.

And if can, a Mysqli extensions support will be roadmapped as well... I haven't really open the file to read how it works yet so we are gonna fully depend on you here..
Unfortunatelly I did not have time but now I wrote examples on github:

README.md

If you want to test it, you still need to insert this line into config.php:

CodeDownload  
$OOPDBLayer = TRUE;



@hien, @Domi: If you can test it and accept, I will remove the old mysql_functions_include.php and pdo_functions_include.php and move the all_functions_include.php into "includes/" as database_functions_include.php.
Probably you need to wait for the weekend since I do not have a free minute because of an other private, urgent work. But I am still alive and will continue the work on the database layer.
You are the man. I will post a 'wow' after I test it when I'm done with the shop.
Multiple Database connection is solved on my local machine

I will upload it to github after some test and write a full documentation. The connection handling has also changed. It is easier than it was in my first comment.

I show you a short example:

core_resources_include.php:
CodeDownload  
//New database handler functions based on enhanced OO solution
DatabaseFactory::setDefaultDriver(intval($pdo_enabled) === 1 ? DatabaseFactory::DRIVER_PDO_MYSQL : DatabaseFactory::DRIVER_MYSQL);
DatabaseFactory::registerConfiguration(DatabaseFactory::getDefaultConnectionID(), array(
   'host' => $db_host,
   'user' => $db_user,
   'password' => $db_pass,
   'database' => $db_name
));
DatabaseFactory::registerConfigurationFromFile(__DIR__.'/../config.altdbs.php');
require_once DB_HANDLERS."all_functions_include.php";


An existing config.altdbs.php is optional. It contains the additional connections' configuration:
CodeDownload  
<?php
return array(
   'test' => array(
      'host' => 'm51.wtk',
      'database' => 'test',
      'user' => 'rimelek',
      'password' => 'password',
      'driver' => 'pdo_mysql',
      'charset' => 'utf8'
   )
);



How to refer the connections:
CodeDownload  
<?php

use PHPFusion\Database\DatabaseFactory;

const IN_FUSION = true;
require_once 'includes/core_resources_include.php';
//require_once 'maincore.php';

$conn = DatabaseFactory::getConnection();
$users = $conn->fetchAllAssoc($conn->query("select * from ".DB_PREFIX."users limit 0, 1"));
var_dump($users);

$conn2 = DatabaseFactory::getConnection('test');
$users2 = $conn2->fetchAllAssoc($conn2->query("select * from users2 limit 0, 1"));
var_dump($users2);


maincore.php is not required to establish the connections. When that is included then the default dbconnect establishes the connection and save it as the default which is available also this way:
CodeDownload  
$conn = DatabaseFactory::getConnection();


or
CodeDownload  
dbconnection();


Multiple connections is not used by simple functions yet. dbquery() and other old functions uses the default connection.

Quote

So your not happy to read mine?
- by hien

Of course, I was :)

Quote

You do know you will need to update a full featured documentation with this as I did with Dynamics and Defender? because I do not have the knowledge in this.
- by hien

I thought and I will not leave anything without explanation/documentation when I will have time.

Quote


See all these major headache requests.. and you can tell, there is not all a direct answer. We even get google as the default answer.. :(

https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=32879
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=32410
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=29313
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=31283
- by hien

Some of these are not about multiple connection. Multisite with shared users does not need more connections in every case. A shared table with a "shared765372_" prefix can be enough.

Quote

CodeDownload  

$connect = new wordpress_database_instance();
$connect2 = new phpfusion_database_instance();

// a bridge
$importer_result = $connect1+2->query("SELECT * FROM ".DB_WORDPRESS_USERS." INNER JOIN ".DB_USERS." ON (xxx.xxx=xxx.xxx)");

// an importer
$get_db_columns = $connect->dbgenerator(DB_WORDPRESS);
$importer_result = $connect->query("SELECT * FROM ".DB_WORDPRESS."");
while (dbarray($importer_result)) {
foreach($get_db_columns as $column_name) {
// bind the user_id to user_id, user_name to _username
}
}


- by hien

Quote

I found the thread.. https://php-fusion.co.uk/forum/viewthread.php?thread_id=35070&pid=188964#post_188964
- by hien


You did not wrote about a really working solution. That could work if the user of the second connection had access to the both databases.
You used the connection link nowhere, so only the second connection could be used. When the second mysql_select_db() selected the database, it overwrote the first selection.

So what really happened?

You had the second connection (it was the new) and selected the second database (it was the original).

Then you put the name of the additional database into DB_CHARACTERS and wrote a select statement that specified the database before the table. To do this, the second user (if it was different) needed to have access to "mysphere" and also the original fusion database.

This was the reason why you could apparently connect to multiple database. You can specify the database in a select and you can access any database you have permission to. Does not matter how many conection you have. But it works only when both databases are on the same server.

A real different connection let you access to different servers.

Quote

I looked through last night, and compared 7.03 (good thing we have it stored.. lol). https://github.com/php-fusion/PHP-Fusion/blob/7.03/themes/templates/footer.php#L113-L117, but in 9.00 the mysql_close is not there .. so when does it close? Just an off-topic question.
- by hien


I left that in the footer commented out for some days. I wrote there something like this: We do not need to manually close the connection because the PHP will close.

mysql_close() can be useful when you write a CLI application (or PHP GTK app) and the program reserved the connection too long. Or in the case when your webapplication can run too long after it selected everything from the database that it needed or when you have too many connection at the same time for some reason. But close the non-persistent connection at the end of the script does not make sense.

Only thing we need to read the documentation :)
http://php.net/manual/en/function.mys...-close.php

Quote

Using mysql_close() isn't usually necessary, as non-persistent open links are automatically closed at the end of the script's execution. See also freeing resources.
I found the thread.. https://php-fusion.co.uk/forum/viewthread.php?thread_id=35070&pid=188964#post_188964

Quote


I am happy to read it, thanks!


So your not happy to read mine? Mine comes with a highlighted bold -> Well, it's a very cool work here. LOL..

Jokes aside.

---

It was very late last night and I couldn't fully have a go at my response here, and i have fatigued finger now.. so i'm not coding eshop for today to give myself a rest.

Yes, I gave myself a good read around the internet too about mysql (fairly speaking I'm not very well versed in it), and I'm unable to try the database factory yet.

You do know you will need to update a full featured documentation with this as I did with Dynamics and Defender? because I do not have the knowledge in this.

When it comes to new things to push -- yes, many skeptical questions, nevertheless relevant. Its will definitely look like a heavy weight to disruptor to the heavy balance and natural ways of life of php-fusion community cycle.

If you are willing to push forward, it's my role here to help.. no matter how hard i try.

When I created Dynamics, I try my best to justify - https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=34818
I post screenshots, I post examples, and I post a big message - 'for the sake of the future... '. Many will be looking at the 'why', and there comes the bloat problem.

Yes, this is definitely another core engine I'm very interested in. Normal users would not need it, have it automated for them. But for developers, I hope this is going to be a Nexus ( http://dictionary.reference.com/browse/nexus ).

To the proposal of DatabaseFactory stand by this in question.
1. It's an instance.
2. So we can have a a multiple connection go at it (without fatal errors).

This is by far the 'unsolved' for the whole community until we have this. So I in a way am very glad this comes to light.

And yes, the request numbers are very high.. and remained unsolved. People want this very bad.. and we cannot tackle it because there's not a class that delivers/implemented changes to the whole of the core.

See all these major headache requests.. and you can tell, there is not all a direct answer. We even get google as the default answer.. :(

https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=32879
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=32410
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=29313
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=31283

Mind, Lipke is a very seasoned coder for us.

But if you ask anyone how to connect to our own database, there is always a very direct, solid one. You see how Netrix nails it.
https://www.php-fusion.co.uk/forum/viewthread.php?thread_id=32517 (Fast, Swift and Done - like a champ).

But with 2-3 db connection.. truth to be told. The answer is always you need to edit maincore.php, and I think if we resort to that, it's nothing but core developers fault if you ask me..

And then someone will come in and say "Oh yes, I found a way!" ..
https://php-fusion.co.uk/forum/viewthread.php?thread_id=35712&pid=192299

You further hack into our core methods.. hmm.. Craig's response is "OH NOES!" funny.

And here is our "Want to do lists" -

We gonna hack ourselves to fulfill these as well... albeit DatabaseFactory or make a 3rd (non-maincore) party script. The question is not to fetch the query, the question is how to dual connect.

https://php-fusion.co.uk/forum/viewthread.php?thread_id=35536&pid=191324 -- So before this, this roadmap is dead or "pending next 999 years."

In this particular roadmap, it's not to write a script on how to query wordpress.. or joomla, it's how to connect 2 live connections, join them together without hacking the core.

With the core stand by today, it's impossible to do this. So the roadmap would very much be a virtual one, not reality.

What will come into reality to the roadmap if we are able to do this...

CodeDownload  

$connect = new wordpress_database_instance();
$connect2 = new phpfusion_database_instance();

// a bridge
$importer_result = $connect1+2->query("SELECT * FROM ".DB_WORDPRESS_USERS." INNER JOIN ".DB_USERS." ON (xxx.xxx=xxx.xxx)");

// an importer
$get_db_columns = $connect->dbgenerator(DB_WORDPRESS);
$importer_result = $connect->query("SELECT * FROM ".DB_WORDPRESS."");
while (dbarray($importer_result)) {
foreach($get_db_columns as $column_name) {
// bind the user_id to user_id, user_name to _username
}
}




My attempted on this : I can't find my link anymore, but many months ago, I have made earlier to do a help on the same (out of interest), and I cannot find any other way than directly make a permanent change in maincore to solve the question.
(I will show you the link when i find it.)

In the question, the guy asked, he have another game_db which he stores his users "game character" info.
But in gist, I directly hack into maincore.php with 2 dbconnect.. and combine them at $userdata after authentication around here..
https://github.com/php-fusion/PHP-Fusion/blob/9.00/maincore.php#L126

Frankly, I'm embarassed with such a tutorial...hacking core is just not cool. But our dbquery is limited.

It is perhaps a chance to redeem ourselves with this new toy.

---

So, in essence I was looking for an answer clear & crisp one like how Netrix tackled the question, and not to beat around the bush with it with the new database driver.

In my opinion, to be able to bridge multiple database connection in an instance is a very big winning factor, (I can show you more and more posts where my opinion come from)

I can already think a couple of very beneficial scenarios here, and will definitely justify the databaseFactory if you have a way into it during release, and we will need samples how to achieve it. - Even if we need to restructure the whole core.. I'm sure everyone will need to get a good run for it.

And yes, I hope for a round 2 from you to make a milestone out of this if you can work a new config out.

-- off topic --

I looked through last night, and compared 7.03 (good thing we have it stored.. lol). https://github.com/php-fusion/PHP-Fusion/blob/7.03/themes/templates/footer.php#L113-L117, but in 9.00 the mysql_close is not there .. so when does it close? Just an off-topic question.

Quote

I like the way this is going,
- by JoiNNN

I am happy to read it, thanks! :)
Thread Information
Author
Replies
24 posts
Views
4,567 times
Last Post
Last updated on 5 years ago
You can view all discussion threads in this forum.
You can start a new discussion thread in this forum.
You cannot reply in this discussion thread.
You cannot start on a poll in this forum.
You cannot upload attachments in this forum.
You cannot download attachments in this forum.