Plugin Directory

Changeset 3497078


Ignore:
Timestamp:
04/01/2026 10:38:16 PM (4 days ago)
Author:
1platform
Message:

Update to version 2.14.0 from GitHub

Location:
1platform-content-ai
Files:
28 added
6 deleted
32 edited
1 copied

Legend:

Unmodified
Added
Removed
  • 1platform-content-ai/tags/2.14.0/.git/FETCH_HEAD

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16        branch 'main' of https://github.com/1platformlabs/1platform-content-ai
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3        branch 'main' of https://github.com/1platformlabs/1platform-content-ai
  • 1platform-content-ai/tags/2.14.0/.git/ORIG_HEAD

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3
  • 1platform-content-ai/tags/2.14.0/.git/config

    r3493505 r3497078  
    1010    auto = 0
    1111[http "https://github.com/"]
    12     extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzX2dkMkduMGxrUUVQNzc4RElJQ29KTFlWWUg2aDFiTDFWTmtZaQ==
     12    extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzX3FkdU9YSEdKY05ubEpNYnEyV29BbkNwVngzeUtybjJWOXJ3bw==
    1313[branch "main"]
    1414    remote = origin
  • 1platform-content-ai/tags/2.14.0/.git/logs/HEAD

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 e418fa987f34e94dc67f3511d9ea9f140ad4eb16 runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    checkout: moving from master to main
     10000000000000000000000000000000000000000 bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3 runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    checkout: moving from master to main
  • 1platform-content-ai/tags/2.14.0/.git/logs/refs/heads/main

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 e418fa987f34e94dc67f3511d9ea9f140ad4eb16 runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    branch: Created from refs/remotes/origin/main
     10000000000000000000000000000000000000000 bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3 runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    branch: Created from refs/remotes/origin/main
  • 1platform-content-ai/tags/2.14.0/.git/logs/refs/remotes/origin/hotfix/fix-job-queue-cron-self-healing-issue-39

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 6a700de81959c5223e1038b4d493b8fa54344cff runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
     10000000000000000000000000000000000000000 6a700de81959c5223e1038b4d493b8fa54344cff runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
  • 1platform-content-ai/tags/2.14.0/.git/logs/refs/remotes/origin/main

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 e418fa987f34e94dc67f3511d9ea9f140ad4eb16 runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
     10000000000000000000000000000000000000000 bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3 runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
  • 1platform-content-ai/tags/2.14.0/.git/refs/heads/main

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3
  • 1platform-content-ai/tags/2.14.0/.git/refs/remotes/origin/main

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3
  • 1platform-content-ai/tags/2.14.0/1platform-content-ai.php

    r3493505 r3497078  
    55 * Plugin URI: https://1platform.pro/
    66 * Description: SaaS client for AI-powered content generation, SEO optimization, and site management. All AI processing happens on 1Platform external servers. Includes free local tools: Table of Contents and Internal Links.
    7  * Version: 2.12.5
     7 * Version: 2.14.0
    88 * Author: 1Platform
    99 * License: GPLv2 or later
     
    187187    $controller = new ContaiAgentRestController();
    188188    $controller->register_routes();
     189
     190    require_once plugin_dir_path( __FILE__ ) . 'includes/services/adsense/ContaiAdSenseRestController.php';
     191    $adsense_controller = new ContaiAdSenseRestController();
     192    $adsense_controller->register_routes();
    189193} );
    190194
     
    343347}
    344348add_action('admin_notices', 'contai_display_migration_error_notice');
     349
     350/**
     351 * Display AdSense policy issue notices.
     352 */
     353function contai_display_adsense_policy_notice() {
     354    if ( ! current_user_can( 'manage_options' ) ) {
     355        return;
     356    }
     357
     358    $policy_count = get_transient( 'contai_adsense_policy_count' );
     359    if ( $policy_count === false || (int) $policy_count === 0 ) {
     360        return;
     361    }
     362
     363    printf(
     364        '<div class="notice notice-warning"><p>%s</p></div>',
     365        esc_html( sprintf(
     366            /* translators: %d: number of policy issues */
     367            __( '%d AdSense policy issue(s) detected. Review in Tools > Ads Manager.', '1platform-content-ai' ),
     368            (int) $policy_count
     369        ) )
     370    );
     371}
     372add_action( 'admin_notices', 'contai_display_adsense_policy_notice' );
  • 1platform-content-ai/tags/2.14.0/includes/admin/admin-apps.php

    r3493400 r3497078  
    117117        }
    118118
     119        // AdSense Account tab CSS (loaded alongside ads-manager)
     120        if ($section === 'ads-manager') {
     121            contai_enqueue_style_with_version(
     122                'contai-adsense-account',
     123                $css_base_url . 'adsense-account.css',
     124                ['contai-apps-base']
     125            );
     126        }
     127
    119128        $section_js_map = [
    120129            'ads-manager' => 'publisher-panel.js',
     
    130139            );
    131140        }
     141
     142        // AdSense Account tab JS (loaded alongside ads-manager)
     143        if ($section === 'ads-manager') {
     144            $js_base_url = plugin_dir_url(__FILE__) . 'apps/assets/js/';
     145            contai_enqueue_script_with_version(
     146                'contai-adsense-account',
     147                $js_base_url . 'adsense-account.js',
     148                [],
     149                true
     150            );
     151            wp_localize_script('contai-adsense-account', 'contaiAdsense', [
     152                'restUrl' => esc_url_raw(rest_url('contai/v1/adsense/')),
     153                'nonce'   => wp_create_nonce('wp_rest'),
     154            ]);
     155        }
    132156    }
    133157}
  • 1platform-content-ai/tags/2.14.0/includes/admin/apps/assets/css/publisher-panel.css

    r3483422 r3497078  
    395395}
    396396
     397/* ===================================================
     398   AdSense Account Tab -- Empty & Connected States
     399   Mirrors Google Analytics panel UX
     400   =================================================== */
     401
     402/* --- Empty State --- */
     403.contai-ads-manager .contai-adsense-empty {
     404    text-align: center;
     405    padding: var(--contai-spacing-xl) var(--contai-spacing-lg);
     406    max-width: 560px;
     407    margin: 0 auto;
     408}
     409
     410.contai-ads-manager .contai-adsense-empty__icon {
     411    width: 64px;
     412    height: 64px;
     413    border-radius: var(--contai-radius-lg);
     414    background: var(--contai-primary-glow);
     415    display: inline-flex;
     416    align-items: center;
     417    justify-content: center;
     418    margin-bottom: var(--contai-spacing-md);
     419}
     420
     421.contai-ads-manager .contai-adsense-empty__icon .dashicons {
     422    font-size: 32px;
     423    width: 32px;
     424    height: 32px;
     425    color: var(--contai-primary);
     426}
     427
     428.contai-ads-manager .contai-adsense-empty h3 {
     429    font-size: 20px;
     430    font-weight: 600;
     431    color: var(--contai-neutral-700);
     432    margin: 0 0 var(--contai-spacing-xs);
     433}
     434
     435.contai-ads-manager .contai-adsense-empty p {
     436    color: var(--contai-neutral-500);
     437    font-size: 14px;
     438    line-height: 1.6;
     439    margin: 0 0 var(--contai-spacing-lg);
     440}
     441
     442/* --- Steps --- */
     443.contai-ads-manager .contai-adsense-steps {
     444    display: flex;
     445    flex-direction: column;
     446    gap: var(--contai-spacing-md);
     447    max-width: 460px;
     448    margin: 0 auto var(--contai-spacing-lg);
     449    text-align: left;
     450}
     451
     452.contai-ads-manager .contai-adsense-step {
     453    display: flex;
     454    align-items: flex-start;
     455    gap: var(--contai-spacing-sm);
     456    padding: var(--contai-spacing-sm) var(--contai-spacing-md);
     457    border-radius: var(--contai-radius-md);
     458    background: var(--contai-neutral-50);
     459    border: 1px solid var(--contai-neutral-200);
     460    transition: border-color 0.2s, background 0.2s;
     461}
     462
     463.contai-ads-manager .contai-adsense-step.active {
     464    border-color: var(--contai-primary-border);
     465    background: var(--contai-primary-glow);
     466}
     467
     468.contai-ads-manager .contai-adsense-step.done {
     469    border-color: var(--contai-success-border);
     470    background: var(--contai-success-bg);
     471}
     472
     473.contai-ads-manager .contai-adsense-step__num {
     474    width: 28px;
     475    height: 28px;
     476    border-radius: 50%;
     477    background: var(--contai-neutral-200);
     478    color: var(--contai-neutral-600);
     479    display: flex;
     480    align-items: center;
     481    justify-content: center;
     482    font-size: 13px;
     483    font-weight: 700;
     484    flex-shrink: 0;
     485}
     486
     487.contai-ads-manager .contai-adsense-step.active .contai-adsense-step__num {
     488    background: var(--contai-primary);
     489    color: #fff;
     490}
     491
     492.contai-ads-manager .contai-adsense-step.done .contai-adsense-step__num {
     493    background: var(--contai-success);
     494    color: #fff;
     495}
     496
     497.contai-ads-manager .contai-adsense-step h4 {
     498    font-size: 14px;
     499    font-weight: 600;
     500    color: var(--contai-neutral-700);
     501    margin: 0 0 2px;
     502}
     503
     504.contai-ads-manager .contai-adsense-step p {
     505    font-size: 12px;
     506    color: var(--contai-neutral-500);
     507    margin: 0;
     508    line-height: 1.4;
     509}
     510
     511/* --- OAuth Button --- */
     512.contai-ads-manager .contai-btn-oauth {
     513    display: inline-flex;
     514    align-items: center;
     515    gap: 8px;
     516    padding: 12px 24px;
     517    background: var(--contai-primary);
     518    color: #fff;
     519    border: none;
     520    border-radius: var(--contai-radius-md);
     521    font-size: 14px;
     522    font-weight: 600;
     523    cursor: pointer;
     524    transition: background 0.2s, box-shadow 0.2s;
     525}
     526
     527.contai-ads-manager .contai-btn-oauth:hover {
     528    background: var(--contai-primary-dark);
     529    box-shadow: var(--contai-shadow-md);
     530    color: #fff;
     531}
     532
     533.contai-ads-manager .contai-btn-oauth:disabled {
     534    opacity: 0.6;
     535    cursor: not-allowed;
     536}
     537
     538.contai-ads-manager .contai-btn-oauth .dashicons {
     539    font-size: 18px;
     540    width: 18px;
     541    height: 18px;
     542}
     543
     544/* --- Connected State --- */
     545.contai-ads-manager .contai-adsense-connected {
     546    display: flex;
     547    flex-direction: column;
     548    gap: var(--contai-spacing-lg);
     549    padding: var(--contai-spacing-lg);
     550}
     551
     552.contai-ads-manager .contai-adsense-header {
     553    display: flex;
     554    align-items: center;
     555    justify-content: space-between;
     556    padding-bottom: var(--contai-spacing-md);
     557    border-bottom: 1px solid var(--contai-neutral-200);
     558}
     559
     560.contai-ads-manager .contai-adsense-header__left {
     561    display: flex;
     562    align-items: center;
     563    gap: var(--contai-spacing-sm);
     564}
     565
     566.contai-ads-manager .contai-adsense-badge {
     567    display: inline-flex;
     568    align-items: center;
     569    gap: 6px;
     570    padding: 4px 12px;
     571    border-radius: var(--contai-radius-pill);
     572    font-size: 13px;
     573    font-weight: 600;
     574    background: var(--contai-success-bg);
     575    color: var(--contai-success-text);
     576    border: 1px solid var(--contai-success-border);
     577}
     578
     579.contai-ads-manager .contai-adsense-badge .dashicons {
     580    font-size: 14px;
     581    width: 14px;
     582    height: 14px;
     583    color: var(--contai-success);
     584}
     585
     586.contai-ads-manager .contai-adsense-mid {
     587    font-family: monospace;
     588    font-size: 14px;
     589    color: var(--contai-neutral-600);
     590    background: var(--contai-neutral-100);
     591    padding: 4px 10px;
     592    border-radius: var(--contai-radius-sm);
     593}
     594
     595.contai-ads-manager .contai-adsense-loading {
     596    display: flex;
     597    align-items: center;
     598    gap: var(--contai-spacing-xs);
     599    font-size: 13px;
     600    color: var(--contai-neutral-500);
     601}
     602
     603.contai-ads-manager .contai-adsense-loading .spinner {
     604    float: none;
     605    margin: 0;
     606}
     607
     608/* --- Feature Grid --- */
     609.contai-ads-manager .contai-adsense-features {
     610    display: grid;
     611    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
     612    gap: var(--contai-spacing-md);
     613}
     614
     615.contai-ads-manager .contai-adsense-feature {
     616    background: var(--contai-neutral-50);
     617    border: 1px solid var(--contai-neutral-200);
     618    border-radius: var(--contai-radius-md);
     619    padding: var(--contai-spacing-md);
     620    display: flex;
     621    align-items: flex-start;
     622    gap: var(--contai-spacing-sm);
     623}
     624
     625.contai-ads-manager .contai-adsense-feature__icon {
     626    width: 36px;
     627    height: 36px;
     628    border-radius: var(--contai-radius-sm);
     629    display: flex;
     630    align-items: center;
     631    justify-content: center;
     632    flex-shrink: 0;
     633}
     634
     635.contai-ads-manager .contai-adsense-feature__icon--blue {
     636    background: var(--contai-info-bg);
     637    color: var(--contai-primary);
     638}
     639
     640.contai-ads-manager .contai-adsense-feature__icon--green {
     641    background: var(--contai-success-bg);
     642    color: var(--contai-success);
     643}
     644
     645.contai-ads-manager .contai-adsense-feature__icon--amber {
     646    background: var(--contai-warning-bg);
     647    color: var(--contai-warning);
     648}
     649
     650.contai-ads-manager .contai-adsense-feature__icon--purple {
     651    background: #f3e8ff;
     652    color: #7c3aed;
     653}
     654
     655.contai-ads-manager .contai-adsense-feature__icon .dashicons {
     656    font-size: 18px;
     657    width: 18px;
     658    height: 18px;
     659}
     660
     661.contai-ads-manager .contai-adsense-feature h4 {
     662    font-size: 13px;
     663    font-weight: 600;
     664    color: var(--contai-neutral-700);
     665    margin: 0 0 2px;
     666}
     667
     668.contai-ads-manager .contai-adsense-feature p {
     669    font-size: 12px;
     670    color: var(--contai-neutral-500);
     671    margin: 0;
     672    line-height: 1.4;
     673}
     674
     675/* --- Earnings Summary --- */
     676.contai-ads-manager .contai-adsense-earnings-summary {
     677    padding-top: var(--contai-spacing-md);
     678    border-top: 1px solid var(--contai-neutral-200);
     679}
     680
     681.contai-ads-manager .contai-adsense-earnings-summary h4 {
     682    font-size: 14px;
     683    font-weight: 600;
     684    color: var(--contai-neutral-700);
     685    margin: 0 0 var(--contai-spacing-md);
     686}
     687
     688.contai-ads-manager .contai-adsense-earnings-val {
     689    font-weight: 700;
     690    color: var(--contai-success) !important;
     691}
     692
     693/* --- Disconnect / Actions --- */
     694.contai-ads-manager .contai-adsense-disconnect {
     695    display: flex;
     696    align-items: center;
     697    gap: var(--contai-spacing-sm);
     698    padding-top: var(--contai-spacing-md);
     699    border-top: 1px solid var(--contai-neutral-200);
     700}
     701
     702.contai-ads-manager .contai-btn-disconnect {
     703    padding: 6px 16px;
     704    background: #fff;
     705    color: var(--contai-error);
     706    border: 1px solid var(--contai-error-border);
     707    border-radius: var(--contai-radius-md);
     708    font-size: 13px;
     709    font-weight: 500;
     710    cursor: pointer;
     711}
     712
     713.contai-ads-manager .contai-btn-disconnect:hover {
     714    background: var(--contai-error-bg);
     715}
     716
    397717/* --- Responsive --- */
    398718@media (max-width: 768px) {
     
    427747        padding: var(--contai-spacing-md);
    428748    }
    429 }
     749
     750    .contai-ads-manager .contai-adsense-features {
     751        grid-template-columns: 1fr;
     752    }
     753
     754    .contai-ads-manager .contai-adsense-header {
     755        flex-direction: column;
     756        align-items: flex-start;
     757        gap: var(--contai-spacing-xs);
     758    }
     759
     760    .contai-ads-manager .contai-adsense-connected {
     761        padding: var(--contai-spacing-md);
     762    }
     763}
  • 1platform-content-ai/tags/2.14.0/includes/admin/apps/panels/AdsManagerPanel.php

    r3483422 r3497078  
    154154            <!-- Tab Navigation -->
    155155            <nav class="contai-ads-tabs-nav" role="tablist">
    156                 <button type="button" class="contai-ads-tab active" data-tab="publishers" role="tab" aria-selected="true">
     156                <button type="button" class="contai-ads-tab active" data-tab="adsense-account" role="tab" aria-selected="true">
     157                    <span class="dashicons dashicons-chart-area"></span>
     158                    <span class="contai-ads-tab-label"><?php esc_html_e( 'AdSense Account', '1platform-content-ai' ); ?></span>
     159                </button>
     160                <button type="button" class="contai-ads-tab" data-tab="publishers" role="tab" aria-selected="false">
    157161                    <span class="dashicons dashicons-media-text"></span>
    158162                    <span class="contai-ads-tab-label"><?php esc_html_e( 'Publisher List', '1platform-content-ai' ); ?></span>
     
    168172            </nav>
    169173
     174            <?php $this->renderAdSenseAccountTab(); ?>
    170175            <?php $this->renderPublishersTab(); ?>
    171176            <?php $this->renderCustomHeaderTab(); ?>
     
    183188        $ads_txt_exists = file_exists( ABSPATH . 'ads.txt' );
    184189        ?>
    185         <div class="contai-ads-tab-content active" id="tab-publishers" role="tabpanel">
     190        <div class="contai-ads-tab-content" id="tab-publishers" role="tabpanel">
    186191            <form method="post">
    187192                <?php wp_nonce_field( 'contai_adsense_injector_save', 'contai_settings_nonce' ); ?>
     
    346351                            <button type="submit" name="delete_ads_txt_and_reset_publishers"
    347352                                    class="button button-danger"
    348                                     data-confirm="<?php esc_attr_e( 'Are you sure? This will permanently delete ads.txt and reset all publisher IDs.', '1platform-content-ai' ); ?>">
     353                                    onclick="return confirm('<?php echo esc_js( __( 'Are you sure? This will permanently delete ads.txt and reset all publisher IDs.', '1platform-content-ai' ) ); ?>')">
    349354                                <span class="dashicons dashicons-trash"></span>
    350355                                <?php esc_html_e( 'Delete & Reset', '1platform-content-ai' ); ?>
     
    357362        <?php
    358363    }
     364
     365    private function renderAdSenseAccountTab(): void {
     366        $is_connected = get_option( 'contai_adsense_connected', false );
     367        ?>
     368        <div class="contai-ads-tab-content active" id="tab-adsense-account" role="tabpanel">
     369            <div id="contai-adsense-account-root">
     370                <?php if ( ! $is_connected ) : ?>
     371                <div class="contai-adsense-empty">
     372                    <div class="contai-adsense-empty__icon">
     373                        <span class="dashicons dashicons-chart-area"></span>
     374                    </div>
     375                    <h3><?php esc_html_e( 'Connect Your AdSense Account', '1platform-content-ai' ); ?></h3>
     376                    <p><?php esc_html_e( 'Connect via OAuth to see earnings, site approval status, and policy alerts directly in your WordPress dashboard.', '1platform-content-ai' ); ?></p>
     377
     378                    <div class="contai-adsense-steps">
     379                        <div class="contai-adsense-step active">
     380                            <span class="contai-adsense-step__num">1</span>
     381                            <div>
     382                                <h4><?php esc_html_e( 'Authorize with Google', '1platform-content-ai' ); ?></h4>
     383                                <p><?php esc_html_e( 'Sign in with your Google account that has access to AdSense', '1platform-content-ai' ); ?></p>
     384                            </div>
     385                        </div>
     386                        <div class="contai-adsense-step">
     387                            <span class="contai-adsense-step__num">2</span>
     388                            <div>
     389                                <h4><?php esc_html_e( 'Select AdSense Account', '1platform-content-ai' ); ?></h4>
     390                                <p><?php esc_html_e( 'Choose which AdSense account to connect to this site', '1platform-content-ai' ); ?></p>
     391                            </div>
     392                        </div>
     393                        <div class="contai-adsense-step">
     394                            <span class="contai-adsense-step__num">3</span>
     395                            <div>
     396                                <h4><?php esc_html_e( 'Auto-Configure', '1platform-content-ai' ); ?></h4>
     397                                <p><?php esc_html_e( 'Earnings, approval status, and policy alerts set up automatically', '1platform-content-ai' ); ?></p>
     398                            </div>
     399                        </div>
     400                    </div>
     401
     402                    <button type="button" id="contai-adsense-connect-btn" class="contai-btn-oauth">
     403                        <span class="dashicons dashicons-admin-links"></span>
     404                        <?php esc_html_e( 'Connect AdSense', '1platform-content-ai' ); ?>
     405                    </button>
     406                </div>
     407                <?php else : ?>
     408                <div class="contai-adsense-connected">
     409                    <div class="contai-adsense-header">
     410                        <div class="contai-adsense-header__left">
     411                            <span class="contai-adsense-badge">
     412                                <span class="dashicons dashicons-yes-alt"></span>
     413                                <?php esc_html_e( 'Connected', '1platform-content-ai' ); ?>
     414                            </span>
     415                            <span class="contai-adsense-mid" id="contai-adsense-publisher-id">&mdash;</span>
     416                        </div>
     417                    </div>
     418                    <div id="contai-adsense-status-loading" class="contai-adsense-loading">
     419                        <span class="spinner is-active"></span>
     420                        <?php esc_html_e( 'Loading AdSense data...', '1platform-content-ai' ); ?>
     421                    </div>
     422                    <div id="contai-adsense-status-data" style="display:none;">
     423                        <div class="contai-adsense-features">
     424                            <div class="contai-adsense-feature">
     425                                <div class="contai-adsense-feature__icon contai-adsense-feature__icon--blue"><span class="dashicons dashicons-businessperson"></span></div>
     426                                <div>
     427                                    <h4><?php esc_html_e( 'Account', '1platform-content-ai' ); ?></h4>
     428                                    <p id="contai-adsense-account-name">&mdash;</p>
     429                                </div>
     430                            </div>
     431                            <div class="contai-adsense-feature">
     432                                <div class="contai-adsense-feature__icon contai-adsense-feature__icon--green"><span class="dashicons dashicons-admin-site-alt3"></span></div>
     433                                <div>
     434                                    <h4><?php esc_html_e( 'Site State', '1platform-content-ai' ); ?></h4>
     435                                    <p id="contai-adsense-site-state">&mdash;</p>
     436                                </div>
     437                            </div>
     438                            <div class="contai-adsense-feature">
     439                                <div class="contai-adsense-feature__icon contai-adsense-feature__icon--amber"><span class="dashicons dashicons-flag"></span></div>
     440                                <div>
     441                                    <h4><?php esc_html_e( 'Status', '1platform-content-ai' ); ?></h4>
     442                                    <p id="contai-adsense-connection-status">&mdash;</p>
     443                                </div>
     444                            </div>
     445                        </div>
     446                        <div class="contai-adsense-earnings-summary" id="contai-adsense-earnings" style="display:none;">
     447                            <h4><?php esc_html_e( 'Earnings (Last 7 Days)', '1platform-content-ai' ); ?></h4>
     448                            <div class="contai-adsense-features">
     449                                <div class="contai-adsense-feature">
     450                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--green"><span class="dashicons dashicons-money-alt"></span></div>
     451                                    <div>
     452                                        <h4><?php esc_html_e( 'Earnings', '1platform-content-ai' ); ?></h4>
     453                                        <p class="contai-adsense-earnings-val" id="contai-adsense-est-earnings">$0.00</p>
     454                                    </div>
     455                                </div>
     456                                <div class="contai-adsense-feature">
     457                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--blue"><span class="dashicons dashicons-pressthis"></span></div>
     458                                    <div>
     459                                        <h4><?php esc_html_e( 'Clicks', '1platform-content-ai' ); ?></h4>
     460                                        <p id="contai-adsense-clicks">0</p>
     461                                    </div>
     462                                </div>
     463                                <div class="contai-adsense-feature">
     464                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--purple"><span class="dashicons dashicons-visibility"></span></div>
     465                                    <div>
     466                                        <h4><?php esc_html_e( 'Impressions', '1platform-content-ai' ); ?></h4>
     467                                        <p id="contai-adsense-impressions">0</p>
     468                                    </div>
     469                                </div>
     470                                <div class="contai-adsense-feature">
     471                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--amber"><span class="dashicons dashicons-chart-line"></span></div>
     472                                    <div>
     473                                        <h4><?php esc_html_e( 'RPM', '1platform-content-ai' ); ?></h4>
     474                                        <p id="contai-adsense-rpm">$0.00</p>
     475                                    </div>
     476                                </div>
     477                            </div>
     478                        </div>
     479                    </div>
     480                    <div class="contai-adsense-disconnect">
     481                        <button type="button" id="contai-adsense-refresh-btn" class="button">
     482                            <span class="dashicons dashicons-update"></span>
     483                            <?php esc_html_e( 'Refresh', '1platform-content-ai' ); ?>
     484                        </button>
     485                        <button type="button" id="contai-adsense-disconnect-btn" class="contai-btn-disconnect">
     486                            <?php esc_html_e( 'Disconnect AdSense', '1platform-content-ai' ); ?>
     487                        </button>
     488                    </div>
     489                </div>
     490                <?php endif; ?>
     491            </div>
     492        </div>
     493        <?php
     494    }
    359495}
  • 1platform-content-ai/tags/2.14.0/readme.txt

    r3493505 r3497078  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.12.5
     7Stable tag: 2.14.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    161161== Changelog ==
    162162
     163= 2.13.0 =
     164* Added AdSense Account management tab in Ads Manager with OAuth connect/disconnect flow
     165* Added 11 REST endpoints for AdSense integration (earnings, sites, alerts, policy issues)
     166* Added earnings overview display and publisher ID auto-sync
     167* Fix: Delete confirmation dialog now works (was dead data-confirm attribute)
     168* Fix: Period parameter validation on earnings endpoint
     169* Fix: Graceful handling of non-JSON server error responses in JS
     170
    163171= 2.12.2 =
    164172* Changed: Renamed "Link Building" to "Publisuites" in Tools sidebar menu, page title, apps panel, and logs adapter
  • 1platform-content-ai/tags/2.14.0/uninstall.php

    r3493366 r3497078  
    6363    // Site hardening.
    6464    'contai_adsense_approved',
     65    'contai_adsense_connected',
     66    'contai_adsense_publisher_id',
    6567    'contai_disable_feeds',
    6668    'contai_disable_author_pages',
  • 1platform-content-ai/trunk/.git/FETCH_HEAD

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16        branch 'main' of https://github.com/1platformlabs/1platform-content-ai
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3        branch 'main' of https://github.com/1platformlabs/1platform-content-ai
  • 1platform-content-ai/trunk/.git/ORIG_HEAD

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3
  • 1platform-content-ai/trunk/.git/config

    r3493505 r3497078  
    1010    auto = 0
    1111[http "https://github.com/"]
    12     extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzX2dkMkduMGxrUUVQNzc4RElJQ29KTFlWWUg2aDFiTDFWTmtZaQ==
     12    extraheader = AUTHORIZATION: basic eC1hY2Nlc3MtdG9rZW46Z2hzX3FkdU9YSEdKY05ubEpNYnEyV29BbkNwVngzeUtybjJWOXJ3bw==
    1313[branch "main"]
    1414    remote = origin
  • 1platform-content-ai/trunk/.git/logs/HEAD

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 e418fa987f34e94dc67f3511d9ea9f140ad4eb16 runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    checkout: moving from master to main
     10000000000000000000000000000000000000000 bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3 runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    checkout: moving from master to main
  • 1platform-content-ai/trunk/.git/logs/refs/heads/main

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 e418fa987f34e94dc67f3511d9ea9f140ad4eb16 runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    branch: Created from refs/remotes/origin/main
     10000000000000000000000000000000000000000 bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3 runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    branch: Created from refs/remotes/origin/main
  • 1platform-content-ai/trunk/.git/logs/refs/remotes/origin/hotfix/fix-job-queue-cron-self-healing-issue-39

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 6a700de81959c5223e1038b4d493b8fa54344cff runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
     10000000000000000000000000000000000000000 6a700de81959c5223e1038b4d493b8fa54344cff runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
  • 1platform-content-ai/trunk/.git/logs/refs/remotes/origin/main

    r3493505 r3497078  
    1 0000000000000000000000000000000000000000 e418fa987f34e94dc67f3511d9ea9f140ad4eb16 runner <runner@runnervmrg6be.iok0aac14kyebbpycwio1tqtlb.gx.internal.cloudapp.net> 1774721755 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
     10000000000000000000000000000000000000000 bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3 runner <runner@runnervm727z3.adpnwl2l04aeti0ubxh5r103uh.cx.internal.cloudapp.net> 1775083047 +0000    fetch --prune --no-recurse-submodules origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*: storing head
  • 1platform-content-ai/trunk/.git/refs/heads/main

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3
  • 1platform-content-ai/trunk/.git/refs/remotes/origin/main

    r3493505 r3497078  
    1 e418fa987f34e94dc67f3511d9ea9f140ad4eb16
     1bf43bd6ba55ffb570e2b1d08731de25fdc48ebc3
  • 1platform-content-ai/trunk/1platform-content-ai.php

    r3493505 r3497078  
    55 * Plugin URI: https://1platform.pro/
    66 * Description: SaaS client for AI-powered content generation, SEO optimization, and site management. All AI processing happens on 1Platform external servers. Includes free local tools: Table of Contents and Internal Links.
    7  * Version: 2.12.5
     7 * Version: 2.14.0
    88 * Author: 1Platform
    99 * License: GPLv2 or later
     
    187187    $controller = new ContaiAgentRestController();
    188188    $controller->register_routes();
     189
     190    require_once plugin_dir_path( __FILE__ ) . 'includes/services/adsense/ContaiAdSenseRestController.php';
     191    $adsense_controller = new ContaiAdSenseRestController();
     192    $adsense_controller->register_routes();
    189193} );
    190194
     
    343347}
    344348add_action('admin_notices', 'contai_display_migration_error_notice');
     349
     350/**
     351 * Display AdSense policy issue notices.
     352 */
     353function contai_display_adsense_policy_notice() {
     354    if ( ! current_user_can( 'manage_options' ) ) {
     355        return;
     356    }
     357
     358    $policy_count = get_transient( 'contai_adsense_policy_count' );
     359    if ( $policy_count === false || (int) $policy_count === 0 ) {
     360        return;
     361    }
     362
     363    printf(
     364        '<div class="notice notice-warning"><p>%s</p></div>',
     365        esc_html( sprintf(
     366            /* translators: %d: number of policy issues */
     367            __( '%d AdSense policy issue(s) detected. Review in Tools > Ads Manager.', '1platform-content-ai' ),
     368            (int) $policy_count
     369        ) )
     370    );
     371}
     372add_action( 'admin_notices', 'contai_display_adsense_policy_notice' );
  • 1platform-content-ai/trunk/includes/admin/admin-apps.php

    r3493400 r3497078  
    117117        }
    118118
     119        // AdSense Account tab CSS (loaded alongside ads-manager)
     120        if ($section === 'ads-manager') {
     121            contai_enqueue_style_with_version(
     122                'contai-adsense-account',
     123                $css_base_url . 'adsense-account.css',
     124                ['contai-apps-base']
     125            );
     126        }
     127
    119128        $section_js_map = [
    120129            'ads-manager' => 'publisher-panel.js',
     
    130139            );
    131140        }
     141
     142        // AdSense Account tab JS (loaded alongside ads-manager)
     143        if ($section === 'ads-manager') {
     144            $js_base_url = plugin_dir_url(__FILE__) . 'apps/assets/js/';
     145            contai_enqueue_script_with_version(
     146                'contai-adsense-account',
     147                $js_base_url . 'adsense-account.js',
     148                [],
     149                true
     150            );
     151            wp_localize_script('contai-adsense-account', 'contaiAdsense', [
     152                'restUrl' => esc_url_raw(rest_url('contai/v1/adsense/')),
     153                'nonce'   => wp_create_nonce('wp_rest'),
     154            ]);
     155        }
    132156    }
    133157}
  • 1platform-content-ai/trunk/includes/admin/apps/assets/css/publisher-panel.css

    r3483422 r3497078  
    395395}
    396396
     397/* ===================================================
     398   AdSense Account Tab -- Empty & Connected States
     399   Mirrors Google Analytics panel UX
     400   =================================================== */
     401
     402/* --- Empty State --- */
     403.contai-ads-manager .contai-adsense-empty {
     404    text-align: center;
     405    padding: var(--contai-spacing-xl) var(--contai-spacing-lg);
     406    max-width: 560px;
     407    margin: 0 auto;
     408}
     409
     410.contai-ads-manager .contai-adsense-empty__icon {
     411    width: 64px;
     412    height: 64px;
     413    border-radius: var(--contai-radius-lg);
     414    background: var(--contai-primary-glow);
     415    display: inline-flex;
     416    align-items: center;
     417    justify-content: center;
     418    margin-bottom: var(--contai-spacing-md);
     419}
     420
     421.contai-ads-manager .contai-adsense-empty__icon .dashicons {
     422    font-size: 32px;
     423    width: 32px;
     424    height: 32px;
     425    color: var(--contai-primary);
     426}
     427
     428.contai-ads-manager .contai-adsense-empty h3 {
     429    font-size: 20px;
     430    font-weight: 600;
     431    color: var(--contai-neutral-700);
     432    margin: 0 0 var(--contai-spacing-xs);
     433}
     434
     435.contai-ads-manager .contai-adsense-empty p {
     436    color: var(--contai-neutral-500);
     437    font-size: 14px;
     438    line-height: 1.6;
     439    margin: 0 0 var(--contai-spacing-lg);
     440}
     441
     442/* --- Steps --- */
     443.contai-ads-manager .contai-adsense-steps {
     444    display: flex;
     445    flex-direction: column;
     446    gap: var(--contai-spacing-md);
     447    max-width: 460px;
     448    margin: 0 auto var(--contai-spacing-lg);
     449    text-align: left;
     450}
     451
     452.contai-ads-manager .contai-adsense-step {
     453    display: flex;
     454    align-items: flex-start;
     455    gap: var(--contai-spacing-sm);
     456    padding: var(--contai-spacing-sm) var(--contai-spacing-md);
     457    border-radius: var(--contai-radius-md);
     458    background: var(--contai-neutral-50);
     459    border: 1px solid var(--contai-neutral-200);
     460    transition: border-color 0.2s, background 0.2s;
     461}
     462
     463.contai-ads-manager .contai-adsense-step.active {
     464    border-color: var(--contai-primary-border);
     465    background: var(--contai-primary-glow);
     466}
     467
     468.contai-ads-manager .contai-adsense-step.done {
     469    border-color: var(--contai-success-border);
     470    background: var(--contai-success-bg);
     471}
     472
     473.contai-ads-manager .contai-adsense-step__num {
     474    width: 28px;
     475    height: 28px;
     476    border-radius: 50%;
     477    background: var(--contai-neutral-200);
     478    color: var(--contai-neutral-600);
     479    display: flex;
     480    align-items: center;
     481    justify-content: center;
     482    font-size: 13px;
     483    font-weight: 700;
     484    flex-shrink: 0;
     485}
     486
     487.contai-ads-manager .contai-adsense-step.active .contai-adsense-step__num {
     488    background: var(--contai-primary);
     489    color: #fff;
     490}
     491
     492.contai-ads-manager .contai-adsense-step.done .contai-adsense-step__num {
     493    background: var(--contai-success);
     494    color: #fff;
     495}
     496
     497.contai-ads-manager .contai-adsense-step h4 {
     498    font-size: 14px;
     499    font-weight: 600;
     500    color: var(--contai-neutral-700);
     501    margin: 0 0 2px;
     502}
     503
     504.contai-ads-manager .contai-adsense-step p {
     505    font-size: 12px;
     506    color: var(--contai-neutral-500);
     507    margin: 0;
     508    line-height: 1.4;
     509}
     510
     511/* --- OAuth Button --- */
     512.contai-ads-manager .contai-btn-oauth {
     513    display: inline-flex;
     514    align-items: center;
     515    gap: 8px;
     516    padding: 12px 24px;
     517    background: var(--contai-primary);
     518    color: #fff;
     519    border: none;
     520    border-radius: var(--contai-radius-md);
     521    font-size: 14px;
     522    font-weight: 600;
     523    cursor: pointer;
     524    transition: background 0.2s, box-shadow 0.2s;
     525}
     526
     527.contai-ads-manager .contai-btn-oauth:hover {
     528    background: var(--contai-primary-dark);
     529    box-shadow: var(--contai-shadow-md);
     530    color: #fff;
     531}
     532
     533.contai-ads-manager .contai-btn-oauth:disabled {
     534    opacity: 0.6;
     535    cursor: not-allowed;
     536}
     537
     538.contai-ads-manager .contai-btn-oauth .dashicons {
     539    font-size: 18px;
     540    width: 18px;
     541    height: 18px;
     542}
     543
     544/* --- Connected State --- */
     545.contai-ads-manager .contai-adsense-connected {
     546    display: flex;
     547    flex-direction: column;
     548    gap: var(--contai-spacing-lg);
     549    padding: var(--contai-spacing-lg);
     550}
     551
     552.contai-ads-manager .contai-adsense-header {
     553    display: flex;
     554    align-items: center;
     555    justify-content: space-between;
     556    padding-bottom: var(--contai-spacing-md);
     557    border-bottom: 1px solid var(--contai-neutral-200);
     558}
     559
     560.contai-ads-manager .contai-adsense-header__left {
     561    display: flex;
     562    align-items: center;
     563    gap: var(--contai-spacing-sm);
     564}
     565
     566.contai-ads-manager .contai-adsense-badge {
     567    display: inline-flex;
     568    align-items: center;
     569    gap: 6px;
     570    padding: 4px 12px;
     571    border-radius: var(--contai-radius-pill);
     572    font-size: 13px;
     573    font-weight: 600;
     574    background: var(--contai-success-bg);
     575    color: var(--contai-success-text);
     576    border: 1px solid var(--contai-success-border);
     577}
     578
     579.contai-ads-manager .contai-adsense-badge .dashicons {
     580    font-size: 14px;
     581    width: 14px;
     582    height: 14px;
     583    color: var(--contai-success);
     584}
     585
     586.contai-ads-manager .contai-adsense-mid {
     587    font-family: monospace;
     588    font-size: 14px;
     589    color: var(--contai-neutral-600);
     590    background: var(--contai-neutral-100);
     591    padding: 4px 10px;
     592    border-radius: var(--contai-radius-sm);
     593}
     594
     595.contai-ads-manager .contai-adsense-loading {
     596    display: flex;
     597    align-items: center;
     598    gap: var(--contai-spacing-xs);
     599    font-size: 13px;
     600    color: var(--contai-neutral-500);
     601}
     602
     603.contai-ads-manager .contai-adsense-loading .spinner {
     604    float: none;
     605    margin: 0;
     606}
     607
     608/* --- Feature Grid --- */
     609.contai-ads-manager .contai-adsense-features {
     610    display: grid;
     611    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
     612    gap: var(--contai-spacing-md);
     613}
     614
     615.contai-ads-manager .contai-adsense-feature {
     616    background: var(--contai-neutral-50);
     617    border: 1px solid var(--contai-neutral-200);
     618    border-radius: var(--contai-radius-md);
     619    padding: var(--contai-spacing-md);
     620    display: flex;
     621    align-items: flex-start;
     622    gap: var(--contai-spacing-sm);
     623}
     624
     625.contai-ads-manager .contai-adsense-feature__icon {
     626    width: 36px;
     627    height: 36px;
     628    border-radius: var(--contai-radius-sm);
     629    display: flex;
     630    align-items: center;
     631    justify-content: center;
     632    flex-shrink: 0;
     633}
     634
     635.contai-ads-manager .contai-adsense-feature__icon--blue {
     636    background: var(--contai-info-bg);
     637    color: var(--contai-primary);
     638}
     639
     640.contai-ads-manager .contai-adsense-feature__icon--green {
     641    background: var(--contai-success-bg);
     642    color: var(--contai-success);
     643}
     644
     645.contai-ads-manager .contai-adsense-feature__icon--amber {
     646    background: var(--contai-warning-bg);
     647    color: var(--contai-warning);
     648}
     649
     650.contai-ads-manager .contai-adsense-feature__icon--purple {
     651    background: #f3e8ff;
     652    color: #7c3aed;
     653}
     654
     655.contai-ads-manager .contai-adsense-feature__icon .dashicons {
     656    font-size: 18px;
     657    width: 18px;
     658    height: 18px;
     659}
     660
     661.contai-ads-manager .contai-adsense-feature h4 {
     662    font-size: 13px;
     663    font-weight: 600;
     664    color: var(--contai-neutral-700);
     665    margin: 0 0 2px;
     666}
     667
     668.contai-ads-manager .contai-adsense-feature p {
     669    font-size: 12px;
     670    color: var(--contai-neutral-500);
     671    margin: 0;
     672    line-height: 1.4;
     673}
     674
     675/* --- Earnings Summary --- */
     676.contai-ads-manager .contai-adsense-earnings-summary {
     677    padding-top: var(--contai-spacing-md);
     678    border-top: 1px solid var(--contai-neutral-200);
     679}
     680
     681.contai-ads-manager .contai-adsense-earnings-summary h4 {
     682    font-size: 14px;
     683    font-weight: 600;
     684    color: var(--contai-neutral-700);
     685    margin: 0 0 var(--contai-spacing-md);
     686}
     687
     688.contai-ads-manager .contai-adsense-earnings-val {
     689    font-weight: 700;
     690    color: var(--contai-success) !important;
     691}
     692
     693/* --- Disconnect / Actions --- */
     694.contai-ads-manager .contai-adsense-disconnect {
     695    display: flex;
     696    align-items: center;
     697    gap: var(--contai-spacing-sm);
     698    padding-top: var(--contai-spacing-md);
     699    border-top: 1px solid var(--contai-neutral-200);
     700}
     701
     702.contai-ads-manager .contai-btn-disconnect {
     703    padding: 6px 16px;
     704    background: #fff;
     705    color: var(--contai-error);
     706    border: 1px solid var(--contai-error-border);
     707    border-radius: var(--contai-radius-md);
     708    font-size: 13px;
     709    font-weight: 500;
     710    cursor: pointer;
     711}
     712
     713.contai-ads-manager .contai-btn-disconnect:hover {
     714    background: var(--contai-error-bg);
     715}
     716
    397717/* --- Responsive --- */
    398718@media (max-width: 768px) {
     
    427747        padding: var(--contai-spacing-md);
    428748    }
    429 }
     749
     750    .contai-ads-manager .contai-adsense-features {
     751        grid-template-columns: 1fr;
     752    }
     753
     754    .contai-ads-manager .contai-adsense-header {
     755        flex-direction: column;
     756        align-items: flex-start;
     757        gap: var(--contai-spacing-xs);
     758    }
     759
     760    .contai-ads-manager .contai-adsense-connected {
     761        padding: var(--contai-spacing-md);
     762    }
     763}
  • 1platform-content-ai/trunk/includes/admin/apps/panels/AdsManagerPanel.php

    r3483422 r3497078  
    154154            <!-- Tab Navigation -->
    155155            <nav class="contai-ads-tabs-nav" role="tablist">
    156                 <button type="button" class="contai-ads-tab active" data-tab="publishers" role="tab" aria-selected="true">
     156                <button type="button" class="contai-ads-tab active" data-tab="adsense-account" role="tab" aria-selected="true">
     157                    <span class="dashicons dashicons-chart-area"></span>
     158                    <span class="contai-ads-tab-label"><?php esc_html_e( 'AdSense Account', '1platform-content-ai' ); ?></span>
     159                </button>
     160                <button type="button" class="contai-ads-tab" data-tab="publishers" role="tab" aria-selected="false">
    157161                    <span class="dashicons dashicons-media-text"></span>
    158162                    <span class="contai-ads-tab-label"><?php esc_html_e( 'Publisher List', '1platform-content-ai' ); ?></span>
     
    168172            </nav>
    169173
     174            <?php $this->renderAdSenseAccountTab(); ?>
    170175            <?php $this->renderPublishersTab(); ?>
    171176            <?php $this->renderCustomHeaderTab(); ?>
     
    183188        $ads_txt_exists = file_exists( ABSPATH . 'ads.txt' );
    184189        ?>
    185         <div class="contai-ads-tab-content active" id="tab-publishers" role="tabpanel">
     190        <div class="contai-ads-tab-content" id="tab-publishers" role="tabpanel">
    186191            <form method="post">
    187192                <?php wp_nonce_field( 'contai_adsense_injector_save', 'contai_settings_nonce' ); ?>
     
    346351                            <button type="submit" name="delete_ads_txt_and_reset_publishers"
    347352                                    class="button button-danger"
    348                                     data-confirm="<?php esc_attr_e( 'Are you sure? This will permanently delete ads.txt and reset all publisher IDs.', '1platform-content-ai' ); ?>">
     353                                    onclick="return confirm('<?php echo esc_js( __( 'Are you sure? This will permanently delete ads.txt and reset all publisher IDs.', '1platform-content-ai' ) ); ?>')">
    349354                                <span class="dashicons dashicons-trash"></span>
    350355                                <?php esc_html_e( 'Delete & Reset', '1platform-content-ai' ); ?>
     
    357362        <?php
    358363    }
     364
     365    private function renderAdSenseAccountTab(): void {
     366        $is_connected = get_option( 'contai_adsense_connected', false );
     367        ?>
     368        <div class="contai-ads-tab-content active" id="tab-adsense-account" role="tabpanel">
     369            <div id="contai-adsense-account-root">
     370                <?php if ( ! $is_connected ) : ?>
     371                <div class="contai-adsense-empty">
     372                    <div class="contai-adsense-empty__icon">
     373                        <span class="dashicons dashicons-chart-area"></span>
     374                    </div>
     375                    <h3><?php esc_html_e( 'Connect Your AdSense Account', '1platform-content-ai' ); ?></h3>
     376                    <p><?php esc_html_e( 'Connect via OAuth to see earnings, site approval status, and policy alerts directly in your WordPress dashboard.', '1platform-content-ai' ); ?></p>
     377
     378                    <div class="contai-adsense-steps">
     379                        <div class="contai-adsense-step active">
     380                            <span class="contai-adsense-step__num">1</span>
     381                            <div>
     382                                <h4><?php esc_html_e( 'Authorize with Google', '1platform-content-ai' ); ?></h4>
     383                                <p><?php esc_html_e( 'Sign in with your Google account that has access to AdSense', '1platform-content-ai' ); ?></p>
     384                            </div>
     385                        </div>
     386                        <div class="contai-adsense-step">
     387                            <span class="contai-adsense-step__num">2</span>
     388                            <div>
     389                                <h4><?php esc_html_e( 'Select AdSense Account', '1platform-content-ai' ); ?></h4>
     390                                <p><?php esc_html_e( 'Choose which AdSense account to connect to this site', '1platform-content-ai' ); ?></p>
     391                            </div>
     392                        </div>
     393                        <div class="contai-adsense-step">
     394                            <span class="contai-adsense-step__num">3</span>
     395                            <div>
     396                                <h4><?php esc_html_e( 'Auto-Configure', '1platform-content-ai' ); ?></h4>
     397                                <p><?php esc_html_e( 'Earnings, approval status, and policy alerts set up automatically', '1platform-content-ai' ); ?></p>
     398                            </div>
     399                        </div>
     400                    </div>
     401
     402                    <button type="button" id="contai-adsense-connect-btn" class="contai-btn-oauth">
     403                        <span class="dashicons dashicons-admin-links"></span>
     404                        <?php esc_html_e( 'Connect AdSense', '1platform-content-ai' ); ?>
     405                    </button>
     406                </div>
     407                <?php else : ?>
     408                <div class="contai-adsense-connected">
     409                    <div class="contai-adsense-header">
     410                        <div class="contai-adsense-header__left">
     411                            <span class="contai-adsense-badge">
     412                                <span class="dashicons dashicons-yes-alt"></span>
     413                                <?php esc_html_e( 'Connected', '1platform-content-ai' ); ?>
     414                            </span>
     415                            <span class="contai-adsense-mid" id="contai-adsense-publisher-id">&mdash;</span>
     416                        </div>
     417                    </div>
     418                    <div id="contai-adsense-status-loading" class="contai-adsense-loading">
     419                        <span class="spinner is-active"></span>
     420                        <?php esc_html_e( 'Loading AdSense data...', '1platform-content-ai' ); ?>
     421                    </div>
     422                    <div id="contai-adsense-status-data" style="display:none;">
     423                        <div class="contai-adsense-features">
     424                            <div class="contai-adsense-feature">
     425                                <div class="contai-adsense-feature__icon contai-adsense-feature__icon--blue"><span class="dashicons dashicons-businessperson"></span></div>
     426                                <div>
     427                                    <h4><?php esc_html_e( 'Account', '1platform-content-ai' ); ?></h4>
     428                                    <p id="contai-adsense-account-name">&mdash;</p>
     429                                </div>
     430                            </div>
     431                            <div class="contai-adsense-feature">
     432                                <div class="contai-adsense-feature__icon contai-adsense-feature__icon--green"><span class="dashicons dashicons-admin-site-alt3"></span></div>
     433                                <div>
     434                                    <h4><?php esc_html_e( 'Site State', '1platform-content-ai' ); ?></h4>
     435                                    <p id="contai-adsense-site-state">&mdash;</p>
     436                                </div>
     437                            </div>
     438                            <div class="contai-adsense-feature">
     439                                <div class="contai-adsense-feature__icon contai-adsense-feature__icon--amber"><span class="dashicons dashicons-flag"></span></div>
     440                                <div>
     441                                    <h4><?php esc_html_e( 'Status', '1platform-content-ai' ); ?></h4>
     442                                    <p id="contai-adsense-connection-status">&mdash;</p>
     443                                </div>
     444                            </div>
     445                        </div>
     446                        <div class="contai-adsense-earnings-summary" id="contai-adsense-earnings" style="display:none;">
     447                            <h4><?php esc_html_e( 'Earnings (Last 7 Days)', '1platform-content-ai' ); ?></h4>
     448                            <div class="contai-adsense-features">
     449                                <div class="contai-adsense-feature">
     450                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--green"><span class="dashicons dashicons-money-alt"></span></div>
     451                                    <div>
     452                                        <h4><?php esc_html_e( 'Earnings', '1platform-content-ai' ); ?></h4>
     453                                        <p class="contai-adsense-earnings-val" id="contai-adsense-est-earnings">$0.00</p>
     454                                    </div>
     455                                </div>
     456                                <div class="contai-adsense-feature">
     457                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--blue"><span class="dashicons dashicons-pressthis"></span></div>
     458                                    <div>
     459                                        <h4><?php esc_html_e( 'Clicks', '1platform-content-ai' ); ?></h4>
     460                                        <p id="contai-adsense-clicks">0</p>
     461                                    </div>
     462                                </div>
     463                                <div class="contai-adsense-feature">
     464                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--purple"><span class="dashicons dashicons-visibility"></span></div>
     465                                    <div>
     466                                        <h4><?php esc_html_e( 'Impressions', '1platform-content-ai' ); ?></h4>
     467                                        <p id="contai-adsense-impressions">0</p>
     468                                    </div>
     469                                </div>
     470                                <div class="contai-adsense-feature">
     471                                    <div class="contai-adsense-feature__icon contai-adsense-feature__icon--amber"><span class="dashicons dashicons-chart-line"></span></div>
     472                                    <div>
     473                                        <h4><?php esc_html_e( 'RPM', '1platform-content-ai' ); ?></h4>
     474                                        <p id="contai-adsense-rpm">$0.00</p>
     475                                    </div>
     476                                </div>
     477                            </div>
     478                        </div>
     479                    </div>
     480                    <div class="contai-adsense-disconnect">
     481                        <button type="button" id="contai-adsense-refresh-btn" class="button">
     482                            <span class="dashicons dashicons-update"></span>
     483                            <?php esc_html_e( 'Refresh', '1platform-content-ai' ); ?>
     484                        </button>
     485                        <button type="button" id="contai-adsense-disconnect-btn" class="contai-btn-disconnect">
     486                            <?php esc_html_e( 'Disconnect AdSense', '1platform-content-ai' ); ?>
     487                        </button>
     488                    </div>
     489                </div>
     490                <?php endif; ?>
     491            </div>
     492        </div>
     493        <?php
     494    }
    359495}
  • 1platform-content-ai/trunk/readme.txt

    r3493505 r3497078  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 2.12.5
     7Stable tag: 2.14.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    161161== Changelog ==
    162162
     163= 2.13.0 =
     164* Added AdSense Account management tab in Ads Manager with OAuth connect/disconnect flow
     165* Added 11 REST endpoints for AdSense integration (earnings, sites, alerts, policy issues)
     166* Added earnings overview display and publisher ID auto-sync
     167* Fix: Delete confirmation dialog now works (was dead data-confirm attribute)
     168* Fix: Period parameter validation on earnings endpoint
     169* Fix: Graceful handling of non-JSON server error responses in JS
     170
    163171= 2.12.2 =
    164172* Changed: Renamed "Link Building" to "Publisuites" in Tools sidebar menu, page title, apps panel, and logs adapter
  • 1platform-content-ai/trunk/uninstall.php

    r3493366 r3497078  
    6363    // Site hardening.
    6464    'contai_adsense_approved',
     65    'contai_adsense_connected',
     66    'contai_adsense_publisher_id',
    6567    'contai_disable_feeds',
    6668    'contai_disable_author_pages',
Note: See TracChangeset for help on using the changeset viewer.