how do I split this php file into MVC format? - php

i'm learning to program in OOP MVC,
I have this code for a simple nav menu:
<?php
$directory = "views";
$scannedDirectory = glob("$directory/*.php");
function uppercaseSpace($str) {
$re = '/(?=[A-Z][a-z])(?<!^)|(?=[A-Z])(?<=[a-z])/m';
$subst = ' ';
$result = preg_replace($re, $subst, $str);
return $result;
}
?>
<div id="header2">
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="http://<?php echo $HOST ?>">Home</a>
</li>
<?php foreach ($scannedDirectory as $key => $value) {
$articleName = substr($value,6,-4);
printf('
<li class="nav-item">
<a class="nav-link active" href="?page=%s">%s</a>
</li>
',$articleName, ucfirst(uppercaseSpace($articleName)));
} ?>
</ul>
</nav>
</div> <!-- /header -->
I have a function in the php file so I could make a class navmenu.class and make a method of this function and put the frist 2 lines in the class as a property and the last html part becomes a view right?
but is this class a model or is it a controler?
here is a screenshot of my current file structure:
Is it worth to split this small code into MVC?
This file is now put in the subfolder includes because I am including the nav menu in my script.

Models are for database, View to render html, Controllers to handle a request
Beside that you can have helper classes and core classes
Follow some tutorials on how to create a mvc.
https://www.youtube.com/watch?v=OsCTzGASImQ&list=PLfdtiltiRHWGXVHXX09fxXDi-DqInchFD
https://www.youtube.com/watch?v=rkaLJrYnpOM&list=PLFPkAJFH7I0keB1qpWk5qVVUYdNLTEUs3
I followed the one of Curtis Parham he explained everything very well. After completing his tutorial I modified his framework alot by including composer, twig and changed the routing on how to handle variables and multiple languageses.

Related

PHP Directory Scope

I'm facing a pretty particular problem, basically I'm tryng to create an header in my PHP project. I put my navbar into the "View" folder, and I'm including it with require in each page that I need to use it, I do the same thing with my head, that includes stylesheet and other stuff... Basically the problem is when I try to call the head/the navbar all the relative paths that I used in my 2 files get messed up, since when I call them I'm into another folder. I found three different solutions, and the one who seems to be the best doesn't work.
(I would rather not to use js, if there's any other good solution)
1 Solution that I tried:
I used absolute PATHS, it works, but it doesn't seem right to me, first of all, the file is not going to work in other computers, but only in mine, and it doesn't seem to be a correct approach to the problem. (But then I thought about creating a constant that contains the path of the folder which contains the project, but there's a problem, how do I make that constant to be accessible from every single file in the project? Since when I create it, it's not global.
2 Solution that I tried:
This one is kinda tricky, I basically tried to make a function that generates the entire navbar
<?php
include_once(PATH.'/functions/relpath.php');
function getNavbar($currentPage, $isInsert, $inserimenti){
$navbar = "
<nav class='navbar navbar-expand-md navbar-dark bg-dark fixed-top'>
<div class='container-fluid'>
<a class='navbar-brand' href='#'>Libreria</a>
<button class='navbar-toggler' type='button' data-bs-toggle='collapse' data-bs-target='#navbarsExampleDefault' aria-controls='navbarsExampleDefault' aria-expanded='false' aria-label='Toggle navigation'>
<span class='navbar-toggler-icon'></span>
</button>
<div class='collapse navbar-collapse' id='navbarsExampleDefault'>
<ul class='navbar-nav me-auto mb-2 mb-md-0'> ";
if($isInsert){
//Nel caso in cui ci troviamo in una pagine di inserimento
$pathhome = getRelativePath($_SERVER['PHP_SELF'],PATH.'/index.php');
$pathtabella = getRelativePath($_SERVER['PHP_SELF'],PATH.'/src/tabelle.php');
$navbar.= "
<ul class='navbar-nav me-auto mb-2 mb-md-0'>
<li class='nav-item'>
<a class='nav-link' href='".$pathhome."'>Home</a>
</li>
<li class='nav-item'>
<a class='nav-link' href='".$pathtabella."'>Tabelle</a>
</li>
<a class='nav-link dropdown-toggle active' href='#' id='dropdown01' data-bs-toggle='dropdown' aria-expanded='false'>Inserisci</a>
<ul class='dropdown-menu' aria-labelledby='dropdown01'>
";
foreach($inserimenti as $key => $value){
$relpath = getRelativePath($_SERVER['PHP_SELF'],PATH.'/'.$value);
$navbar.= "
<li><a class='dropdown-item' href='".$relpath."'>".$value."</a></li>
";
}
$navbar.="
</ul>
</li>
</ul>
</div>
</div>
</nav>
";
}else{
//Nel caso in cui ci troviamo in un altra pagina, non di inserimento
$pathhome = getRelativePath($_SERVER['PHP_SELF'],'/progetti/www/Informatica/Marzo2021/ProgettoLibreria/index.php');
echo("PHP SELF: ".$_SERVER['PHP_SELF']."\n PATH ABS: ".PATH.'/index.php'."\n Path Generata da Funzione ".$pathhome);
$pathtabella = getRelativePath($_SERVER['PHP_SELF'],PATH.'/src/tabelle.php');
if($currentPage=="index.php"){
$navbar.= "
<ul class='navbar-nav me-auto mb-2 mb-md-0'>
<li class='nav-item'>
<a class='nav-link active' aria-current='page' href='".$pathhome."'>Home</a>
</li>
<li class='nav-item'>
<a class='nav-link' href='".$pathtabella."'>Tabelle</a>
</li>
<a class='nav-link dropdown-toggle' href='#' id='dropdown01' data-bs-toggle='dropdown' aria-expanded='false'>Inserisci</a>
<ul class='dropdown-menu' aria-labelledby='dropdown01'>
";
}else{
//Dovrebbe quindi essere la tabella
$navbar.= "
<ul class='navbar-nav me-auto mb-2 mb-md-0'>
<li class='nav-item'>
<a class='nav-link' href='".$pathhome."'>Home</a>
</li>
<li class='nav-item'>
<a class='nav-link active' aria-current='page' href='".$pathtabella."'>Tabelle</a>
</li>
<a class='nav-link dropdown-toggle' href='#' id='dropdown01' data-bs-toggle='dropdown' aria-expanded='false'>Inserisci</a>
<ul class='dropdown-menu' aria-labelledby='dropdown01'>
";
}
foreach($inserimenti as $key => $value){
$relpath = getRelativePath($_SERVER['PHP_SELF'],PATH.'/'.$value);
$navbar.= "
<li><a class='dropdown-item' href='".$relpath."'>".$value."</a></li>
";
}
$navbar.="
</ul>
</li>
</ul>
</div>
</div>
</nav>
";
}
return $navbar;
}
?>
In this function, I call another function that I copied from another guy that essentially, outputs the relative path if you give to it the absolute path of your current folder, and the absolute path of the folder that you want to go to. As follows
<?php
function getRelativePath($from, $to)
{
// some compatibility fixes for Windows paths
$from = is_dir($from) ? rtrim($from, '\/') . '/' : $from;
$to = is_dir($to) ? rtrim($to, '\/') . '/' : $to;
$from = str_replace('\\', '/', $from);
$to = str_replace('\\', '/', $to);
$from = explode('/', $from);
$to = explode('/', $to);
$relPath = $to;
foreach($from as $depth => $dir) {
// find first non-matching dir
if($dir === $to[$depth]) {
// ignore this directory
array_shift($relPath);
} else {
// get number of remaining dirs to $from
$remaining = count($from) - $depth;
if($remaining > 1) {
// add traversals up to first matching dir
$padLength = (count($relPath) + $remaining - 1) * -1;
$relPath = array_pad($relPath, $padLength, '..');
break;
} else {
$relPath[0] = './' . $relPath[0];
}
}
}
return implode('/', $relPath);
}
?>
The third solution is the one that I thought to be the best pick, basically I wanted to use the function chdir(), to change the working folder. Essentialy, when I'm into a file that is inside a folder i use the command chdir('..') in order to get into the main folder, and then I could use the relative paths as if I was out of that folder. Put apparently it doesen't work as planned at all, since it still doesn't work!! The relative paths inside the head and the navbar act as if they where into a folder, even if the working folder changed... I'm desperate at this point.
This is the page inside a folder, don't minnd the paths that I wrote, it's for debug, but as you can see, it doesn't load the css that is inside the head
And when I click on a link of the navbar, it acts like I'm into a folder
when I click home, it should go into index.php, but out of the folder, not inside src
The last thing that I send is the folder structure that I have, It's not complete, but at least you can see the interested part. Consider that the navbar and the head is into the view file, while the pages of the website are into src
File structure
If you need more details about the problem, or anything else, ask me. Thanks in advance for the help, if you have other solutions apart from solving the ones that I tried, it would be very nice, I'm sorry if I made some grammar mistakes or anything else, since my spaghetti Italian English could be a bit rusty.

How to embed PHP inside a text file to include later?

I have a simple template created through my ClassPage. The class gets called and reads html code from a text file. Inside the navigation I want to echo a PHP variable but all I am getting is the embedded php commented out on the browser's console?
I'm thinking perhaps the file that gets read isn't being processed by the server and that is why the php isn't being processed? Or I'm missing something really simple?
Heres the code:
ClassPage -> getBody which gets the file called "superNav.txt". The string that gets returned is put together with the needed HTML head tags etc then outputted.
private function getBody() {
$text = "";
if ($this->specialUser) {
$text .= file_get_contents("Template/superNav.txt");
} else {
$text .= file_get_contents("Template/userNav.txt");
}
return $text;
}
This is the Text File:
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar"> <span id="glyph" class="glyphicon glyphicon-th-large"></span></button>
<a class="navbar-brand" href="#"><img alt="brand" id="brandLogo" src="Images/logo.png"></a>
<p id="navbarText" class="navbar-text">Webmin</p>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li>Home</li>
<li>Rota</li>
<li>Rota Admin</li>
<li>User Admin</li>
<li>Archive</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-user"></span><?php echo $user->getName(); ?></li>
<li><span class="glyphicon glyphicon-log-out"></span> Log Out</li>
</ul>
</div>
</div>
</nav>
This is the line that is giving me an issue:
<li><span class="glyphicon glyphicon-user"></span><?php echo $user->getName(); ?></li>
The php does not get shown to screen, the browsers console shows that the code is commented.
Any help is welcomed. Thanks in advance!
For this first get the content from the .txt file and then do something like this :
$name = $user->getName();
$text = file_get_contents("Template/superNav.txt");
$text = str_replace('USERNAME', $name, $message);
$text$message = str_replace('logo_url', $base_url, $message);
and in your .txt file replace the php value with some Constants.
like this
<li><span class="glyphicon glyphicon-user"></span>USERNAME</li>
So here you can see we have replaced the value of USERNAME with dynamic value. Hope it helps!!!
file_get_contents does not execute php, as you have discovered.
Instead you can use output buffering and include.
You will also need to make sure $user is in scope for the getBody method as include inherets its scope from the calling block.
In this example i have used a made up method to illustrate that:
private function getBody()
{
//create local user variable somehow
$user = $this->getUser();
//start buffer
ob_start();
if ($this->specialUser) {
include "Template/superNav.txt";
} else {
include "Template/userNav.txt";
}
//return contents of buffer as string
return ob_get_clean();
}

Get specific output from HTML

<div class="info">
<ul class="links">
</ul>
<h1>Vykúpenie z väznice Shawshank</h1>
<ul class="names">
<li>
<img src="http://img.csfd.cz/assets/images/flags/flag_1.gif" alt="USA" />
<h3>Shawshank Redemption, The</h3>
</li>
<li>
<img src="http://img.csfd.cz/assets/images/flags/flag_34.gif" alt="CZ název" />
<h3>Vykoupení z věznice Shawshank</h3>
</li>
</ul>
Hey guys, this is part of big HTML, what i need is to use HTML SIMPLE DOM PRASER and get this 3 text : "Vyykúpenie z väznice Shawshank", "Shawshank Redemption, The", "Vykoupení z věznice Shawshank" How should i do that?
my try of PHP code:
$html = file_get_html('file.txt');
$ret = $html->find('ul[class="links"]'); //nazov filmu
foreach ($ret as $translate) {
$translate = $translate->innertext;
}
echo "$translate";
There are so many ways to do the translation. You can use contants you can use method. The one of my favourite way is to use Zend Translate check it.
The main aim is to create method which will change some contants depending on language.
class Translator
{
public static $lang = 'en';
public function translate($str){
if(isset($this->data[$str]))
return $this->data[$str];
else return 'no translation';
}
}
$translate->('DO_HOMEWORK');
Language should be stored in session and depends on language it should give proper values. You can get $this->data from CSV files, ini files or get it straightly from the array it doesn't really mater. You can use singleton pattern to Translator class.
I think you want so:
<div class="info">
<ul class="links">
<li><h1>Vykúpenie z väznice Shawshank</h1>
<ul class="names">
<li>
<img src="http://img.csfd.cz/assets/images/flags/flag_1.gif" alt="USA" />
<h3>Shawshank Redemption, The</h3>
</li>
<li>
<img src="http://img.csfd.cz/assets/images/flags/flag_34.gif" alt="CZ název" />
<h3>Vykoupení z věznice Shawshank</h3>
</li>
</ul>
</li>
</ul>
</div>

How do I apply my php code to a bootstrap code?

I am trying to display something from my database on a bootstrap bar and I have no idea how to combine or implement the two. Ive made my bootstrap html's file a .php, was that the correct thing to do? Here's my code (ignore the filler words)
<ul class="nav nav-list well">
<li class="nav-header"></li>
<li class="active">HIT INFO</li>
<li>Linky link</li>
<li class="divider"></li>
<li>ANOTHER HIT INFO</li>
<li>ANOTHER LINKY LINK</li>
<li class="divider"></li>
<li>YET ANOTHER HIT</li>
<li>AAAAAnd another link</li>
</ul>
and this is the php i want to include (the code to making what i want to display is in the file)
<?php include 'one.php'; ?>
where "linky link" is, i want to display this but it didnt seem to work when i put that php right there. Another thing i want to do is when a link from the database gets displayed, it displays as a bootstrap button. i tried and am just not sure how to implement php code in my bootstrap code.
Print " <td>".$row['link'] . "</td></tr> ";
How would i add this bootstrap code to that so when a link from my database gets displayed, it gets displayed as this button
<i class="icon-heart icon-white"></i>Do this HIT!
Your code seems right to me except to your "<td> and <tr>" tag. You're not using it right.
Try this approach
In one.php
<?php
$links = array( 0 => array("url"=>"http://google.com","text"=>"Google") );
?>
In Menu
<?php include('one.php')?>
<ul>
<li>Menu one</li>
<?php foreach( $links as $link){ ?>
<li><a href="<?php print $link['url']?>"><?php print $link['text']?></li>
<?php } ?>
</ul>

How to have the class="selected" depending on what the current page/url is

This is my first post so forgive as I am just new in the world of web development.
Normally, when I try to make a website, I create a file called header.html and footer.html so that I only change data once in all of the pages rather than having multiple same headers on many html files. And include them all in a php file together with the content and the php codes that comes per page.
Now my problem is because I only have 1 header, the css is designed in a way that whatever the current menu/tab is, it will be marked as "selected" so that its obvious to the user what page they are currently in.
My question is how do I solve this problem:
1.) To have the class="selected" depending on what the current page/url is.
<!--Menu Starts-->
<div class="menu">
<div id="smoothmenu" class="ddsmoothmenu">
<ul>
<li>Home</li>
<li>About </li>
<li>Services </li>
<li>Features</li>
<li>Support
<ul>
<li>Support 1</li>
<li>Support 2</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- Menu Ends--!>
Thank You :)
If you're looking for a non-javascript / php approach...
First you need to determine which nav-link should be set as active and then add the selected class. The code would look something like this
HTML within php file
Call a php function inline within the hyperlink <a> markup passing in the links destination request uri
<ul>
<li><a href="index.php" <?=echoSelectedClassIfRequestMatches("index")?>>Home</a></li>
<li><a href="about.php" <?=echoSelectedClassIfRequestMatches("about")?>>About</a> </li>
<li><a href="services.php" <?=echoSelectedClassIfRequestMatches("services")?>>Services</a> </li>
<li><a href="features.php" <?=echoSelectedClassIfRequestMatches("features")?>>Features</a></li>
<li>Support
<ul>
<li><a href="support1.php" <?=echoSelectedClassIfRequestMatches("support1")?>>Support 1</a></li>
<li><a href="support2.php" <?=echoSelectedClassIfRequestMatches("support2")?>>Support 2</a></li>
</ul>
</li>
</ul>
PHP function
The php function simply needs to compare the passed in request uri and if it matches the current page being rendered output the selected class
<?php
function echoSelectedClassIfRequestMatches($requestUri)
{
$current_file_name = basename($_SERVER['REQUEST_URI'], ".php");
if ($current_file_name == $requestUri)
echo 'class="selected"';
}
?>
You could ID each link and use JavaScript/Jquery to add the selected class to the appropriate link.
<!--Menu Starts-->
<div class="menu">
<div id="smoothmenu" class="ddsmoothmenu">
<ul>
<li id="home-page">Home</li>
<li id="about-page">About </li>
<li id="services-page">Services </li>
<li id="features-page">Features</li>
<li id="support-page">Support
<ul>
<li id="support1-page">Support 1</li>
<li id="support2-page">Support 2</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- Menu Ends--!>
On your content page use jQuery to do something like:
$(document).ready(function(){
$("#features-page").addClass("selected");
});
Another method you could use is:
Add class element based on the name of the page
Give each link a separate id then use jQuery on the individual pages.
<li>Home</li>
<li>About </li>
<li>Services </li>
<li>Features</li>
<li>Support
<ul>
<li>Support 1</li>
<li>Support 2</li>
</ul>
</li>
On the services page:
$(document).ready(function(){
$("#services").addClass("selected");
});
Or even better as robertc pointed out in the comments, there is no need to even bother with the id's just make the jquery this:
$(document).ready(function(){
$("[href='services.php']").addClass("selected");
});
One variant on Chris's approach is to output a particular class to identify the page, for example on the body element, and then use fixed classes on the menu items, and a CSS rule that targets them matching. For example, this page:
<DOCTYPE HTML>
<head>
<title>I'm the about page</title>
<style type="text/css">
.about .about,
.index .index,
.services .services,
.features .features {
font-weight: bold;
}
</style>
</head>
<body class="<?php echo basename(__FILE__, ".php"); ?>">
This is a menu:
<ul>
<li>Home</li>
<li>About </li>
<li>Services </li>
<li>Features</li>
</ul>
</body>
...is pretty light on dynamic code, but should achieve the objective; if you save it as "about.php", then the About link will be bold, but if you save it as "services.php", then the Services link will be bold, etc.
If your code structure suits it, you might be able to simply hardcode the page's body class in the page's template file, rather than using any dynamic code for it. This approach effectively gives you a way of moving the "logic" for the menu system out of the menu code, which will always remain the same for every page, and up to a higher level.
As an added bonus, you can now use pure CSS to target other things based on the page you're on. For example, you could turn all the h1 elements on the index.php page red just using more CSS:
.index h1 { color: red; }
You can do it from simple if and PHP page / basename() function..
<!--Menu Starts-->
<div class="menu">
<div id="smoothmenu" class="ddsmoothmenu">
<ul>
<li><a href="index.php" <?php if (basename($_SERVER['PHP_SELF']) == "index.php") { ?> class="selected" <?php } ?>>Home</a></li>
<li><a href="about.php" <?php if (basename($_SERVER['PHP_SELF']) == "about.php") { ?> class="selected" <?php } ?>>About</a> </li>
<li><a href="services.php" <?php if (basename($_SERVER['PHP_SELF']) == "services.php") { ?> class="selected" <?php } ?>>Services</a> </li>
<li><a href="features.php" <?php if (basename($_SERVER['PHP_SELF']) == "features.php") { ?> class="selected" <?php } ?>>Features</a></li>
</ul>
</div>
</div>
Sorry for my bad English, however may be it could help. You can use jQuery for this task. For this you need to match the page url to the anchor of menu and then add class selected to it. for example the jQuery code would be
jQuery('[href='+currentURL+']').addClass('selected');

Categories