Wie erstelle ich einen effizienten Inhaltsfilter für bestimmte Beiträge?

Ich habe diesen Beitrag als WordPress getaggt, bin mir aber nicht ganz sicher, ob er WordPress-spezifisch ist. Deshalb veröffentliche ich ihn eher auf StackOverflow als auf WPSE.Die Lösung muss nicht WordPress-spezifisch sein, sondern nur PHP.

Das Szenario
Ich leite eineFischzucht-Website mit einer Reihe von tropischen FischenSpecies Profiles undGlossary Einträge.

Unsere Website orientiert sich an unseren Profilen. Sie sind, wie Sie es nennen können, das Brot und die Butter der Website.

Ich hoffe, dass ich in jedem Artenprofil, in dem eine andere Art oder ein Glossareintrag erwähnt wird, diese Wörter durch einen Link ersetzen kann - wie Sie sehen werdenHier. Im Idealfall möchte ich dies auch in Nachrichten, Artikeln und Blog-Posts tun.

Wir haben fast1400 species profiles und1700 glossary entries. Unsere Artenprofile sind oft langwierig und zählen zuletzt nur unsere Artenprofilenumbered more than 1.7 million words von Informationen.

Was ich gerade versuche
Derzeit habe ich einefilter.php mit einer Funktion, die - glaube ich - das tut, wofür ich sie brauche. Der Code ist ziemlich lang und kann vollständig gefunden werdenHier.

Außerdem in meinem WordPress-Themefunctions.phpIch habe folgendes:

# ==============================================================================================
# [Filter]
#
# Every hour, using WP_Cron, `my_updated_posts` is checked. If there are new Post IDs in there,
# it will run a filter on all of the post's content. The filter will search for Glossary terms
# and scientific species names. If found, it will replace those names with links including a 
# pop-up.

    include "filter.php";

# ==============================================================================================
# When saving a post (new or edited), check to make sure it isn't a revision then add its ID
# to `my_updated_posts`.

    add_action( 'save_post', 'my_set_content_filter' );
    function my_set_content_filter( $post_id ) {
        if ( !wp_is_post_revision( $post_id ) ) {

            $post_type = get_post_type( $post_id );

            if ( $post_type == "species" || ( $post_type == "post" && in_category( "articles", $post_id ) ) || ( $post_type == "post" && in_category( "blogs", $post_id ) ) ) {
                //get the previous value
                $ids = get_option( 'my_updated_posts' );

                //add new value if necessary
                if( !in_array( $post_id, $ids ) ) {
                    $ids[] = $post_id;
                    update_option( 'my_updated_posts', $ids );
                }
            }
        }
    }

# ==============================================================================================
# Add the filter to WP_Cron.

    add_action( 'my_filter_posts_content', 'my_filter_content' );
    if( !wp_next_scheduled( 'my_filter_posts_content' ) ) {
        wp_schedule_event( time(), 'hourly', 'my_filter_posts_content' );
    }

# ==============================================================================================
# Run the filter.

    function my_filter_content() {
        //check to see if posts need to be parsed
        if ( !get_option( 'my_updated_posts' ) )
            return false;

        //parse posts
        $ids = get_option( 'my_updated_posts' );

        update_option( 'error_check', $ids );

        foreach( $ids as $v ) {
            if ( get_post_status( $v ) == 'publish' )
                run_filter( $v );

            update_option( 'error_check', "filter has run at least once" );
        }

        //make sure no values have been added while loop was running
        $id_recheck = get_option( 'my_updated_posts' );
        my_close_out_filter( $ids, $id_recheck );

        //once all options, including any added during the running of what could be a long cronjob are done, remove the value and close out
        delete_option( 'my_updated_posts' );
        update_option( 'error_check', 'working m8' );
        return true;
    }

# ==============================================================================================
# A "difference" function to make sure no new posts have been added to `my_updated_posts` whilst
# the potentially time-consuming filter was running.

    function my_close_out_filter( $beginning_array, $end_array ) {
        $diff = array_diff( $beginning_array, $end_array );
        if( !empty ( $diff ) ) {
            foreach( $diff as $v ) {
                run_filter( $v );
            }
        }
        my_close_out_filter( $end_array, get_option( 'my_updated_posts' ) );
    }

Dies funktioniert, wie (hoffentlich) in den Kommentaren des Codes beschrieben, so, dass WordPress jede Stunde einen Cron-Job ausführt (was wie ein falscher Cron aussieht), der bei Benutzertreffern funktioniert, aber das spielt keine Rolle, da das Timing nicht stimmt wichtig), auf dem der oben gefundene Filter läuft.

Die Gründe für die stündliche Ausführung waren: Wenn wir versuchen würden, sie auszuführen, wenn jeder Beitrag gespeichert würde, würde dies zu Lasten des Autors gehen. Sobald wir Gastautoren einbeziehen, ist dies offensichtlich keine akzeptable Vorgehensweise.

Das Problem...
Seit Monaten habe ich Probleme, diesen Filter zuverlässig zum Laufen zu bringen. Ich glaube nicht, dass das Problem beim Filter selbst liegt, sondern bei einer der Funktionen, die den Filter aktivieren - dh dem Cron-Job oder der Funktion, die auswählt, welche Beiträge gefiltert werden, oder der Funktion, die die Wortlisten usw. vorbereitet Der Filter.

Leider ist die Diagnose des Problems recht schwierig (wie ich sehe), da es im Hintergrund und nur stündlich ausgeführt wird. Ich habe versucht, WordPress zu verwendenupdate_option Funktion (die im Grunde genommen einen einfachen Datenbankwert schreibt) zur Fehlerprüfung, aber ich hatte nicht viel Glück - und um ehrlich zu sein, bin ich ziemlich verwirrt, wo das Problem liegt.

Am Ende haben wir die Website live geschaltet, ohne dass dieser Filter richtig funktioniert. Manchmal scheint es zu funktionieren, manchmal nicht. Infolgedessen haben wir jetzt einige Artenprofile, die nicht richtig gefiltert werden.

Was ich gerne hätte ...
Grundsätzlich suche ich Rat, wie man diesen Filter am besten laufen lässt.

Ist ein Cron Job die Antwort? Ich kann eine einrichten.php Datei, die jeden Tag läuft, das wäre kein Problem. Wie würde es bestimmen, welche Beiträge gefiltert werden müssen? Welche Auswirkungen hätte dies zum Zeitpunkt der Ausführung auf den Server?

Ist alternativ eine WordPress-Admin-Seite die Antwort? Wenn ich wüsste, wie es geht, wäre etwas in der Art einer Seite - unter Verwendung von AJAX - perfekt, mit dem ich die Posts auswählen kann, auf denen der Filter ausgeführt werden soll. Es gibt ein Plugin namensAJAX Regenerate Thumbnails was funktioniert so, vielleicht wäre das das effektivste?

Überlegungen

Die Größe der betroffenen / gelesenen / geschriebenen Datenbank / InformationWelche Beiträge werden gefiltertDie Auswirkung des Filters auf den Server. vor allem, wenn ich bedenke, dass ich das WordPress-Speicherlimit nicht auf über 32 MB erhöhen kann.Ist der eigentliche Filter selbst effizient, effektiv und zuverlässig?

Dies ist eine recht komplexe Frage, und ich habe unweigerlich (da ich ungefähr 18 Mal von Kollegen abgelenkt wurde) einige Details ausgelassen. Bitte zögern Sie nicht, mich für weitere Informationen zu kontaktieren.

Danke im Voraus,

Antworten auf die Frage(1)

Ihre Antwort auf die Frage