I'm creating Joomla3 component and I need to create some dummy content during the installation, I know that I can use sql file to fill the tables, but this works mainly for custom created tables specific for my component. Problem arises when I want to add something to the #__content table, the 'alias' column isn't considered as unique and there can occur duplicate entries, if someone tries to install the component several times.
I would like to know what is the best way to insert a record into #__content table without worrying about collateral damage like duplicate entries.
Thanks all !
Solution 1 :
You can use INSERT IGNORE so that while installing extension multiple times there will be no concern of duplicate entries.
Solution 2 :
In Joomla there is a provision of script file which a component can have.
So, when an extension is installed/update/uninstall joomla triggers or calls certain predefined function like install, update, preflight, postflight etc available in the extension script file.
You can add install method in your extension script and execute this sql file on this method so that this will not be called on extension update case
Solution 3 :
You can maintain a separate table in your database for this task and when you perform this dummy content creation you can mark this in your DB and further you can check whether this step has already done or not before initiating dummy content creation so that when someone install this extension multiple times this checking will prevent the same task to execute again and again.
Related
Is there a convenient way to remove obsolete table columns from the database? I'm wondering if there is a more convention-based solutions rather than logging into PHPMyADMIN and deleting columns manually.
Example
When installing SilverStripe-Fluent and adding an extra locale (eg nz-NZ) the module will split each SiteTree record to add extra translation columns with prefix _nz-NZ. Suppose we delete the extra locale (nz-NZ), the columns will stay there after a /dev/build.
there was a great module DBPlumber for version 2.4 that had this function but I'm guessing you are using a later version! It would be great if this was upgraded for V3.
The module artefact cleaner would be ideal. Its description from the github page is...
Find and optionally delete disused tables and fields in a SilverStripe
database.
During development of a SilverStripe application it is common to
delete a data object class or remove a field from a data object. This
leaves obsolete columns and tables in your database. Because these
columns or tables may contain data that you still want, the
SilverStripe framework doesn't delete those automatically. This task
displays the obsolete columns and tables in the form of SQL DROP and
ALTER commands. It also provides a way to delete them. If you do that,
there is no undo, so always make a backup first.
I'm developing an application using CakePHP (latest version) framework for PHP that will unite several instalations of a CMS with a single registration form. I'm using a MySql DB. The problem is that I cannot modify the CMS code, I can only modify the DB data since very frequent CMS updates will overwrite my modifications.
The idea is that the system will keep a master Users table as shown in the diagram with the shared data. The table model of the master Users table and the child Users table is the same, except for a few CMS installation specific columns (as shown in the simplified diagram).
Now I'm trying to figure out a way to reflect the changes I do on master (INSERT and UPDATE) to occur on all of the child DBs. So when I make a change in my CakePHP app I want those fields that are shared to be updated in all child DB instances.
One solution would be to write manual MySQL queries for every single action in the application but that seems redundant and annoying.
How could I make my app to repeat all of the queries I do on my MASTER on every CHILD. Basicly if I UPDATE the name of entry ID 5 in MASTER, that that same query is ran on all of the child databases (which will hold the same entry under the same ID but with a few additional columns).
You could do that easily with CakePHP's model triggers (beforeSave, afterSave...) BUT keeping all that stuff synchronized will soon become your worst nightmare. Instead, I would do something like this:
Master.User has (id, name, password, specData1, specData2...)
Child1.User is a mysql VIEW: CREATE VIEW User AS SELECT id AS id, name AS name.., specData1 AS specData FROM Master.User
Yes, you can create cross-DB views. For the CMSs Child1.User is a table, all operations CREATE/DELETE/UPDATE are transparently done by the CMS on the VIEW thinking its a table. (but Master.User gets updated)
What is the best way to rebuild a model without loss data in MySQL for Symfony?
What if I have a big site, and a lot of data in the database and I would like after six months to add few new fields to database?
You can use migration.
Doctine manual
Symfony task for migrations
Slideshare presentation
Slideshare presentation
So you need write migrations, migrate, and build your models, forms, etc.
I suggest you use #denys281 for Symfony1.4 ....in Symfony2 however its VERY simple ... just use the command :
php app/console doctrine:schema:update --force
It compares what your database should look like (based on the mapping information of your entities) with how it actually looks, and generates the SQL statements needed to update the database to where it should be. In other words, if you add a new property with mapping metadata to Product and run this task again, it will generate the "alter table" statement needed to add that new column to the existing product table. So it doesnt remove any data
There is also a DoctrineMigrations bundle for Symfony2 if you fancy that route -> http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html
Hypothetically, let's say I had multiple installations of some odd MySQL/PHP driven software. They are the same software so the database table structure is the same cross all of the installs. What I want to do, is make the software use a different database prefix for just one table. Specifically, a user table. So say the installs are set up like this:
Main install: /home/www/main, database main, prefix is1
Second install: /home/www/second, database main, prefix is2
Third install: /home/www/third, database main, prefix is3
So what I want is to tell second install and third install to pull from the users table on prefix is1 for its own data via that table. Thus, any user that registers on main install is also registered on second and third and vice versa. Is it possible, and how would I do it if it is? Even if it's just a workaround that gives the same basic result I would be happy.
If you don't want to modify the app's PHP source-code, and it's not already configurable in this respect, then another option is to modify the database, changing is2users and is3users to be views on is1users:
DROP TABLE is2users;
CREATE VIEW is2users AS SELECT * FROM is1users;
DROP TABLE is3users;
CREATE VIEW is3users AS SELECT * FROM is1users;
(See http://dev.mysql.com/doc/refman/5.0/en/views.html for general information on views, http://dev.mysql.com/doc/refman/5.0/en/create-view.html for information on CREATE VIEW specifically.)
Depending on the app, this may not work perfectly -- for example, the app might cache some information in memory (such as the current value of an identifier-sequence) -- but it will probably work. Test it before putting it in production!
Your php code likely goes something like this in something like cfg.php:
$prefix = 'is3'
and in something like user.model.php:
$sql = 'SELECT * FROM `'.$prefix.'users`';
So you need to change in two of three installs code for working with 'users' table. But it seems to be too dangerous.
The setup of this is easy, schema-wise. You mention 'installs' which means you are using some packaged library which probably contains a config file where you can change various settings, and chances are one of the settings is the table prefix. If there is no table prefix option you can browse the install code and find where the schema is located and change the prefix manually for each install.
Now comes the hardpart, getting the code to behave as you described. You will have to make your app aware of all three databases, meaning you will probably have to add two new database connectors to the code (one connector for each database). Then you will have to add logic to handle user CRUD functionality to insert/update/delete user data across all three databases (transaction would be good here).
What you are describing is possible, but will require some custom code.
i am wondering how can i have simple versioning, say i want to be able to undo past edits (just up to 3 will do) to a post. maybe because the app allows other user to edit a post. but i may want the owner to restore the post for example.
do i just store the full post in another field?
One suggestion could be something like this:
you propably have each post as a separate row in the table and it has indexes that point to right threat and you retain their order by those indexes.
Add a "revision" to each post row. Everytime user edits the post, you store a new row into table but with higher revision. And when showing the posts, you just fetch the one with highest revision..
I've done this previously by creating a table which contains the following columns:
id, serialisation value of entire row you want backed up, the table it is for, datetime, why the backup was created.
That way you have a complete listing of all the versions of that table. I use Doctrine ORM so that way I can setup a postSave hook to create a new backup version in that table.
Doctrine Versionable Bebaviour may be the simplest solution for you:
Doctrine - Doctrine ORM for PHP - Versionable