Jump to content

gizmola

Administrators
  • Posts

    5,537
  • Joined

  • Last visited

  • Days Won

    107

Everything posted by gizmola

  1. Yes, use services you configure. Make sure that you have passed in any related class objects you need to class constructors, including inside controllers.
  2. Let's go back to this as well. What is the query? Do you understand what you are actually doing here? With each fetch you create a new array element in $table that contains that row. So you end up with $table being an array of the rows of the select statement. There is no reason for you to then be trying to access those using the 0 array element. What you *should* be doing is foreach() through $table, as each element should be the single row, but that brings us back to what VehSelection is. if (!empty($table)) { echo '<ul>'; foreach ($table as $row) { echo "<li>{$row['FirstName']} {$row['LastName']} {$row['VehSelection']}</li>"; } echo '</ul>'; } This is a placeholder for how you ought to be foreach-ing through your result set row by row, and finding out what the heck you actually have in VehSelection. I'm unclear why you aren't already doing something like this, unless you are doing a join of some sort, and your issue is that you have multiple rows for each person, because they have multiple vehicle selections. Looking back on the discussion of database design you had with people like Barand, it was pointed out that logically, a one-to-many from Form -> Vehicle should actually be a Many-to-Many resolution between Form >--< Vehicle. Nomenclature and Semantics are highly valuable for an application. Let's look at what your tables should actually be called, and structured: You: Form Should be: person You: Vehicle Should be person_vehicle Missing: vehicle You stated that you didn't want to restructure your database to use something like what Barand provided in great detail, but then also stated this is just a learning exercise. If it's a learning exercise, then please examine what you have done so far, and look at "Refactoring" things that obfuscate your actual requirements. You have a database structure that isn't relationally sound, and has an intrinsic problem -- you don't have a query that provides you a list of all "available" vehicles, from which a user can choose. Thus you are hard-coding that list, even though your problems began with the fact that you don't have that list, and are trying to create it via an array variable. Here's a simplified version of the tables you should have, and the relationships between them. I omitted a bunch of the other "person" fields you have for simplicity. Hopefully you should now see that: SELECT * FROM vehicle can be used to populate your available checkboxes When saving the checked vehicles for a person, upon save you would: Delete all person_vehicle rows where person_id = {the person.id of the person being updated} Insert a new person_vehicle row for each checkbox that is checked Setting person_id to the person you are updating this for AND vehicle_id = to the appropriate id of the vehicle (1 - 3 Barand had a fully fleshed out version of this with queries and a lot more, in an attempt to merge what you had with a many to many as illustrated here. I know the people who have responded to you previously, and they are exceedingly willing to help someone out, but they tend to exit a discussion when they don't see any forward progress, or work on the part of the person being helped. When someone provides you some code, it's up to you to examine it, try and understand it, and determine if you should adopt it, or if it taught you an important concept. Posting a reply that says: "I tried your code but it didn't work" is a great way to get ignored. Show the code you attempted to use, and the specific errors you got. Don't just say: "It didn't work". Given that you are struggling, I am providing the database definition language SQL if you want to start over and use this structure. You would need to alter the person table, to add the other columns you need, but it might be a good reset at this point, allowing you to get some clarity on what you are doing. Whether you use it or not, I hope there are some things in my most recent replies that will help you find the forest through the trees. # ---------------------------------------------------------------------- # # Add table "person" # # ---------------------------------------------------------------------- # CREATE TABLE `person` ( `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, `firstName` VARCHAR(40), `lastName` VARCHAR(40), `birthDate` DATE, CONSTRAINT `PK_person` PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # ---------------------------------------------------------------------- # # Add table "vehicle" # # ---------------------------------------------------------------------- # CREATE TABLE `vehicle` ( `id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(80) NOT NULL, CONSTRAINT `PK_vehicle` PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # ---------------------------------------------------------------------- # # Add table "person_vehicle" # # ---------------------------------------------------------------------- # CREATE TABLE `person_vehicle` ( `vehicle_id` SMALLINT UNSIGNED NOT NULL, `person_id` INTEGER UNSIGNED NOT NULL, CONSTRAINT `PK_person_vehicle` PRIMARY KEY (`vehicle_id`, `person_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # ---------------------------------------------------------------------- # # Foreign key constraints # # ---------------------------------------------------------------------- # ALTER TABLE `person_vehicle` ADD CONSTRAINT `vehicle_person_vehicle` FOREIGN KEY (`vehicle_id`) REFERENCES `vehicle` (`id`); ALTER TABLE `person_vehicle` ADD CONSTRAINT `person_person_vehicle` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`);
  3. There are numerous posts to you in this thread. I don't know what your code looks like now. People have provided you refactored code snippets covering many things. At this point, we need a sense of what your current code is *now*. Only you know what that is. I can only advise you to simplify your data structures. Also, it might be helpful for you to start using "camelCase" variable naming, which is a standard convention for php coding. There are many other standards that can help your code readability. See https://www.php-fig.org/psr/psr-12/ A perfect example here is your use of $Vehicle. Rename your variable $vehicle. Start all variable names with a lower case letter. If the variable has multiple words, use camelcase ie. $firstName. What are you trying to do here? What is $table, and why are you accessing element 0? Why are you setting $Vehicle[] = this thing, which actually makes $Vehicle into an array, so that the "thing" needs to be accessed via $Vehicle[0]? If $table[0]['VehSelection'] is an array, then just assign $Vehicle = $table[0]["VehSelection"]; Why were you doing this? You don't need to output the same array inside the foreach! All you needed was to see the value of it *before the loop*. It doesn't change. With that noted, what can be seen clearly, is that despite your claims as to what was actually selected, in all cases, there is only ever one value specified. Even when your form checked "Yacht" and "Plane" this array only contains the single "Yacht" value. You need to determine why that is.
  4. What's your contact.php contain at this point?
  5. Facades are aliases defined in the config/app.php. Look in that file for the "aliases" key and you'll find the mappings. With that said, so long as they remain a part of Laravel, if you want to avoid using them (which is a good idea, especially if you want to have sensible unit tests) then just don't use them. There isn't an option to remove them or disable them entirely, and no plan that I know of to do so. They are a convenience option, but you are not forced to, nor required to ever use a facade.
  6. It was missing a closing param in the snippet I provided.
  7. No, because you are adding your security check code to the function or method you are securing. The voter is a place where you can add the code that would do the row level checking you need -- so for example, determining if someone is a project member.
  8. Didn't look through the whole set of code but a quick partial answer is, you can use the php filter_var function for your email validation. That will be better than your regex. if (false === filter_var($email, FILTER_VALIDATE_EMAIL)) { $error_message .= 'The Email Address you entered does not appear to be valid.<br />'; | Another better way to check for input: if (empty(trim($_POST['name'])) || empty(trim($_POST['email'])) || etc ) { died('We are sorry, but there appears to be a problem with the form you submitted.'); } // Code continues This is a more common "positive" guard clause, where if something should cause an exit from processing, check for that and return/exit. The rest of the code is considered "happy path". You are doing a similar thing with your short circuit evaluation, but it requires all the nots, and isn't clear or easily maintainable code. I wouldn't recommend it when you can do something simpler. The obvious improvement is that your code will pass if someone types a simple space into your form.
  9. The Party model is a relational database design pattern. It deals in a robust and fully relational way with how to represent organizations/companies/people and contacts. It's a very specific way of representing those things in a relational database. It also happens to use supertype/subtype for reasons that hopefully will be apparent. Most of what I was talking about was the inherent problem with matching a relational database (which is based on set theory) to an object oriented code base (with interfaces, inheritance and composition) is that they are just entirely different paradigms. This article does an excellent job walking you through the pattern and providing some concrete examples. Just be careful not to conflate the author's use of roles, which is specific to solving the "organizational and team" relationships he wants to represent. While those could be used by a system for security, that's not the point of how they were used in his later examples.
  10. There is no way for any of us to know, because you have a variable ($Vehicle) that isn't initialized anywhere in the code you have shown. We have no idea what is in that array, and apparently you don't either. The way for you to debug that would be to add either print_r($Vehicle) or var_dump($Vehicle) or even die($Vehicle) before the foreach(). This will show you what is in that array. If there is only one checkbox checked it's either: There is only one matching value for the strings in $VehicleArray You have one or more typos so that the values in $Vehicle should be the same, but still don't match.
  11. Just FYI, use empty for all your checks if (empty($_POST["vname0"]) || empty($_POST["vname1"]) || empty($_POST["vemail"]) || empty($_POST['cbox'])) { echo "<h1>Fill All Fields..</h1>"; } However, this is unsophisticated, because a single space entered will pass the test. PHP has validators that can be used with filter_var for things like email that can provide some better hygiene, but at very least you should have a function that trims entry of your text fields. Better: if (empty(trim($_POST["vname0"])) || empty(trim($_POST["vname1"])) || empty(trim($_POST["vemail"])) || empty($_POST['cbox'])) { echo "<h1>Fill All Fields..</h1>"; }
  12. Maybe this doesn't matter to you either, but ftp has absolutely no transit/network level security. There is a longstanding php library (phpseclib) that implements ssh/sftp https://github.com/phpseclib/phpseclib. There are also php extensions that do the same.
  13. As for your 2nd post, there is a lot of material that you are close to, and I am not, which makes it hard for me to really see the forest through the trees. I don't see Roles/ACL being different things. A role is just a convenient way to group up sets of permissions. This makes it simple and easy to give people sets of access. All security schemes tend to boil down to the same thing: For an effective user The system has something to secure. That "thing" needs an identifier, so your code can bridge between the abstract idea of "I want to secure one or more features, functions" and a way of representing those things in your code. Once you start to group those individual things together, a role is simply a parent grouper for a set of permissions By giving a "user" one or more roles, you give them the access appropriate for the role(s) you want them to have There is nothing more or less than that involved. It also points out that roles are more than just a relational concept, but can also have meaning that can short cut granular permissions. In some cases (Symfony 5/6 for example) which you mentioned, there really aren't any granular permissions. You have roles (and again a user can have one or more roles) and you use roles specifically in controllers or methods. The problem of user authentication is intrinsically separated and solved for you, but after a user has been authenticated, you use roles in various ways to write whatever security code you might need. To handle more complicated scenarios like the ones you brought up in your use case, you utilize voters. Custom voters basically let you write the type of complicated access code you might have that involves row level access to things. Their documentation covers scenarios for a blog/forum system like: For a post If I'm the owner I can see it If I have the "admin" role I can see it If It's public anyone can see it Since you already mentioned you are using some portions of symfony, then I would highly recommend looking through the security documentation, and paying special attention to the "Access Control" and discussion of voters and custom voters. It also has an event system, which lets you write hooks for specific security events that can be very useful in dealing with many scenarios (login, logout, user changes password, unsuccessful login attempts etc.) From what I understand of what your requirements are, there isn't anything that can't be done with a higher degree of simplicity and elegance, using the current symfony security scheme. The voters give you a way of handling the things that pure roles can't. The main exercise for you would be to devise a role system that matches what you require. Keep in mind that with this sort of system, you don't want or need something like "read", "write" etc, because you are going to secure those individual routes or class methods. You won't have an abstract token to represent those ideas, and one could argue that trying to use a file system oriented access scheme isn't appropriate to data anyways, so trying to borrow those concepts isn't a good juxtaposition.
  14. From what I interpret from your first reply, here is what I think could be helpful. Relational databases have no concept of inheritance/super/sublcasses. So when you have OOP code that clearly benefits from inheritance, and you are persisting data in a relational database, you are left with 3 choices: Put all the attributes in one table/set of tables even though there will be a handful of attributes that are only relevant for a subtype. The more subtypes you have, the more of these irrelevant attributes, and to compound this, you have to name them all in some way Create a full set of separate table(s) for each type Use the supertype/subtype model There is nothing special in SQL that makes this relational design pattern work. You have a type field in the supertype that indicates which subtype of user this is The relationship between supertype and subtype is 1-1, and thus the subtype has the same primary key as the supertype. This is what is described in the article It is what your model implemented with supertype user, and subytpes (vendor_user, tenant_user) -- typed by user.type value/field You or your ORM need enhanced capabilities beyond the basic one-to-many, many-to-one, etc built ins. You will have in essence some switch statement type logic in your model to handle the subtypes I won't talk about the first 2 options, other than in comparison of some benefits that supertype/subtype can have. A typical requirement would be in storing contact methods for a user. Let's say that you have these contact methods: (phone, email, address) and each of these can exist as multiple types (home, work, mobile, cell) and perhaps you will have a primary designation. A lot more about this problem is covered by an implementation of the "party pattern", by which I refer specifically to a relational structure. Another common requirement would be in relating users together in some way. An example is a hierarchy for Company -> Department -> Employee. Just to simplify, let's say you implement this with a many to many resolution of employee to employee, typically with a "relationshipType" attribute to give context to the values. Just for simplicity, I'll provide these relationship types ("parent of", "spouse of"). Here is where the benefits start to add up. You create these tables and code that lets you add (for an employee) one or more addresses, one or more emails, one or more phone numbers. This code works for all subtypes. You are not duplicating database structure. Your query capabilities are more rich (I have this phone number, who/what is it for?) You query one table for that, vs, if you have tables for each subtype, you have to query the phone number table for each type of employee. You can relate subtypes together again using one relational structure. Following this, and looking at the party pattern, if you step back from employee, and instead make the supertype "entity" where an entity can be any of (a person, a user, a company, a department, a subsidiary, a customer etc.) you get more and more flexibility with your structure, and you still have a way to map between your classes and your relational store. You are still going to use composition and Dependency Injection etc. but you also have a nucleus of tables that support your data persistence requirements and you will be reusing more code and structure. Now in terms of Laravel and Symfony, both ORM's have capabilities that support the supertype/subtype relationship. You may or may not find those facilities useful, or better yet, performant to an acceptable level for you, but they exist and can be used. Yes this is a common pattern used by data architects. It's not found much in garden variety systems, although to be fair those type of systems either don't have complex requirements or the people designing the database aren't experienced with relational database design in general. So to conclude, you have already got a model that uses this pattern, in the case of your user table and subtypes. I assume that the reason you were doing that is that you'd already concluded there were benefits in terms of attaching things like security, which will require relating security to users across types.
  15. In most relational design parlance you call this "subtype" or "subtyping" and refer to the base table as a "supertype". There is a symbol that ERD tools use for this type of relationship, as shown in this article: https://learndatamodeling.com/blog/supertype-and-subtype/ It's the half circle connector they show. Ultimately, it resolves in the same way you resolved it for those tables, but my initial take on what you are doing is: Not sure why tenant_user and vendor_user both have tenant_id and public_id. If there are a bunch more specific attributes only pertinent to the type, then that's where they would go. Right now I don't see the value of the subtype tables at all. You have a bunch of attributes that smell like repeating groups tenant_default_permission vendor_default_permission or tenant_read_permission vendor_read_permission I would return to the question of "Is there an entirely generic ACL structure that can do what i need?" Obviously there is, because people have used generic ACL/security systems for years to support complicated business security concepts. I don't really buy into your "reinvent the wheel" approach. The other thing that is notoriously problematic, is when you have a mixture of static permissions and row level permissions. It means that you can't do a single query without baking that into everything you do. Some years ago I worked for a startup that implemented a full social media system, not unlike facebook, but with more sophisticated access control and permissions of things. The primary insight for me, was that "entity groups" was the mechanism that facilitated and solved a lot of problems. By having groups that related users and organizations to each other, and groups to each other, every piece of content or digital asset could be controlled by belonging to one or more groups. Rather than a single person entity owning a file, a group owned the file, with the original creator being the only member of the "owner" group. Through the creation of different groups with separate "group type" it was always possible to join to content and determine if that should be in a relational result or not. This is just an aside, but it's what I thought about when seeing how you are attempting to solve a few different problems. "Do I have access to this feature or function?" is one problem that ACL is built for. What content should I see based on my place within an organization or department, is another problem. ACL's are not well suited to the 2nd problem, and it looks to me like you are trying to solve both problems with a hybrid/relational structure, and that's jamming a square peg into a round hole if it's too much of one thing or another.
  16. It really depends on your markup. Another solution would be to render the data back into a form, perhaps with the original form elements set as read only. The important thing to note, is that with html, whitespace is not preserved. There is an expectation that markup will be used for formatting, and thus, the idea that a bunch of text with newlines in it, means there are separate paragraphs, is not a concept that exists in html. You can use nl2br as Barand suggested, but it's not that great a solution. It basically just replaces newline characters in the original text with '<br>' characters. A more robust solution would be to use explode in combination with something like trim to derive paragraph blocks and then render them using actual paragraph tags. This gives you much better control of the re-formatting of content. PHP has the explode function which makes this fairly easy to construct. Something along the lines of this could also be a solution: <?php // Original Text in a variable named $content function makeParagraphs($content, $cssClass='') { $content = explode(PHP_EOL, $content); $output = ''; $p = $cssClass ? '<p class="' . $cssClass . '">' : '<p>'; foreach ($content as $paragraph) { $paragraph = trim($paragraph); if (!empty($paragraph)) { $output .= $p . $paragraph . '</p>' . PHP_EOL; } } return $output; } I'm not a huge fan of this type of function for generating html output to be honest, as I try and always separate markup from data, but it gives you an idea of what a function like this could be used for, and problems it can solve for you. Most of my code utilizes a templating system (twig or laravel blade), so I wouldn't have written a function like this, but instead would probably do something more like this, if I was going to only utilize PHP built in templating: function makeParagraphs($content) { return array_filter(explode(PHP_EOL, $content), function($p) { return !empty(trim($p)); }); } ?> <?php foreach(makeParagraphs($content) as $paragraph): ?> <p class="largeText blue"><?= $paragraph ?></p> <?php endforeach ?>
  17. I've not following along too closely on this long and convoluted journey, but the obvious answer is that the derivation of the $chk variable (which is probably erroneous given that you check a variable you create outside a loop that seems to be a related part of the $table array) has absolutely nothing to do with how many checkboxes you have. Your code should output a checkbox for every row in $table. One thing that might be problematic in your markup, is the lack of a space between the value attribute and the word 'checked'. That has nothing to do with why you don't have more checkboxes, but I'd still fix it like this: foreach($table as $id => $arr) { $chk = in_array($id, $Vehicle ?? []) ? ' checked' : ''; echo "<label class='boxstyle'><input type='checkbox' name='vehicle[]' value='$id'$chk>{$arr['VehSelection']}</label><br>\n"; }
  18. We don't really need your entire project, but the answer would be to put it up in a github repo, and provide people a link to that. If there are any credentials in config files, make sure you remove those, if you go that route. With that said, it appears that the problem is concentrated in the email sending portion of things. Getting emails to be sent properly is a non-trivial system administration exercise. Post the class and implementation code that actually sends the email, so we have a better idea of what that is. Are you using an smtp class? Do you have a local/workstation version of the app, and have you tested it locally using a mail trap like mailhog? This is the modern way to work on an app and allows you to ascertain whether your issues are code based, or mail configuration based This is an incredibly common issue, and 98% of the time, the code is correct, but there is some hosting issue or relaying issue preventing email from being sent or handed off.
  19. You were advised to use the code tags before you even posted any code. Now you have made 2 posts and didn't use the code tag button to input your code. Why is that? You said you changed things as advised. What exactly did you change? You commented out two settings that have nothing to do with your problem. Where is this code? Is it in a function or file that is being included? It appears to be code in a function, because you inject a global variable into function scope "global $config". This suggests that you have a function that you are then including or calling somehow, but you only provided this snippet of code, which gives no context to what you are doing. If you "did what was advised" then why are you still using ob_start()??? Do you know what ob_start() does and what it is for? You are wasting everyone's time by providing parts of your code, and not following directions. The error indicates that your code is starting a session before the session_set_cookie_params() call is made. I'm going to guess that this is because you are providing a small piece of your actual code, and the problem won't be found in the 7 lines of code you cherry picked.
  20. Putting the vhosts into separate conf files is an option. It's not a necessity. In your original file i saw this mismatch: DocumentRoot /var/www/foxclone/public_html <Directory /var/www/public_html> You declare the docroot to be /var/www/foxclone/public_html but then your Directory doesn't match that. See the issue? In order for an index.php to be the default file loaded you need a DirectoryIndex index.php Somewhere in the loading of files. One other thing that can cause issues is that the user that apache is running as, needs at very least "rx" permissions to directories, and "r" perms for the files. It doesn't matter if they get those permissions as owner,group or other, although it's best practice not to use "other" perms. Typically your apache process is going to be configured to run as "apache". You can do a quick check from a shell using "ps aux | grep http"
  21. Do you realize that the SSL configuration for radproducts.com is incorrect/broken?
  22. Is that your actual html page? Where is your doctype? Like Requinix stated, the 1st thing you should be doing is using your browser development tools to investigate. In particular the javascript console, network tab, and perhaps the sources, in order to debug your javascript if some obvious problem doesn't jump out at you before you get to that point. Since you rely on ajax, the network tab is where you can actually debug the data loading.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.