0

I have a small CSS file.

:root {
    --header-bg:
#004d73;
    --header-title-color:
#dbebfa;
}

I am trying to write a script that accepts an input value and overwrites a specific line in the CSS file with the new data. Here is what I have so far.

 $path = 'custom-test.css';
 if (isset($_POST['header-bg'])) {
    $fh = fopen($path,"a+");
    $string = $_POST['header-bg'];
    fwrite($fh,$string,7); // Write information to the file
    fclose($fh); // Close the file
    header('Location: ' . $_SERVER['HTTP_REFERER']);
 }

This is working, except of course it simply appends the data to the end of the file.

I can't figure out if I need to specify what line to overwrite through fopen, fwrite, or if I need the script to open the entire file into an array (which is way beyond my rudimentary PHP skillset).

Again, my skills are quite limited. All tips are welcome, but suggestions that expand upon my existing code would be very helpful.

BTW without going into detail I cannot use a database entry for this.

azjezz
  • 3,827
  • 1
  • 14
  • 35
stevland
  • 119
  • 1
  • 8
  • one way is to read whole file into a string and then make changes to the string and write it back to the file – JoshKisb Jan 20 '18 at 21:59
  • Possible duplicate of [Is there a way to mix CSS and PHP?](https://stackoverflow.com/questions/46001660/is-there-a-way-to-mix-css-and-php) – Andreas Jan 20 '18 at 23:03
  • @Andreas That looks like a similar situation but the person asking is using WordPress and I am not, so it completely changes the requirements. – stevland Jan 20 '18 at 23:21
  • No it doesn't! It's CSS. CSS is CSS no matter if it's PHP, HTML or WordPress "running it" – Andreas Jan 20 '18 at 23:31
  • 1
    @Andreas according to the comments blow, its not, he's trying to change css files in multiple servers for the same website so he made a form to change each one individual, i already answered his question, the answer in the question you link won't help, nether less.js or using a database. in this situation the answer i posted is the one that works best – azjezz Jan 24 '18 at 21:28
  • It doesn't matter how many servers or websites or pages you try to change css values on. str_replace is not a good idea. How do you develop a webpage? Do you make a template html file that you then in php edit with str_replace? Or do you add the values on the fly in a php file that renders the html? Your method is the equivilent the first. You just set a php variable and include the php-css file and the values will be changed. If it's on a different server you include a return and use GET method to add the variables. Str_replace is a really poor solution that will break one day – Andreas Jan 25 '18 at 06:14

2 Answers2

-1

The best and standard way to do that is making a template file and then render that file with parameters.
Take a look at this

First make a template file like this :

:root {
    --header-bg: <?=$this->e($headerBg)?>;
    --header-title-color: <?=$this->e($headerTitleColor)?>;
}

and in your php script:

 $path = './';
 $template = 'custom-test.css';
 $output = 'output-test.css';
 if (isset($_POST['header-bg'])) {
    $params = [
        'headerBg' => $_POST['header-bg'],
        'headerTitleColor' => ''
    ];
    $templates = new League\Plates\Engine($path);
    file_put_content($output, $templates->render($template, $params));
    header('Location: ' . $_SERVER['HTTP_REFERER']);
 }

You must install this package with composer (if you are using composer) :

composer require league/plates

And then import it in your script require 'vendor/autoload.php'
If you don't use composer you must download it and include below files in your script

    "src/Template/match.php",
    "src/Extension/Data/data.php",
    "src/Extension/Path/path.php",
    "src/Extension/RenderContext/func.php",
    "src/Extension/RenderContext/render-context.php",
    "src/Extension/LayoutSections/layout-sections.php",
    "src/Extension/Folders/folders.php",
    "src/Util/util.php"
Rassoul
  • 174
  • 16
  • This is more than likely to be way over the head of the OP asking this question – RiggsFolly Jan 20 '18 at 22:30
  • Hi sr_hosseini, I appreciate you taking the time to compose this detailed explanation. But OMG I can't believe such a simple task would require such an elaborate solution! Also, my script is part of a theme that will be redistributed and run on various servers. Would this solution require that Plates be installed on the server of each end user, or can the required bits be bundled in my package? And I can't find any licensing info... is it safe to assume that it is okay to redistribute? – stevland Jan 20 '18 at 22:32
  • why would a library be needed ? this can be achieved with one php function ! `str_replace`. check my answer above – azjezz Jan 20 '18 at 22:32
  • RiggsFolly you called that one right! I'm happy to wrap my brain around challenge such as this, but I'm surprised that there isn't a simple solution to my problem. – stevland Jan 20 '18 at 22:34
  • dear @stevland I start my answer with best and standard way, my solution is very extendable and maintainable, if your task is so simple then you don't need this this library Of course it's not so complicated, you can easily download library and put theme behind your scripts and import them in your script – Rassoul Jan 20 '18 at 22:40
  • Thank you sr_hosseini. I will have to take a better look at this tomorrow when I have more time. – stevland Jan 20 '18 at 23:19
-1

You can use a template file, and str_replace function and do it like this.

Let's assume you have style.css which contains this :

:root {
    --header-bg: #004d73;
    --header-title-color: #dbebfa;
}

and you have template.style.css which contains this :

:root {
    --header-bg: {{background}};
    --header-title-color: {{color}};
}

Now all you have to do whenever you need to change style.css is replace the values in template.style.css and place the content in style.css

<?php 

$background = $_POST['background'];
$color      = $_POST['color'];
// you may need to check these values before using them

$contents = file_get_contents('template.style.css');
$css = str_replace('{{background}}',$background,$contents);
$css = str_replace('{{color}}',$color,$css);
file_put_contents('style.css',$css);



?>

Update

From your comments, I understand that you are trying to use different theme color for each website you have in different servers, and you don't need php for that.

The simplest method is to change each file manually for each website since you are not going to change them again, but! if you want something more dynamic, still you don't need php, because in that cause you are going to need Less.js: using 2 variables in your less file (you don't need to change CSS, you only need to replace the colors by variable name @varName) and set the variable via less.js for each website.

Update

In your situation I think the first answer is the best, I'll leave my second suggestion in case someone was looking for that answer or found it useful in a different situation.

halfer
  • 19,824
  • 17
  • 99
  • 186
azjezz
  • 3,827
  • 1
  • 14
  • 35
  • Thank you for this. This answer appears to be what I am looking for. But I am struggling to figure out how the input would factor in. Let's say we called the script `change-colors.css`. What would the input look like to call this script? I'll take a stab at it myself: `
    `
    – stevland Jan 20 '18 at 22:46
  • I am developing a theme with backend that has various options for the end user to configure. These options include a color picker (https://www.jquery-az.com/a-bootstrap-jquery-color-picker-with-7-demos/) for the end user to change a few colors. I removed that code from my question to keep things simple. Here is a demo of what I am attempting to do (below _"Create Your Own Theme"_): https://osticketawesome.com/2017/scp/theme.php? – stevland Jan 20 '18 at 22:58
  • so i guess using the first solution that i gave you is easier, even tho you can still use less.js, and that by saving the values in database and giving them to less.js everytime so all your websites can use 1 less file instead of 1 css file for each website – azjezz Jan 20 '18 at 23:05
  • Please note the last line in my original question, "BTW without going into detail I cannot use a database entry for this." I like your first solution... it looks great. But I am struggling to figure out how the **input** would factor into the solution. Let's say we called the script `change-colors.css`. What would the input look like to call this script? I'll take a stab at it myself: `
    `. Does that look like it would work? Thank you!
    – stevland Jan 20 '18 at 23:18
  • Actually, I'm getting ready to go out for the evening. I thought it would be really simple but I was wrong. But I will implement this into my code tomorrow and report back. Thank you, azjezz. – stevland Jan 20 '18 at 23:54
  • 1
    Hi azjezz, This *almost* works. But the outcome looks like this: `:root { --header-bg: {{background}}; --header-title-color: #ffffff; }` If I switch the `$css` lines around in the script so that `$css = str_replace('{{color}}',$color,$contents);` runs first, the outcome looks like this: `:root { --header-bg: #ffffff; --header-title-color: {{color}}; }` – stevland Jan 21 '18 at 20:37
  • 1
    That's brilliant, @azjezz! I have already added a third variable to the script and it worked, so I can see that this is going to be the perfect solution. `str_replace` to the rescue. **Thank you very much for your time**. – stevland Jan 21 '18 at 20:55