Plugin Directory

Changeset 3416344


Ignore:
Timestamp:
12/10/2025 11:34:13 AM (3 months ago)
Author:
chrmrtns
Message:

Version 1.2.0 - Variable font support with weight ranges, toggle in upload form, automatic CSS generation

Location:
safefonts
Files:
34 added
9 edited

Legend:

Unmodified
Added
Removed
  • safefonts/trunk/LICENSE

    r3388505 r3416344  
    11GPL v2 License
    22
    3 Copyright (c) 2024 Chris Martens
     3Copyright (c) 2025 Chris Martens
    44
    55This WordPress plugin is licensed under the GNU General Public License v2.0.
    66
    7 See: https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
     7                    GNU GENERAL PUBLIC LICENSE
     8                       Version 2, June 1991
     9
     10 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
     11 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     12 Everyone is permitted to copy and distribute verbatim copies
     13 of this license document, but changing it is not allowed.
     14
     15                            Preamble
     16
     17  The licenses for most software are designed to take away your
     18freedom to share and change it.  By contrast, the GNU General Public
     19License is intended to guarantee your freedom to share and change free
     20software--to make sure the software is free for all its users.  This
     21General Public License applies to most of the Free Software
     22Foundation's software and to any other program whose authors commit to
     23using it.  (Some other Free Software Foundation software is covered by
     24the GNU Lesser General Public License instead.)  You can apply it to
     25your programs, too.
     26
     27  When we speak of free software, we are referring to freedom, not
     28price.  Our General Public Licenses are designed to make sure that you
     29have the freedom to distribute copies of free software (and charge for
     30this service if you wish), that you receive source code or can get it
     31if you want it, that you can change the software or use pieces of it
     32in new free programs; and that you know you can do these things.
     33
     34  To protect your rights, we need to make restrictions that forbid
     35anyone to deny you these rights or to ask you to surrender the rights.
     36These restrictions translate to certain responsibilities for you if you
     37distribute copies of the software, or if you modify it.
     38
     39  For example, if you distribute copies of such a program, whether
     40gratis or for a fee, you must give the recipients all the rights that
     41you have.  You must make sure that they, too, receive or can get the
     42source code.  And you must show them these terms so they know their
     43rights.
     44
     45  We protect your rights with two steps: (1) copyright the software, and
     46(2) offer you this license which gives you legal permission to copy,
     47distribute and/or modify the software.
     48
     49  Also, for each author's protection and ours, we want to make certain
     50that everyone understands that there is no warranty for this free
     51software.  If the software is modified by someone else and passed on, we
     52want its recipients to know that what they have is not the original, so
     53that any problems introduced by others will not reflect on the original
     54authors' reputations.
     55
     56  Finally, any free program is threatened constantly by software
     57patents.  We wish to avoid the danger that redistributors of a free
     58program will individually obtain patent licenses, in effect making the
     59program proprietary.  To prevent this, we have made it clear that any
     60patent must be licensed for everyone's free use or not licensed at all.
     61
     62  The precise terms and conditions for copying, distribution and
     63modification follow.
     64
     65                    GNU GENERAL PUBLIC LICENSE
     66   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
     67
     68  0. This License applies to any program or other work which contains
     69a notice placed by the copyright holder saying it may be distributed
     70under the terms of this General Public License.  The "Program", below,
     71refers to any such program or work, and a "work based on the Program"
     72means either the Program or any derivative work under copyright law:
     73that is to say, a work containing the Program or a portion of it,
     74either verbatim or with modifications and/or translated into another
     75language.  (Hereinafter, translation is included without limitation in
     76the term "modification".)  Each licensee is addressed as "you".
     77
     78Activities other than copying, distribution and modification are not
     79covered by this License; they are outside its scope.  The act of
     80running the Program is not restricted, and the output from the Program
     81is covered only if its contents constitute a work based on the
     82Program (independent of having been made by running the Program).
     83Whether that is true depends on what the Program does.
     84
     85  1. You may copy and distribute verbatim copies of the Program's
     86source code as you receive it, in any medium, provided that you
     87conspicuously and appropriately publish on each copy an appropriate
     88copyright notice and disclaimer of warranty; keep intact all the
     89notices that refer to this License and to the absence of any warranty;
     90and give any other recipients of the Program a copy of this License
     91along with the Program.
     92
     93You may charge a fee for the physical act of transferring a copy, and
     94you may at your option offer warranty protection in exchange for a fee.
     95
     96  2. You may modify your copy or copies of the Program or any portion
     97of it, thus forming a work based on the Program, and copy and
     98distribute such modifications or work under the terms of Section 1
     99above, provided that you also meet all of these conditions:
     100
     101    a) You must cause the modified files to carry prominent notices
     102    stating that you changed the files and the date of any change.
     103
     104    b) You must cause any work that you distribute or publish, that in
     105    whole or in part contains or is derived from the Program or any
     106    part thereof, to be licensed as a whole at no charge to all third
     107    parties under the terms of this License.
     108
     109    c) If the modified program normally reads commands interactively
     110    when run, you must cause it, when started running for such
     111    interactive use in the most ordinary way, to print or display an
     112    announcement including an appropriate copyright notice and a
     113    notice that there is no warranty (or else, saying that you provide
     114    a warranty) and that users may redistribute the program under
     115    these conditions, and telling the user how to view a copy of this
     116    License.  (Exception: if the Program itself is interactive but
     117    does not normally print such an announcement, your work based on
     118    the Program is not required to print an announcement.)
     119
     120These requirements apply to the modified work as a whole.  If
     121identifiable sections of that work are not derived from the Program,
     122and can be reasonably considered independent and separate works in
     123themselves, then this License, and its terms, do not apply to those
     124sections when you distribute them as separate works.  But when you
     125distribute the same sections as part of a whole which is a work based
     126on the Program, the distribution of the whole must be on the terms of
     127this License, whose permissions for other licensees extend to the
     128entire whole, and thus to each and every part regardless of who wrote it.
     129
     130Thus, it is not the intent of this section to claim rights or contest
     131your rights to work written entirely by you; rather, the intent is to
     132exercise the right to control the distribution of derivative or
     133collective works based on the Program.
     134
     135In addition, mere aggregation of another work not based on the Program
     136with the Program (or with a work based on the Program) on a volume of
     137a storage or distribution medium does not bring the other work under
     138the scope of this License.
     139
     140  3. You may copy and distribute the Program (or a work based on it,
     141under Section 2) in object code or executable form under the terms of
     142Sections 1 and 2 above provided that you also do one of the following:
     143
     144    a) Accompany it with the complete corresponding machine-readable
     145    source code, which must be distributed under the terms of Sections
     146    1 and 2 above on a medium customarily used for software interchange; or,
     147
     148    b) Accompany it with a written offer, valid for at least three
     149    years, to give any third party, for a charge no more than your
     150    cost of physically performing source distribution, a complete
     151    machine-readable copy of the corresponding source code, to be
     152    distributed under the terms of Sections 1 and 2 above on a medium
     153    customarily used for software interchange; or,
     154
     155    c) Accompany it with the information you received as to the offer
     156    to distribute corresponding source code.  (This alternative is
     157    allowed only for noncommercial distribution and only if you
     158    received the program in object code or executable form with such
     159    an offer, in accord with Subsection b above.)
     160
     161The source code for a work means the preferred form of the work for
     162making modifications to it.  For an executable work, complete source
     163code means all the source code for all modules it contains, plus any
     164associated interface definition files, plus the scripts used to
     165control compilation and installation of the executable.  However, as a
     166special exception, the source code distributed need not include
     167anything that is normally distributed (in either source or binary
     168form) with the major components (compiler, kernel, and so on) of the
     169operating system on which the executable runs, unless that component
     170itself accompanies the executable.
     171
     172If distribution of executable or object code is made by offering
     173access to copy from a designated place, then offering equivalent
     174access to copy the source code from the same place counts as
     175distribution of the source code, even though third parties are not
     176compelled to copy the source along with the object code.
     177
     178  4. You may not copy, modify, sublicense, or distribute the Program
     179except as expressly provided under this License.  Any attempt
     180otherwise to copy, modify, sublicense or distribute the Program is
     181void, and will automatically terminate your rights under this License.
     182However, parties who have received copies, or rights, from you under
     183this License will not have their licenses terminated so long as such
     184parties remain in full compliance.
     185
     186  5. You are not required to accept this License, since you have not
     187signed it.  However, nothing else grants you permission to modify or
     188distribute the Program or its derivative works.  These actions are
     189prohibited by law if you do not accept this License.  Therefore, by
     190modifying or distributing the Program (or any work based on the
     191Program), you indicate your acceptance of this License to do so, and
     192all its terms and conditions for copying, distributing or modifying
     193the Program or works based on it.
     194
     195  6. Each time you redistribute the Program (or any work based on the
     196Program), the recipient automatically receives a license from the
     197original licensor to copy, distribute or modify the Program subject to
     198these terms and conditions.  You may not impose any further
     199restrictions on the recipients' exercise of the rights granted herein.
     200You are not responsible for enforcing compliance by third parties to
     201this License.
     202
     203  7. If, as a consequence of a court judgment or allegation of patent
     204infringement or for any other reason (not limited to patent issues),
     205conditions are imposed on you (whether by court order, agreement or
     206otherwise) that contradict the conditions of this License, they do not
     207excuse you from the conditions of this License.  If you cannot
     208distribute so as to satisfy simultaneously your obligations under this
     209License and any other pertinent obligations, then as a consequence you
     210may not distribute the Program at all.  For example, if a patent
     211license would not permit royalty-free redistribution of the Program by
     212all those who receive copies directly or indirectly through you, then
     213the only way you could satisfy both it and this License would be to
     214refrain entirely from distribution of the Program.
     215
     216If any portion of this section is held invalid or unenforceable under
     217any particular circumstance, the balance of the section is intended to
     218apply and the section as a whole is intended to apply in other
     219circumstances.
     220
     221It is not the purpose of this section to induce you to infringe any
     222patents or other property right claims or to contest validity of any
     223such claims; this section has the sole purpose of protecting the
     224integrity of the free software distribution system, which is
     225implemented by public license practices.  Many people have made
     226generous contributions to the wide range of software distributed
     227through that system in reliance on consistent application of that
     228system; it is up to the author/donor to decide if he or she is willing
     229to distribute software through any other system and a licensee cannot
     230impose that choice.
     231
     232This section is intended to make thoroughly clear what is believed to
     233be a consequence of the rest of this License.
     234
     235  8. If the distribution and/or use of the Program is restricted in
     236certain countries either by patents or by copyrighted interfaces, the
     237original copyright holder who places the Program under this License
     238may add an explicit geographical distribution limitation excluding
     239those countries, so that distribution is permitted only in or among
     240countries not thus excluded.  In such case, this License incorporates
     241the limitation as if written in the body of this License.
     242
     243  9. The Free Software Foundation may publish revised and/or new versions
     244of the General Public License from time to time.  Such new versions will
     245be similar in spirit to the present version, but may differ in detail to
     246address new problems or concerns.
     247
     248Each version is given a distinguishing version number.  If the Program
     249specifies a version number of this License which applies to it and "any
     250later version", you have the option of following the terms and conditions
     251either of that version or of any later version published by the Free
     252Software Foundation.  If the Program does not specify a version number of
     253this License, you may choose any version ever published by the Free Software
     254Foundation.
     255
     256  10. If you wish to incorporate parts of the Program into other free
     257programs whose distribution conditions are different, write to the author
     258to ask for permission.  For software which is copyrighted by the Free
     259Software Foundation, write to the Free Software Foundation; we sometimes
     260make exceptions for this.  Our decision will be guided by the two goals
     261of preserving the free status of all derivatives of our free software and
     262of promoting the sharing and reuse of software generally.
     263
     264                            NO WARRANTY
     265
     266  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
     267FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
     268OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
     269PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
     270OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     271MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
     272TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
     273PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
     274REPAIR OR CORRECTION.
     275
     276  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
     277WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
     278REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
     279INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
     280OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
     281TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
     282YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
     283PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
     284POSSIBILITY OF SUCH DAMAGES.
     285
     286                     END OF TERMS AND CONDITIONS
     287
     288            How to Apply These Terms to Your New Programs
     289
     290  If you develop a new program, and you want it to be of the greatest
     291possible use to the public, the best way to achieve this is to make it
     292free software which everyone can redistribute and change under these terms.
     293
     294  To do so, attach the following notices to the program.  It is safest
     295to attach them to the start of each source file to most effectively
     296convey the exclusion of warranty; and each file should have at least
     297the "copyright" line and a pointer to where the full notice is found.
     298
     299    <one line to give the program's name and a brief idea of what it does.>
     300    Copyright (C) <year>  <name of author>
     301
     302    This program is free software; you can redistribute it and/or modify
     303    it under the terms of the GNU General Public License as published by
     304    the Free Software Foundation; either version 2 of the License, or
     305    (at your option) any later version.
     306
     307    This program is distributed in the hope that it will be useful,
     308    but WITHOUT ANY WARRANTY; without even the implied warranty of
     309    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     310    GNU General Public License for more details.
     311
     312    You should have received a copy of the GNU General Public License along
     313    with this program; if not, write to the Free Software Foundation, Inc.,
     314    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     315
     316Also add information on how to contact you by electronic and paper mail.
     317
     318If the program is interactive, make it output a short notice like this
     319when it starts in an interactive mode:
     320
     321    Gnomovision version 69, Copyright (C) year name of author
     322    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     323    This is free software, and you are welcome to redistribute it
     324    under certain conditions; type `show c' for details.
     325
     326The hypothetical commands `show w' and `show c' should show the appropriate
     327parts of the General Public License.  Of course, the commands you use may
     328be called something other than `show w' and `show c'; they could even be
     329mouse-clicks or menu items--whatever suits your program.
     330
     331You should also get your employer (if you work as a programmer) or your
     332school, if any, to sign a "copyright disclaimer" for the program, if
     333necessary.  Here is a sample; alter the names:
     334
     335  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
     336  `Gnomovision' (which makes passes at compilers) written by James Hacker.
     337
     338  <signature of Ty Coon>, 1 April 1989
     339  Ty Coon, President of Vice
     340
     341This General Public License does not permit incorporating your program into
     342proprietary programs.  If your program is a subroutine library, you may
     343consider it more useful to permit linking proprietary applications with the
     344library.  If this is what you want to do, use the GNU Lesser General
     345Public License instead of this License.
  • safefonts/trunk/assets/css/admin.css

    r3390097 r3416344  
    199199.safefonts-font-weight {
    200200    background: #f0b429 !important;
     201}
     202
     203.safefonts-font-weight.safefonts-variable-font {
     204    background: linear-gradient(90deg, #f0b429 0%, #ff6b6b 100%) !important;
    201205}
    202206
  • safefonts/trunk/assets/js/admin.js

    r3394862 r3416344  
    1313            this.initTabs();
    1414            this.initCssRegeneration();
     15            this.initVariableFontToggle();
    1516        },
    1617
     
    182183                SafeFontsAdmin.handleCssRegeneration($(this));
    183184            });
     185        },
     186
     187        initVariableFontToggle: function() {
     188            const $checkbox = $('#is_variable');
     189            const $staticRow = $('#static-weight-row');
     190            const $variableRow = $('#variable-weight-row');
     191
     192            // Handle checkbox change
     193            $checkbox.on('change', function() {
     194                if ($(this).is(':checked')) {
     195                    $staticRow.hide();
     196                    $variableRow.show();
     197                } else {
     198                    $staticRow.show();
     199                    $variableRow.hide();
     200                }
     201            });
     202
     203            // Set initial state based on checkbox
     204            if ($checkbox.is(':checked')) {
     205                $staticRow.hide();
     206                $variableRow.show();
     207            }
    184208        },
    185209
  • safefonts/trunk/includes/Admin/AdminInterface.php

    r3395519 r3416344  
    298298                    <tr>
    299299                        <th scope="row">
     300                            <label for="is_variable"><?php esc_html_e('Variable Font', 'safefonts'); ?></label>
     301                        </th>
     302                        <td>
     303                            <label>
     304                                <input type="checkbox" id="is_variable" name="is_variable" value="1">
     305                                <?php esc_html_e('This is a variable font', 'safefonts'); ?>
     306                            </label>
     307                            <p class="description">
     308                                <?php esc_html_e('Variable fonts contain multiple weights in a single file.', 'safefonts'); ?>
     309                            </p>
     310                        </td>
     311                    </tr>
     312                    <tr id="static-weight-row">
     313                        <th scope="row">
    300314                            <label for="font_weight"><?php esc_html_e('Font Weight', 'safefonts'); ?></label>
    301315                        </th>
     
    311325                                <option value="800">800 (Extra Bold)</option>
    312326                                <option value="900">900 (Black)</option>
     327                            </select>
     328                        </td>
     329                    </tr>
     330                    <tr id="variable-weight-row" style="display: none;">
     331                        <th scope="row">
     332                            <label><?php esc_html_e('Weight Range', 'safefonts'); ?></label>
     333                        </th>
     334                        <td>
     335                            <select id="weight_min" name="weight_min">
     336                                <option value="100" selected>100 (Thin)</option>
     337                                <option value="200">200 (Extra Light)</option>
     338                                <option value="300">300 (Light)</option>
     339                                <option value="400">400 (Normal)</option>
     340                                <option value="500">500 (Medium)</option>
     341                                <option value="600">600 (Semi Bold)</option>
     342                                <option value="700">700 (Bold)</option>
     343                                <option value="800">800 (Extra Bold)</option>
     344                                <option value="900">900 (Black)</option>
     345                            </select>
     346                            <span><?php esc_html_e('to', 'safefonts'); ?></span>
     347                            <select id="weight_max" name="weight_max">
     348                                <option value="100">100 (Thin)</option>
     349                                <option value="200">200 (Extra Light)</option>
     350                                <option value="300">300 (Light)</option>
     351                                <option value="400">400 (Normal)</option>
     352                                <option value="500">500 (Medium)</option>
     353                                <option value="600">600 (Semi Bold)</option>
     354                                <option value="700">700 (Bold)</option>
     355                                <option value="800">800 (Extra Bold)</option>
     356                                <option value="900" selected>900 (Black)</option>
    313357                            </select>
    314358                        </td>
     
    411455                                           value="<?php echo esc_attr($font->id); ?>"
    412456                                           data-family="<?php echo esc_attr($font->font_family); ?>">
    413                                     <span class="safefonts-font-weight"><?php echo esc_html($font->font_weight); ?></span>
     457                                    <?php if (!empty($font->is_variable) && !empty($font->weight_min) && !empty($font->weight_max)): ?>
     458                                        <span class="safefonts-font-weight safefonts-variable-font" title="<?php esc_attr_e('Variable Font', 'safefonts'); ?>"><?php echo esc_html($font->weight_min . '-' . $font->weight_max); ?></span>
     459                                    <?php else: ?>
     460                                        <span class="safefonts-font-weight"><?php echo esc_html($font->font_weight); ?></span>
     461                                    <?php endif; ?>
    414462                                    <span class="safefonts-font-style"><?php echo esc_html($font->font_style); ?></span>
    415463                                    <?php
     
    420468                                </div>
    421469
     470                                <?php
     471                                // For variable fonts, use 400 for preview
     472                                $preview_weight = $font->font_weight;
     473                                if (!empty($font->is_variable) && !empty($font->weight_min) && !empty($font->weight_max)) {
     474                                    $preview_weight = '400';
     475                                }
     476                                ?>
    422477                                <div class="safefonts-font-preview"
    423478                                     style="font-family: '<?php echo esc_attr($font->font_family); ?>', sans-serif;
    424                                             font-weight: <?php echo esc_attr($font->font_weight); ?>;
     479                                            font-weight: <?php echo esc_attr($preview_weight); ?>;
    425480                                            font-style: <?php echo esc_attr($font->font_style); ?>;">
    426481                                    The quick brown fox jumps over the lazy dog.
  • safefonts/trunk/includes/Core.php

    r3395519 r3416344  
    499499            font_style varchar(50) NOT NULL DEFAULT 'normal',
    500500            font_weight varchar(50) NOT NULL DEFAULT '400',
     501            is_variable tinyint(1) NOT NULL DEFAULT 0,
     502            weight_min int(11) DEFAULT NULL,
     503            weight_max int(11) DEFAULT NULL,
    501504            file_path varchar(500) NOT NULL,
    502505            file_hash varchar(64) NOT NULL,
     
    519522            $wpdb->query($wpdb->prepare("ALTER TABLE %i ADD COLUMN family_slug varchar(255) NOT NULL DEFAULT '' AFTER font_family", $table_name)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Adding missing column for migration
    520523            $wpdb->query($wpdb->prepare("ALTER TABLE %i ADD KEY family_slug (family_slug)", $table_name)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Adding index for new column
     524        }
     525
     526        // Migration check: Add variable font columns if they don't exist (v1.2.0+)
     527        if (!in_array('is_variable', $columns, true)) {
     528            $wpdb->query($wpdb->prepare("ALTER TABLE %i ADD COLUMN is_variable tinyint(1) NOT NULL DEFAULT 0 AFTER font_weight", $table_name)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Adding variable font column
     529            $wpdb->query($wpdb->prepare("ALTER TABLE %i ADD COLUMN weight_min int(11) DEFAULT NULL AFTER is_variable", $table_name)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Adding weight_min column
     530            $wpdb->query($wpdb->prepare("ALTER TABLE %i ADD COLUMN weight_max int(11) DEFAULT NULL AFTER weight_min", $table_name)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Adding weight_max column
    521531        }
    522532
  • safefonts/trunk/includes/FontManager.php

    r3395519 r3416344  
    127127            $format = $this->get_font_format($font->file_path);
    128128
     129            // Check if this is a variable font
     130            $is_variable = !empty($font->is_variable);
     131
    129132            $css .= "@font-face {\n";
    130133            $css .= "  font-family: '" . esc_attr($font->font_family) . "';\n";
    131134            $css .= "  font-style: " . esc_attr($font->font_style) . ";\n";
    132             $css .= "  font-weight: " . esc_attr($font->font_weight) . ";\n";
     135
     136            // Variable fonts use weight range, static fonts use single weight
     137            if ($is_variable && !empty($font->weight_min) && !empty($font->weight_max)) {
     138                $css .= "  font-weight: " . intval($font->weight_min) . " " . intval($font->weight_max) . ";\n";
     139                // Use variable font format
     140                $format = 'woff2-variations';
     141            } else {
     142                $css .= "  font-weight: " . esc_attr($font->font_weight) . ";\n";
     143            }
     144
    133145            $css .= "  font-display: swap;\n";
    134146            $css .= "  src: url('" . esc_url($font_url) . "') format('" . $format . "');\n";
     
    224236            'font_style' => sanitize_text_field($font_info['style'] ?? 'normal'),
    225237            'font_weight' => sanitize_text_field($font_info['weight'] ?? '400'),
     238            'is_variable' => isset($font_info['is_variable']) ? intval($font_info['is_variable']) : 0,
     239            'weight_min' => isset($font_info['weight_min']) ? intval($font_info['weight_min']) : null,
     240            'weight_max' => isset($font_info['weight_max']) ? intval($font_info['weight_max']) : null,
    226241            'file_path' => $relative_path,
    227242            'file_hash' => hash_file('sha256', $destination),
     
    452467
    453468        // Get font info from form
     469        $is_variable = isset($_POST['is_variable']) && $_POST['is_variable'] === '1';
     470
    454471        $font_info = array(
    455472            'family' => isset($_POST['font_family']) ? sanitize_text_field(wp_unslash($_POST['font_family'])) : '',
    456473            'style' => isset($_POST['font_style']) ? sanitize_text_field(wp_unslash($_POST['font_style'])) : 'normal',
    457             'weight' => isset($_POST['font_weight']) ? sanitize_text_field(wp_unslash($_POST['font_weight'])) : '400'
     474            'weight' => isset($_POST['font_weight']) ? sanitize_text_field(wp_unslash($_POST['font_weight'])) : '400',
     475            'is_variable' => $is_variable ? 1 : 0,
     476            'weight_min' => $is_variable && isset($_POST['weight_min']) ? intval($_POST['weight_min']) : null,
     477            'weight_max' => $is_variable && isset($_POST['weight_max']) ? intval($_POST['weight_max']) : null
    458478        );
    459479
  • safefonts/trunk/languages/safefonts.pot

    r3395526 r3416344  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: SafeFonts 1.1.9\n"
     5"Project-Id-Version: SafeFonts 1.2.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/safefonts\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-11-14T07:25:20+00:00\n"
     12"POT-Creation-Date: 2025-12-10T11:02:25+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.12.0\n"
     
    6262#: includes/Admin/AdminInterface.php:80
    6363#: includes/Admin/AdminInterface.php:81
    64 #: includes/Admin/AdminInterface.php:461
     64#: includes/Admin/AdminInterface.php:516
    6565#: views/admin-page.php:26
    6666#: views/dashboard-page.php:69
     
    9090
    9191#: includes/Admin/AdminInterface.php:160
    92 #: includes/Admin/AdminInterface.php:361
     92#: includes/Admin/AdminInterface.php:405
    9393msgid "Uploading..."
    9494msgstr ""
     
    147147
    148148#: includes/Admin/AdminInterface.php:300
     149#: includes/Admin/AdminInterface.php:458
     150msgid "Variable Font"
     151msgstr ""
     152
     153#: includes/Admin/AdminInterface.php:305
     154msgid "This is a variable font"
     155msgstr ""
     156
     157#: includes/Admin/AdminInterface.php:308
     158msgid "Variable fonts contain multiple weights in a single file."
     159msgstr ""
     160
     161#: includes/Admin/AdminInterface.php:314
    149162msgid "Font Weight"
    150163msgstr ""
    151164
    152 #: includes/Admin/AdminInterface.php:318
     165#: includes/Admin/AdminInterface.php:332
     166msgid "Weight Range"
     167msgstr ""
     168
     169#: includes/Admin/AdminInterface.php:346
     170msgid "to"
     171msgstr ""
     172
     173#: includes/Admin/AdminInterface.php:362
    153174msgid "Font Style"
    154175msgstr ""
    155176
    156 #: includes/Admin/AdminInterface.php:329
     177#: includes/Admin/AdminInterface.php:373
    157178msgid "Font File"
    158179msgstr ""
    159180
    160 #: includes/Admin/AdminInterface.php:338
     181#: includes/Admin/AdminInterface.php:382
    161182msgid "Select a font file (.woff2, .woff, .ttf, .otf)."
    162183msgstr ""
    163184
    164 #: includes/Admin/AdminInterface.php:351
     185#: includes/Admin/AdminInterface.php:395
    165186msgid "Upload Font"
    166187msgstr ""
    167188
    168 #: includes/Admin/AdminInterface.php:353
     189#: includes/Admin/AdminInterface.php:397
    169190msgid "Upload font file"
    170191msgstr ""
    171192
    172 #: includes/Admin/AdminInterface.php:374
     193#: includes/Admin/AdminInterface.php:418
    173194msgid "No fonts found. Upload font files to get started."
    174195msgstr ""
    175196
    176 #: includes/Admin/AdminInterface.php:383
    177 #: includes/Admin/AdminInterface.php:701
     197#: includes/Admin/AdminInterface.php:427
     198#: includes/Admin/AdminInterface.php:756
    178199msgid "Installed Fonts"
    179200msgstr ""
    180201
    181 #: includes/Admin/AdminInterface.php:387
     202#: includes/Admin/AdminInterface.php:431
    182203msgid "Select All"
    183204msgstr ""
    184205
    185 #: includes/Admin/AdminInterface.php:394
     206#: includes/Admin/AdminInterface.php:438
    186207msgid "Delete Selected"
    187208msgstr ""
    188209
    189210#. translators: %s: font family name
    190 #: includes/Admin/AdminInterface.php:432
     211#: includes/Admin/AdminInterface.php:487
    191212#, php-format
    192213msgid "Delete %s font"
    193214msgstr ""
    194215
    195 #: includes/Admin/AdminInterface.php:439
     216#: includes/Admin/AdminInterface.php:494
    196217msgid "Delete"
    197218msgstr ""
    198219
    199 #: includes/Admin/AdminInterface.php:467
     220#: includes/Admin/AdminInterface.php:522
    200221msgid "Maximum File Size (MB)"
    201222msgstr ""
    202223
    203 #: includes/Admin/AdminInterface.php:478
     224#: includes/Admin/AdminInterface.php:533
    204225msgid "Maximum size for individual font files."
    205226msgstr ""
    206227
    207 #: includes/Admin/AdminInterface.php:485
    208 #: includes/Admin/AdminInterface.php:490
     228#: includes/Admin/AdminInterface.php:540
     229#: includes/Admin/AdminInterface.php:545
    209230#: views/help-page.php:129
    210231msgid "Allowed Font Types"
    211232msgstr ""
    212233
    213 #: includes/Admin/AdminInterface.php:498
     234#: includes/Admin/AdminInterface.php:553
    214235msgid "Recommended"
    215236msgstr ""
    216237
    217 #: includes/Admin/AdminInterface.php:526
     238#: includes/Admin/AdminInterface.php:581
    218239msgid "WOFF2 is recommended for best performance and compression."
    219240msgstr ""
    220241
    221 #: includes/Admin/AdminInterface.php:534
    222 #: includes/Admin/AdminInterface.php:543
     242#: includes/Admin/AdminInterface.php:589
     243#: includes/Admin/AdminInterface.php:598
    223244#: views/help-page.php:132
    224245msgid "Font Preloading"
    225246msgstr ""
    226247
    227 #: includes/Admin/AdminInterface.php:548
     248#: includes/Admin/AdminInterface.php:603
    228249msgid "No fonts uploaded yet. Upload fonts to enable preloading."
    229250msgstr ""
    230251
    231 #: includes/Admin/AdminInterface.php:562
     252#: includes/Admin/AdminInterface.php:617
    232253msgid "weights"
    233254msgstr ""
    234255
    235 #: includes/Admin/AdminInterface.php:579
     256#: includes/Admin/AdminInterface.php:634
    236257msgid "⚡ Font preloading tells the browser to download fonts earlier, reducing flash of invisible text (FOIT)."
    237258msgstr ""
    238259
    239 #: includes/Admin/AdminInterface.php:580
     260#: includes/Admin/AdminInterface.php:635
    240261msgid "Tip:"
    241262msgstr ""
    242263
    243 #: includes/Admin/AdminInterface.php:580
     264#: includes/Admin/AdminInterface.php:635
    244265msgid "Only preload 1-2 critical font weights (like your main body font weight) for best performance."
    245266msgstr ""
    246267
    247 #: includes/Admin/AdminInterface.php:589
    248 #: includes/Admin/AdminInterface.php:594
     268#: includes/Admin/AdminInterface.php:644
     269#: includes/Admin/AdminInterface.php:649
    249270#: views/help-page.php:139
    250271msgid "Data Management"
    251272msgstr ""
    252273
    253 #: includes/Admin/AdminInterface.php:602
     274#: includes/Admin/AdminInterface.php:657
    254275msgid "Delete all plugin data when uninstalling"
    255276msgstr ""
    256277
    257 #: includes/Admin/AdminInterface.php:606
     278#: includes/Admin/AdminInterface.php:661
    258279msgid "⚠️ Warning: If checked, uninstalling this plugin will permanently delete:"
    259280msgstr ""
    260281
    261 #: includes/Admin/AdminInterface.php:607
     282#: includes/Admin/AdminInterface.php:662
    262283msgid "All uploaded font files"
    263284msgstr ""
    264285
    265 #: includes/Admin/AdminInterface.php:608
     286#: includes/Admin/AdminInterface.php:663
    266287msgid "Font database records"
    267288msgstr ""
    268289
    269 #: includes/Admin/AdminInterface.php:609
     290#: includes/Admin/AdminInterface.php:664
    270291msgid "All plugin settings"
    271292msgstr ""
    272293
    273 #: includes/Admin/AdminInterface.php:610
     294#: includes/Admin/AdminInterface.php:665
    274295msgid "This cannot be undone!"
    275296msgstr ""
    276297
    277 #: includes/Admin/AdminInterface.php:610
     298#: includes/Admin/AdminInterface.php:665
    278299msgid "Leave unchecked if you plan to reinstall later."
    279300msgstr ""
    280301
    281 #: includes/Admin/AdminInterface.php:618
     302#: includes/Admin/AdminInterface.php:673
    282303msgid "Font CSS"
    283304msgstr ""
    284305
    285 #: includes/Admin/AdminInterface.php:625
     306#: includes/Admin/AdminInterface.php:680
    286307msgid "Regenerate CSS"
    287308msgstr ""
    288309
    289 #: includes/Admin/AdminInterface.php:628
     310#: includes/Admin/AdminInterface.php:683
    290311msgid "Manually regenerate the fonts.css file. This is useful if fonts aren't displaying correctly after an update."
    291312msgstr ""
    292313
    293 #: includes/Admin/AdminInterface.php:641
     314#: includes/Admin/AdminInterface.php:696
    294315msgid "Save Settings"
    295316msgstr ""
    296317
    297 #: includes/Admin/AdminInterface.php:662
     318#: includes/Admin/AdminInterface.php:717
    298319msgid "System Information"
    299320msgstr ""
    300321
    301 #: includes/Admin/AdminInterface.php:666
     322#: includes/Admin/AdminInterface.php:721
    302323msgid "Plugin Version"
    303324msgstr ""
    304325
    305 #: includes/Admin/AdminInterface.php:671
     326#: includes/Admin/AdminInterface.php:726
    306327msgid "WordPress Version"
    307328msgstr ""
    308329
    309 #: includes/Admin/AdminInterface.php:676
     330#: includes/Admin/AdminInterface.php:731
    310331msgid "PHP Version"
    311332msgstr ""
    312333
    313 #: includes/Admin/AdminInterface.php:681
     334#: includes/Admin/AdminInterface.php:736
    314335msgid "Fonts Directory"
    315336msgstr ""
    316337
    317 #: includes/Admin/AdminInterface.php:688
     338#: includes/Admin/AdminInterface.php:743
    318339msgid "Writable"
    319340msgstr ""
    320341
    321 #: includes/Admin/AdminInterface.php:690
     342#: includes/Admin/AdminInterface.php:745
    322343msgid "Not writable"
    323344msgstr ""
    324345
    325 #: includes/Admin/AdminInterface.php:696
     346#: includes/Admin/AdminInterface.php:751
    326347msgid "Fonts URL"
    327348msgstr ""
    328349
    329 #: includes/Admin/AdminInterface.php:706
     350#: includes/Admin/AdminInterface.php:761
    330351msgid "Max Upload Size"
    331352msgstr ""
    332353
    333 #: includes/Admin/AdminInterface.php:711
     354#: includes/Admin/AdminInterface.php:766
    334355msgid "Memory Limit"
    335356msgstr ""
    336357
    337 #: includes/Admin/AdminInterface.php:716
     358#: includes/Admin/AdminInterface.php:771
    338359#: views/admin-page.php:65
    339360#: views/dashboard-page.php:125
     
    342363msgstr ""
    343364
    344 #: includes/Admin/AdminInterface.php:719
     365#: includes/Admin/AdminInterface.php:774
    345366msgid "WordPress 6.5+ Font Library Supported"
    346367msgstr ""
    347368
    348 #: includes/Admin/AdminInterface.php:721
     369#: includes/Admin/AdminInterface.php:776
    349370msgid "WordPress 6.5+ required for Font Library"
    350371msgstr ""
    351372
    352 #: includes/Admin/AdminInterface.php:728
     373#: includes/Admin/AdminInterface.php:783
    353374msgid "🚀 Want More Features?"
    354375msgstr ""
    355376
    356 #: includes/Admin/AdminInterface.php:729
     377#: includes/Admin/AdminInterface.php:784
    357378msgid "Upgrade to SafeFonts Pro for:"
    358379msgstr ""
    359380
    360 #: includes/Admin/AdminInterface.php:731
     381#: includes/Admin/AdminInterface.php:786
    361382msgid "✅ Page Builder Integration (Elementor, Bricks, Beaver Builder, Divi, Oxygen)"
    362383msgstr ""
    363384
    364 #: includes/Admin/AdminInterface.php:732
     385#: includes/Admin/AdminInterface.php:787
    365386msgid "✅ Bulk ZIP Package Import from Google Fonts Downloader"
    366387msgstr ""
    367388
    368 #: includes/Admin/AdminInterface.php:733
     389#: includes/Admin/AdminInterface.php:788
    369390msgid "✅ Professional Admin Interface with Drag & Drop"
    370391msgstr ""
    371392
    372 #: includes/Admin/AdminInterface.php:734
     393#: includes/Admin/AdminInterface.php:789
    373394msgid "✅ Advanced Font Management Tools"
    374395msgstr ""
    375396
    376 #: includes/Admin/AdminInterface.php:738
     397#: includes/Admin/AdminInterface.php:793
    377398msgid "Learn More About SafeFonts Pro →"
    378399msgstr ""
     
    577598msgstr ""
    578599
    579 #: includes/Core.php:791
    580 #: includes/Core.php:803
     600#: includes/Core.php:801
     601#: includes/Core.php:813
    581602msgid "SafeFonts Error:"
    582603msgstr ""
    583604
    584605#. translators: %s: directory path
    585 #: includes/Core.php:794
     606#: includes/Core.php:804
    586607#, php-format
    587608msgid "Could not create the fonts directory at <code>%s</code>. Please create this directory manually and ensure it is writable by the web server."
     
    589610
    590611#. translators: %s: directory path
    591 #: includes/Core.php:806
     612#: includes/Core.php:816
    592613#, php-format
    593614msgid "The fonts directory at <code>%s</code> is not writable. Please set the correct permissions (755 or 775) for this directory."
    594615msgstr ""
    595616
    596 #: includes/Core.php:810
     617#: includes/Core.php:820
    597618msgid "You can fix this by running:"
    598619msgstr ""
    599620
    600 #: includes/FontManager.php:182
     621#: includes/FontManager.php:194
    601622msgid "Failed to create font family directory."
    602623msgstr ""
    603624
    604 #: includes/FontManager.php:189
     625#: includes/FontManager.php:201
    605626msgid "Font directory is not writable. Check file permissions."
    606627msgstr ""
    607628
    608 #: includes/FontManager.php:205
     629#: includes/FontManager.php:217
    609630msgid "Failed to copy font file."
    610631msgstr ""
    611632
    612 #: includes/FontManager.php:210
     633#: includes/FontManager.php:222
    613634msgid "Font file was not copied to destination."
    614635msgstr ""
    615636
    616 #: includes/FontManager.php:238
     637#: includes/FontManager.php:253
    617638msgid "Failed to save font to database."
    618639msgstr ""
    619640
    620 #: includes/FontManager.php:258
     641#: includes/FontManager.php:273
    621642msgid "Font file not found."
    622643msgstr ""
    623644
    624 #: includes/FontManager.php:264
     645#: includes/FontManager.php:279
    625646msgid "Font file is too large."
    626647msgstr ""
    627648
    628649#. translators: %1$s: file extension, %2$s: allowed file types
    629 #: includes/FontManager.php:283
     650#: includes/FontManager.php:298
    630651#, php-format
    631652msgid "Font file extension \"%1$s\" is not allowed. Allowed types: %2$s"
     
    633654
    634655#. translators: %1$s: detected MIME type, %2$s: file extension
    635 #: includes/FontManager.php:294
     656#: includes/FontManager.php:309
    636657#, php-format
    637658msgid "Font file MIME type \"%1$s\" is not valid for .%2$s files."
    638659msgstr ""
    639660
    640 #: includes/FontManager.php:299
     661#: includes/FontManager.php:314
    641662msgid "Font file signature validation failed."
    642663msgstr ""
    643664
    644 #: includes/FontManager.php:438
    645 #: includes/FontManager.php:485
    646 #: includes/FontManager.php:559
     665#: includes/FontManager.php:453
     666#: includes/FontManager.php:505
     667#: includes/FontManager.php:579
    647668msgid "Security check failed."
    648669msgstr ""
    649670
    650 #: includes/FontManager.php:442
     671#: includes/FontManager.php:457
    651672msgid "No file uploaded."
    652673msgstr ""
    653674
    654 #: includes/FontManager.php:450
     675#: includes/FontManager.php:465
    655676msgid "File upload error."
    656677msgstr ""
    657678
    658 #: includes/FontManager.php:461
     679#: includes/FontManager.php:481
    659680msgid "Font family name is required."
    660681msgstr ""
    661682
    662 #: includes/FontManager.php:473
     683#: includes/FontManager.php:493
    663684msgid "Font uploaded successfully!"
    664685msgstr ""
    665686
    666 #: includes/FontManager.php:489
     687#: includes/FontManager.php:509
    667688msgid "Font ID is required."
    668689msgstr ""
    669690
    670 #: includes/FontManager.php:508
     691#: includes/FontManager.php:528
    671692msgid "Font not found."
    672693msgstr ""
    673694
    674 #: includes/FontManager.php:548
     695#: includes/FontManager.php:568
    675696msgid "Font deleted successfully."
    676697msgstr ""
    677698
    678 #: includes/FontManager.php:563
     699#: includes/FontManager.php:583
    679700msgid "No fonts selected."
    680701msgstr ""
    681702
    682 #: includes/FontManager.php:570
     703#: includes/FontManager.php:590
    683704msgid "No valid font IDs provided."
    684705msgstr ""
    685706
    686707#. translators: %d: number of fonts deleted
    687 #: includes/FontManager.php:643
     708#: includes/FontManager.php:663
    688709#, php-format
    689710msgid "%d font deleted successfully."
  • safefonts/trunk/readme.txt

    r3395519 r3416344  
    33Tags: fonts, google fonts, custom fonts, typography, gutenberg
    44Requires at least: 6.2
    5 Tested up to: 6.8
    6 Stable tag: 1.1.9
     5Tested up to: 6.9
     6Stable tag: 1.2.0
    77Requires PHP: 7.4
    88License: GPLv2 or later
     
    223223
    224224== Changelog ==
     225
     226= 1.2.0 =
     227* NEW: Variable font support - upload and use variable fonts with full weight range (e.g., 100-900 in a single file)
     228* NEW: Variable font toggle in upload form - mark fonts as variable and set weight range
     229* NEW: Automatic CSS generation with proper variable font format (font-weight: 100 900; format('woff2-variations'))
     230* NEW: Visual indicator in font list showing variable fonts with weight range badge
     231* IMPROVEMENT: Database schema updated with is_variable, weight_min, weight_max columns
     232* IMPROVEMENT: Font preview uses appropriate weight (400) for variable fonts
    225233
    226234= 1.1.9 =
  • safefonts/trunk/safefonts.php

    r3395519 r3416344  
    44 * Plugin URI: https://safefonts.com
    55 * Description: Secure font management for WordPress with Gutenberg integration and local hosting for GDPR compliance.
    6  * Version: 1.1.9
     6 * Version: 1.2.0
    77 * Requires at least: 6.2
    88 * Requires PHP: 7.4
     
    2121
    2222// Define plugin constants
    23 define('CHRMRTNS_SAFEFONTS_VERSION', '1.1.9');
     23define('CHRMRTNS_SAFEFONTS_VERSION', '1.2.0');
    2424define('CHRMRTNS_SAFEFONTS_PLUGIN_FILE', __FILE__);
    2525define('CHRMRTNS_SAFEFONTS_PLUGIN_DIR', plugin_dir_path(__FILE__));
Note: See TracChangeset for help on using the changeset viewer.