Μετατροπή από K2 σε Joomla

Από τη στιγμή που ανακοινώθηκε πως το K2 for Joomla δεν θα αναβαθμιστεί για εκδόσεις Joomla μετά την έκδοση 3 προέκυψε η ανάγκη να μετατρέψουμε το περιεχόμενό μας σε Joomla articles προκειμένου να μπορέσουμε να αναβαθμίσουμε το Joomla

Αν το site μας είναι μικρό τα πράγματα είναι σχετικά απλά. Τι γίνεται όμως όταν έχουμε ένα μεγάλο site με K2 πχ ένα ειδησεογραφικό με 300.000+ άρθρα;

Θα σας δείξουμε τα βήματα για να κάνετε γρήγορα, εύκολα και με ασφάλεια την μετατροπή από K2 σε Jooomla articles.

Εννοείτε πως πριν κάνετε οτιδήποτε πρέπει να έχετε πάρει Backup και δεν έχουμε εμείς κάποια ευθύνη αν κάτι πάει στραβά στον δικό σας σέρβερ. Οτι θα διαβάσετε εδώ έχει δοκιμαστεί με επιτυχία αλλά επειδή ο δικός σας σέρβερ και η δική σας εγκατάσταση Joomla έχει διαφορετικό configuration μπορεί να χρειαστεί να ακολουθήσετε διαφορετικό δρόμο σε κάποια σημεία. Η λογική πάντως είναι η ίδια.

Στο συγκεκριμένο παράδειγμα που θα δούμε, έχουμε μια εγκατάσταση Joomla 3 (3.10.20 elts) με template Rockettheme (και αυτή η εταιρία έχει κλείσει οπότε περάσαμε σε template Joomlead) σε framework Gantry 5 με την τελευταία έκδοση K2  

Ροή 
Α: Migration σε Joomla 3
Μεταφορά K2 άρθρων
Μεταφορά K2 tags
Μεταφορά K2 tag relations

Β: Update Joomla 3 → Joomla 4/5/6
Core update
Extensions update
Database fixes

ΒΗΜΑ 1 φτιάχνουμε ένα αντίγραφο του site και της βάσης δεδομένων έτσι ώστε αν πάει κάτι στραβά να μην έχουμε πρόβλημα.

Θα χρειαστούμε επίσης πρόσβαση SSH και κάποιο πρόγραμμα διαχείρισης της database πχ phpmyAdmin ή Navicat κτλ

Βρίσκουμε τα paths στον server μας. Πχ θα δουλέψουμε στο /var/www/vhosts/mydomain.gr/dev.mydomain.gr/

ΒΗΜΑ 2 Οπως γνωρίζετε το K2 αποθηκεύει πολλαπλές εκδόσεις των φωτογραφιών στους φακέλους: media/k2/items/cache και media/k2/items/src 

Εμείς χρειαζόμαστε μόνο μία φωτογραφία για κάθε άρθρο, οπότε επιλέγουμε την φωτογραφία που έχει κατάληξη *_L.jpg, θα φτιάξουμε έναν φάκελο μέσα στο images πχ K2 και θα αντιγράψουμε εκεί μέσα όλες τις φωτογραφίες με κατάληξη *_L.jpg έτσι ώστε μετά να τις συσχετίσουμε με τα αντιστοιχα Joomla άρθρα. Εννοείται πως επειδή σε ένα μεγάλο site αυτές θα είναι πάρα πάρα πολλές θα το κάνουμε μέσω SSH στον server (λογικά αν έχετε ένα site με 100.000+ άρθρα θα έχετε dedicated server ή vps οπότε θα έχετε και προσβαση SSH). Μην δοκιμάσετε να το κάνετε με άλλο τρόπο (πχ plesk file manager) γιατί θα προκαλέσετε overload ή δεν θα ολοκληρωθεί η διαδικασία ή θα κάνετε χάλια τα permissions.

Πρώτα λοιπόν φτιάχνουμε τον φάκελο προορισμού

mkdir -p /var/www/vhosts/mydomain.gr/dev.mydomain.gr/images/k2/

Αντιγραφή όλων των K2 εικόνων τύπου _L.jpg χωρίς overwrite με σωστά permissions έτσι ώστε αν χρειαστεί να κάνουμε ενημέρωση των άρθρων K2 που προστέθηκαν από το live site να το ξανατρέξουμε χωρίς να κάνει copy χιλιάδες αρχεία πάλι χωρίς λόγο

find "/var/www/vhosts/mydomain.gr/dev.mydomain.gr/media/k2/items/cache/" -type f -name "*_L.jpg" -print0 | xargs -0 -I {} cp -pn "{}" "/var/www/vhosts/mydomain.gr/dev.mydomain.gr/images/k2/"

Εννοείται πως αλλάζετε τα paths με αυτά του δικού σας server

Μόλις τελειώσει κάνουμε και έναν έλεγχο 

find /var/www/vhosts/mydomain.gr/dev.mydomain.gr/images/k2 -type f -name "*_L.jpg" | wc -l

BHMA 3 Αντιστοίχιση πεδίων στην database. Θα περάσουμε τα πεδία που χρειαζόμαστε από πίνακες του K2 στους αντίστοιχους πίνακες των Joomla articles

σε πρώτη φάση θα αντιστοιχίσουμε τα βασικά πεδία πό τον πίνακα k2_items στον πίνακα content

Πριν από την αντιστοίχιση πρέπει να φτιάξουμε τις κατηγορίες Joomla ίδιες με τις κατηγορίες του K2. Μόλις τις φτιάξουμε μπαίνουμε στην db με phpmyAdmin και αλλάζουμε τα ID των joomla κατηγοριών έτσι ώστε να είναι ΙΔΙΑ με αυτά των κατηγοριών Κ2

Επίσης αδειάζουμε όλα τα άρθρα Joomla (και από τον κάδο) έτσι ώστε να ειναι άδειος ο πίνακας ή φροντίζουμε να έχουμε κρατήσει Joomla άρθρα τα οποία δεν θα έχουν κανένα ίδιο ID με τα K2 άρθρα.

Καλό θα είναι να έχουμε εγκαταστήσει το PWT ACL για να διορθώνουμε τα assets εύκολα μετά από κάθε πείραγμα της db

Σε γενικές γραμμές η αντιστοίχιση των πεδίων είναι αυτή:

Αντιστοίχιση των πεδίων (εκτός tags και images που θα το κάνουμε μετά)

Εννοείται αλλάζουμε το jos με το prefix της δικής μας DB

INSERT INTO `jos_content`
(
    id,
    asset_id,
    title,
    alias,
    introtext,
    `fulltext`,
    state,
    catid,
    created,
    created_by,
    created_by_alias,
    modified,
    modified_by,
    publish_up,
    publish_down,
    images,
    urls,
    attribs,
    version,
    ordering,
    metakey,
    metadesc,
    access,
    hits,
    metadata,
    language
)
SELECT
    k.id,
    0 AS asset_id,
    k.title,
    k.alias,
    k.introtext,
    k.`fulltext`,

    CASE
        WHEN k.trash = 1 THEN -1
        WHEN k.published = 1 THEN 1
        ELSE 0
    END AS state,

    k.catid,
    k.created,
    k.created_by,
    '' AS created_by_alias,
    k.modified,
    k.modified_by,
    k.publish_up,
    k.publish_down,

    '' AS images,
    '' AS urls,
    '' AS attribs,
    1 AS version,
    0 AS ordering,
    '' AS metakey,
    '' AS metadesc,
    k.access,
    k.hits,
    '' AS metadata,
    '*' AS language

FROM `jos_k2_items` AS k;

Μετά την εκτέλεση του script: Joomla Administrator → Extensions → Manage → Database → FIX

και τρέχουμε το PWT ACL για να κάνει τις απαραιτητες διορθώσεις

ΒΗΜΑ 4 Αντιστοίχιση των άρθρων Joomla με τις φωτογραφίες που έχουμε αντιγράψει στο images/K2

UPDATE `jos_content`
SET images = CONCAT(
    '{',
    '"image_intro":"images/k2/', MD5(CONCAT('Image', id)), '_L.jpg",',
    '"float_intro":"",',
    '"image_intro_alt":"",',
    '"image_intro_caption":"",',
    '"image_fulltext":"images/k2/', MD5(CONCAT('Image', id)), '_L.jpg",',
    '"float_fulltext":"",',
    '"image_fulltext_alt":"",',
    '"image_fulltext_caption":""',
    '}'
)
WHERE id IN (SELECT id FROM `jos_k2_items`);

Ελεγχος μετά

SELECT id, images 
FROM jos_content
WHERE images != ''
LIMIT 5;

τρέχουμε πάλι το PWT ACL για να κάνει τις απαραιτητες διορθώσεις

ΒΗΜΑ 5 Αντιστοίχιση tags

Καθαρισμός υπαρχόντων Joomla tags

TRUNCATE jos_tags;

Κάνουμε την μεταφορά των tags 

Αλλάζουμε τα σωστά στη δική μας περίπτωση:

εδώ έχουμε 

  • ROOT tag έχει id = 1

  • Super User έχει id = 460

INSERT INTO jos_tags
(
    id,
    parent_id,
    lft,
    rgt,
    level,
    path,
    title,
    alias,
    note,
    description,
    published,
    checked_out,
    checked_out_time,
    access,
    language,
    created_user_id,
    created_time,
    created_by_alias
)
SELECT
    t.id,
    1 AS parent_id,
    0 AS lft,
    0 AS rgt,
    1 AS level,
    '' AS path,
    t.name AS title,
    LOWER(REPLACE(t.name, ' ', '-')) AS alias,
    '' AS note,
    '' AS description,
    t.published,
    0 AS checked_out,
    NULL AS checked_out_time,
    1 AS access,
    '*' AS language,
    460 AS created_user_id,
    NOW() AS created_time,
    'migration-k2' AS created_by_alias
FROM jos_k2_tags AS t;

Εισαγωγή συσχέτισης των tags

INSERT IGNORE INTO jos_contentitem_tag_map
(
    type_alias,
    core_content_id,
    content_item_id,
    tag_id,
    tag_date,
    type_id
)
SELECT DISTINCT
    'com_content.article'          AS type_alias,
    u.core_content_id              AS core_content_id,
    c.id                           AS content_item_id,
    x.tagid                        AS tag_id,
    NOW()                          AS tag_date,
    1                              AS type_id
FROM jos_k2_tags_xref AS x
JOIN jos_content AS c
    ON c.id = x.itemid
JOIN jos_ucm_content AS u
    ON u.core_type_alias = 'com_content.article'
   AND u.core_content_item_id = c.id;

Μετά την εκτέλεση του script: Joomla Administrator → Extensions → Manage → Database → FIX

και τρέχουμε το PWT ACL για να κάνει τις απαραιτητες διορθώσεις

Σε περίπτωση που χρησιμοποιείτε Simple image gallery joomlaworks σημειώνετε το path των galleries σας πχ images/galleries και κάνετε απεγκατάσταση. Μπορείτε να χρησιμοποιήσετε το sige image gallery βάζοντας το ίδιο path πχ images/galleries και όλα τα galleries που είχατε θα δουλέψουν σωστά γιατί χρησιμοποιεί το ίδιο shortcode και είναι συμβατό με όλες τις νεότερες εκδόσεις Joomla

Έλεγχος αν όλα τα Joomla άρθρα διαβάζουν εικόνα από τον φάκελο images/k2

SELECT COUNT(*) 
FROM jos_content
WHERE images LIKE '%k2/%';

Έλεγχος να δούμε αν και ποια modules χρησιμοποιούν κ2 component έτσι ώστε να τα απεγκαταστήσουμε και να τα αντικαταστήσουμε. 

SELECT id, title, module 
FROM jos_modules
WHERE module LIKE '%k2%';

Έλεγχος αν υπάρχουν ακόμα μενού που χρησιμοποιούν k2 για να τα αλλάξουμε μετά και να τα συσχετίσουμε με articles έτσι ώστε να παραμείνουν τα ίδια urls

SELECT id, title, link 
FROM jos_menu
WHERE link LIKE '%com_k2%';

Αν όλα είναι οκ μπορούμε να προχωρήσουμε σε πλήρη απεγκατάσταση του K2

Διόρθωση orphan assets (χρειάζεται για Joomla upgrade μετα την απεγκατασταση κ2)

DELETE FROM jos_assets WHERE name LIKE 'com_k2%';

Μετά πάλι: Joomla Administrator → Extensions → Manage → Database → FIX

και τρέχουμε πάλι το PWT ACL για να κάνει τις απαραιτητες διορθώσεις

Προσθήκη στο .htaccess ετσι ωστε τα παλιά URL's του K2 που έχουν μέσα το /item/ να δουλεύουν χωρίς αυτό και να μην βγάζουν 404

RewriteRule ^(.+)/item/([0-9]+)-(.*)$ /$1/$2-$3 [R=301,L]

Το .htaccess μπορείτε να το φτιάχνετε σωστα με Akeeba Admin Tools

Αφου έχουμε τελειώσει με το K2 μπορούμε να προχωρήσουμε προσεκτικά τις γνωστες διαδικασίες και να αναβαθμίσουμε μέχρι την τελευταια έκδοση. Στη συγκεκριμένη περίπτωση του παραδείγματος φτάσαμε εύκολα μέχρι την τελευταία έκδοση 6

Αν πριν την απεγκατάσταση του K2 θέλετε να ενημερώσετε τα προσφατα άρθρα από το live site σας:

τρέχετε πάλι το ΒΗΜΑ 2 για τις φωτό και μετά:

αν πχ θέλετε να πάρετε τα άρθρα μετά τα προηγούμενα 200.000 που πήρατε: 

SET @last_id = 200000;



INSERT INTO `jos_content`
(
    id,
    asset_id,
    title,
    alias,
    introtext,
    fulltext,
    state,
    catid,
    created,
    created_by,
    created_by_alias,
    modified,
    modified_by,
    publish_up,
    publish_down,
    images,
    urls,
    attribs,
    version,
    ordering,
    metakey,
    metadesc,
    access,
    hits,
    metadata,
    language
)
SELECT
    k.id,
    0 AS asset_id,
    k.title,
    k.alias,
    k.introtext,
    k.fulltext,
    CASE
        WHEN k.trash = 1 THEN -1
        WHEN k.published = 1 THEN 1
        ELSE 0
    END AS state,
    k.catid,
    k.created,
    k.created_by,
    '' AS created_by_alias,
    k.modified,
    k.modified_by,
    k.publish_up,
    k.publish_down,
    '' AS images,
    '' AS urls,
    '' AS attribs,
    1 AS version,
    0 AS ordering,
    '' AS metakey,
    '' AS metadesc,
    k.access,
    k.hits,
    '' AS metadata,
    '*' AS language

FROM `jos_k2_items` AS k
WHERE k.id > @last_id;