SitePoint Sponsor

User Tag List

Page 2 of 4 FirstFirst 1234 LastLast
Results 26 to 50 of 77
  1. #26
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it's set by the logError() method and returned to the public resize() method. This method then decides weather the error produced needs to be handled and if so, what should be done.

  2. #27
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    time to get practical...

    I have made my first attempt at planning out an OOP site.

    This website is a classifieds directory that will:
    - have classifieds, members and categories all stored in the db

    At this point, I am trying to understand two things:

    1. is my UML diagram (also a first ever attempt) logical, and look like it's going to work? Have I fallen for any common pitfalls or just totally got the concept wrong?

    2. the concept of MVC. From what I understand, I have the model and controller covered in my UML, and the view layer will be the html interacting with my objects.

    I have a feeling i've gone slightly off the rails with the User superclass and subclasses. I'm also unsure about the relationships - for example, a Member can update their own classified. However, does this method belong to Classified or Member?

    .please take a look at the attached file and let me know if i'm on the right track!

    P.S. This diagram is by no means meant to be complete or comprehensive..
    Attached Images Attached Images
    Last edited by wheeler; Oct 31, 2007 at 20:21.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  3. #28
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    first class time

    In addition to the UML attempt, any constructive criticism on my first beginnings of a class attempt would be great!
    PHP Code:
    <?php

    class db
    {
        
    // connection settings
        
    var $conn;
        var 
    $username;
        var 
    $password;
        var 
    $db_name;
        var 
    $localhost;
        var 
    $port;
        
        
    // query builders
        
    var $field;
        var 
    $fields = array();
        var 
    $table;
        var 
    $tables = array();
        var 
    $where;
        var 
    $value;
        var 
    $values = array();
        
        
    // contruct class by establishing connection and selecting database
        
    function __construct($username$password$db_name$host 'localhost'$port 3306)
        {
            
    $conn = @mysql_connect($host ':' $port$username$password);
            if (!
    $conn) exit('<p>' ERROR_TXT '</p>');
            if (!@
    mysql_select_db($db_name$conn)) exit('<p>' ERROR_TXT '</p>');
            
            
    // assign the db details (excluding password) for future reference
            
    $this->username $username;
            
    $this->db_name $db_name;
            
    $this->host $host;
            
    $this->port $port;
            
            
    $this->conn $conn// create the db resource handler
        
    }
        
        
    // handle where conditions - if empty leave clause out completely
        
    function where($value)
        {
            return (empty(
    $value)) ? '' "WHERE $value"
        }
        
        
    // count rows
        
    function countRows($table$where='')
        {
            return 
    mysql_result(mysql_query("SELECT COUNT(*) FROM $table " $this->where($where), $this->conn),0);
        }
        
        
    // select
        
        // update
        
        // delete


    }

    ?>
    One thing that confuses me, are the variables declared at the top for any real reason? I see that I can just as easily create a new variable by $this->variable whenever I like, anywhere in the class. Is it just for quick reference?
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  4. #29
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    // ... etc ...

    // handle where conditions - if empty leave clause out completely
        
    function where($value)
        {
            return (empty(
    $value)) ? '' "WHERE $value"
        }
        
        
    // count rows
        
    function countRows($table$where='')
        {
            return 
    mysql_result(mysql_query("SELECT COUNT(*) FROM $table " $this->where($where), $this->conn),0);
        }
        
        
    // select
        
        // update
        
        // delete

    // ... etc ... 
    That sort of knowledge doesn't belong in this layer but the one above, in your Model for example? The way you have it at the moment, you are treating your data access layer as your Model as well.

    Your data access level shouldn't be concerned with a WHERE clause... Nor should it be aware of how you build your INSERTs, etc.

    You have other more serious issues though,

    PHP Code:
    // ... 
    if (!$conn) exit('<p>' ERROR_TXT '</p>');
            if (!@
    mysql_select_db($db_name$conn)) exit('<p>' ERROR_TXT '</p>');
    // ... etc ... 
    Don't exit at this level; Leave it for your application to make that choice or not, so instead what you'd do is to throw an exception (PHP5 only), so your application knows about the problem.

  5. #30
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    One thing that confuses me, are the variables declared at the top for any real reason? I see that I can just as easily create a new variable by $this->variable whenever I like, anywhere in the class. Is it just for quick reference?
    By declaring the variables on top, you are explicitly stating which variables are available. That makes it easier to get an overview. Also, in PHP5, implicitly created variables will always be public. If you have no reason for declaring a property public, you should reconsider -- protected is much better as a default.
    Another reason is, that while you can implicitly create a variable, you'll get a warning, when reading from an undeclared variable. If the variable is declared in the top of the class, it will de initiated to null (Or what ever, you explicitly set it to).
    On that topic; The use of var is deprecated in PHP5. Use public instead -- It's synonymous.

  6. #31
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hasn't var been un-deprecated? Personally I'd want as many people as possible to use var so that nobody can try to force public/private/protected on us again.

  7. #32
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    error_reportingE_ALL );

    class 
    Something {
            var 
    $variable '';
            
            function 
    __construct() {}
            
        }
        
        
    $something = new Something(); 
    Don't use E_STRICT in your error reporting and you shouldn't have any problem, however no one is forcing anything on you anyways.

    If you have a problem, you can always go back to PHP4.x

  8. #33
    SitePoint Evangelist
    Join Date
    Mar 2006
    Location
    Sweden
    Posts
    451
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    McGruff:
    Just out of curiosity, why don't you like public/private/protected?

  9. #34
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    since var is equivalent to public, I'm not sure what the problem is...

  10. #35
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wysiwyg View Post
    McGruff:
    Just out of curiosity, why don't you like public/private/protected?
    In programming, the great task is to keep things as simple and clear as possible. It's very easy to write difficult, hard-to-follow code but our job is to pare and polish until meaning is accessible in easily digestible chunks. Hence we have things like OOP, (unit) testing and refactoring.

    IMO adding public, private and protected to the language does nothing except create extra clutter. They look important, they sound like they're doing something useful, but it's not so. I cannot think of a real requirement which would make these necessary. There is no unit test which would fail if something private were made public and - with underscores to mark them out - there is no more risk of someone misusing a notionally private method than there is that they might stick their fingers in a power socket.

  11. #36
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    FWIW I don't intend to ever use a PHP4 server (again) and so I would like to take advantage of PHP5 features as much as possible. In that sense I feel somewhat lucky because I don't even want to know about the PHP4 limitations and quirks... I just wish I hadn't already read so many PHP4 OOP specific examples that are abound on the web.
    Quote Originally Posted by Dr Livingston View Post
    That sort of knowledge doesn't belong in this layer but the one above, in your Model for example? The way you have it at the moment, you are treating your data access layer as your Model as well.

    Your data access level shouldn't be concerned with a WHERE clause... Nor should it be aware of how you build your INSERTs, etc.

    You have other more serious issues though,

    PHP Code:
    // ... 
    if (!$conn) exit('<p>' ERROR_TXT '</p>');
            if (!@
    mysql_select_db($db_name$conn)) exit('<p>' ERROR_TXT '</p>');
    // ... etc ... 
    Don't exit at this level; Leave it for your application to make that choice or not, so instead what you'd do is to throw an exception (PHP5 only), so your application knows about the problem.
    I have a bit of an idea about what MVC is and how to use it - and want to use it, but in reality I only have a very vague idea about how to start coding in this style - so I suppose I am guilty of chucking in everything "db" I can think of and perhaps splitting it up into MVC down the line.

    I gather that exceptions are the best way to handle errors in PHP5, and I intend to build an error class soon. I can only imagine how good it must be to control an error and the user experience rather than "good old" exit().

    I try to have display_errors=off and log errors on whenever possible, and I also like to email myself when a major error occurs.

    I have to say that i'm left a bit confused by the disagreement here regarding permissions.

    In Head First Java, the best book i've found to learn OOP concepts (ironic huh), it explains that a instance variable should be protected where it might be misused somewhere in the application. This is somewhat foreign to me, but I guess when you perhaps have API's and the like being developed by other people, JUST IN CASE, you might want to prevent something like
    PHP Code:
    $db = new db;
    echo 
    $db->password
    had $password being private it wouldn't be accessible outside the class. Although my instinct is telling me sites that allow external developers to interact with their classes are smart enough to keep the 3rd party code in a very small cage.

    On a slightly different note, getter and setter methods are used to control output / validate input respectively.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  12. #37
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    50
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    IMO adding public, private and protected to the language does nothing except create extra clutter. They look important, they sound like they're doing something useful, but it's not so. I cannot think of a real requirement which would make these necessary. There is no unit test which would fail if something private were made public and - with underscores to mark them out - there is no more risk of someone misusing a notionally private method than there is that they might stick their fingers in a power socket.
    Perhaps. But the alternative of putting underscores in front of method and property names is:

    (a) possibly more verbose (7 uses of _somePrivateMethod() == same extra characters as 'private' keyword). I say this slightly tongue in cheek, as I know you like succinct code.
    (b) repetitive. If I want to make _somePrivateMethod() public.. I have to rename the method to remove the underscore. Changing my code in lots of places rather than just one if I had used an access keyword.

    I personally think leading underscores are 'orrible, and am glad to be rid of them.

  13. #38
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    368
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    for php "programmers" (especially coming from a procedural background) it may seem redundant

    well thats what you get for having a half arsed OO implementation in the language... and "programmers" for whom ignorance of basic OO principles is bliss...


    like someone said earlier if you don't like OO stick with php4, no one is forcing you to upgrade, same way as no one is stopping people from using C (oh the days!the gray hair due to pointers!) or (gasp!) Assembly

  14. #39
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > interact with their classes are smart enough to keep the 3rd party code in a very
    > small cage.

    Yes. You expose a public API only and little else, if anything. There are various reasons as to why that is, but lets stay on topic

    > ... with underscores to mark them out ...

    I'll be damned if I'm going to use -beep- underscores to represent a non public class property or method. I could tell you where to shove those underscores but I'm not going to

    The language does need them [public, et al] and I'm not going to get into an argument with anyone as to why the language needs them, but if someone doesn't want to use them, they don't have to.

    The language doesn't force you to use them either.

  15. #40
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    In Head First Java, the best book i've found to learn OOP concepts (ironic huh), it explains that a instance variable should be protected where it might be misused somewhere in the application. This is somewhat foreign to me, but I guess when you perhaps have API's and the like being developed by other people, JUST IN CASE, you might want to prevent something like...
    First, I wouldn't recommend accessing properties directly. Encapsulation means wrapping up behaviour and data in a well-defined interface.

    It is of course very important to have a clear concept of what this interface is but it's not necessary to enforce it. There's a lot of java stuff creeping in which just looks anally retentive in php. A quick survey ought to put this to bed:

    1. How many times - not just this week, this month, or this year but in your entire programming career - have readers of this topic mistakenly tried to access a property/method which either was or should have been private/protected ?
    2. How many times have you seen someone else do it?
    3. How many times have you heard people praise php v5's "better" object model?

    The ratio of option 3 to option 2 + option 1 combined is roughly equal to the ratio of stars in the universe to the number of planets harbouring some form of intelligent life. If that level of risk troubles you, by all means use protected and private. My view is that we've got plenty real problems to deal with without inventing imaginary ones. Reflection was nice to get, and this does require some extra information in the code, but I've yet to find a use for ppp.

    This:

    PHP Code:
    /**
     * Gets a parameter from the {@link $_request Request object}.  If the
     * parameter does not exist, NULL will be returned.
     *
     * If the parameter does not exist and $default is set, then
     * $default will be returned instead of NULL.
     *
     * @param string $paramName
     * @param mixed $default
     * @return mixed
     */
    final protected function _getParam($paramName$default null)
    {
        
    $value $this->getRequest()->getParam($paramName);
        if ((
    null == $value) && (null !== $default)) {
            
    $value $default;
        }

        return 
    $value;

    ..is better pared down to this:
    PHP Code:
    function _getRequestParameter($name$default null) {
        
    $value $this->request()->get($parameter_name);
        if ((
    null == $value) && (null !== $default)) {
            
    $value $default;
        }
        return 
    $value;

    The large comment block makes up the bulk of the difference but "final protected" also play their part in adding unnecessary clutter. It's all got to go.

  16. #41
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    368
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    is it me or the first one is a lot easier to read? whitespace does have its uses


    thats another problem with php "developers" manifested in huge amounts of non-reusable spaghetti php code out there (99&#37; ill say, nice exceptions are far apart)

    and thats usingz L33T code is OMGz easier than following basic soft engineering techniques

    tho once again its up to you write what you want, just hope you never find yourself in a team environment

  17. #42
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Encapsulation is an important part of OOP, and it's impossible to enforce without visibility modifiers. Clutter is a legitimate concern, though, which is why making them optional is a good idea. Unfortunately, having data members public by default is not ideal, but there are several obvious
    reasons why that isn't possible in PHP.

  18. #43
    SitePoint Enthusiast
    Join Date
    Oct 2005
    Location
    Lyon, France
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Object-oriented programming references

    Quote Originally Posted by holmescreek View Post
    Well, since you have already worked with PHP in the procedural sense, if your serious about learning OOP, I highly recommend you get a copy of the book Head First Java. It is the best book for learning OOP inside and out.
    I haven't read a Head First book yet but the collection seems very interesting. Some free chapters from the book are available on the Head First Labs :: Head First Java, Second Edition page.

    When I switched from PHP 4 to 5 I also found the Classes and Objects (PHP 5) chapter of the PHP manual very enlightening, the user contributed notes are also very helpful.

    Quote Originally Posted by holmescreek View Post
    All the books that I have found on PHP & OOP, just cover the very basics of OOP and php i.e. syntax, classes, constructors etc.
    It's weird because they're many PHP books for advanced and object-oriented developers. Just try some keywords on Amazon.com for example. They're also dozens of great tutorials available online.

    Don't hesitate to ask if you need some good references.

  19. #44
    SitePoint Enthusiast
    Join Date
    Oct 2005
    Location
    Lyon, France
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Variable & function naming conventions

    Quote Originally Posted by robt View Post
    I personally think leading underscores are 'orrible, and am glad to be rid of them.
    I agree and think prefixing variable and function names with black magic characters is a bad practice . I think some developers add leading underscores because they don't really understand the difference between a variable and a function. A variable is an attribute of the class when a function defines a behavior. A variable stores a value when a function does an action. If you don't know that you will write something like the following code for a user class that maps a user database table :
    Code:
    class user {
    
    /** User login */
    
    private $_login;
    
    /**
    @return
    User login
    */
    
    public function login () {
    ...
    }
    }
    But if you understood the difference between a variable and a function, you would pick
    names like $login for your variable and get_login for your function.
    Last edited by jmmolina; Nov 13, 2007 at 08:21. Reason: Summary added

  20. #45
    SitePoint Enthusiast
    Join Date
    Oct 2005
    Location
    Lyon, France
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Importance of visibility in the OOP paradigm

    Quote Originally Posted by McGruff View Post
    IMO adding public, private and protected to the language does nothing except create extra clutter. They look important, they sound like they're doing something useful, but it's not so. I cannot think of a real requirement which would make these necessary. There is no unit test which would fail if something private were made public and - with underscores to mark them out - there is no more risk of someone misusing a notionally private method than there is that they might stick their fingers in a power socket.
    I have to disagree and consider visibility a very important features, some arguments :
    • Documentation : Specifying the visibility of a variable or function documents the code. Crucial when sharing your code, releasing a library (framework)… For example you could decide to exclude all private functions, it avoids "cluttering" the doc with functions other developers don't need.
    • Public variable : It means you can access or modify it from outside the class. So it makes functions handling the variables pretty useless, get/set for example. As the class developer, you're not in control anymore. Better switch back to PHP 4.
    • Private variable : IMHO all variables should be private. Only public functions should be used to handle them from outside.
    • Public Vs. private function : Encapsulation is not only about grouping functions into a class, it's also about defining the visibility of these functions. Private function, because it's only used by the class. Public, because it should be accessible from "outside" : get/set, validation, other actions…
    • Protected : The next step, when inheritance is considered.
    • Unit testing/Debugging : If someone tries to call a private function, it fails ; If someone tries to modify a public variable, it fails ; ...
    I hope these few arguments convinced you. If the visibility feature was useless, then most OO features would be : final, interface, static… Visibility is part of the OO paradigm, there's not a single OOP language that doesn't support it : C++, Java, Python… More important, I don't think PHP 5 core developers would have wasted so much time implementing it if it was that useless

  21. #46
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Unit testing/Debugging : If someone tries to call a private function, it fails
    Unit tests make assertions about public behaviours not private implementations: you would never call a private method in unit test. If you program test-first, there is no reason ever to write a single visibility keyword. They really don't do anything useful.

    Describing
    the interface for a class is of course very important but once you've done that enforcing it isn't necessary. How often have you tried to stick your fingers in a power socket? You just wouldn't do that, provided you know it is a power socket.

    It's very, very easy to make things complicated. The best programmers are those who can cut through all the clutter and confusion to make things as simple as they can be.

  22. #47
    SitePoint Enthusiast
    Join Date
    May 2007
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you program test-first, there is no reason ever to write a single visibility keyword. They really don't do anything useful.

    do not understand why you think 'test first' will eliminate the need of visibility keyword.

    do you think every one will following your test plan? or are you not going to break you own test plan?

    regards.

  23. #48
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Test-first means you don't write any code except the simplest thing you need to make a failing test pass. The tests don't care about implementation, only behaviour, and access restrictions don't affect the latter. You would never call a private method in a test.

    I used to look after a mountain hut. Part of my job was repairing the roof when the latest storms blew some slates off. For years I happily pattered about on my own with no safety equipment. It was an easy angle, not too high off the ground and I was perfectly at ease up there so much so that I used to do handstands to show off. One day, along came Health & Safety to spoil the fun. I had to use roof ladders and scaffolding, everyone within a ten mile radius had to wear a hard hat, and a nuclear bunker should be prepared, just in case. Now H&S has its place but it often goes way too far. In this case it was voluntary work and nobody was forcing me to do the job without safety equipment. I simply didn't need it.

    The thing is though, I'd meet lots of people who insisted that what I was doing was unsafe. Some of them came along to a work party one day. They had to carry ladders and other equipment for miles over rough tracks to get to the hut and you know what? Everything sat around unused all weekend. On this particular building nobody needed them despite what the rules said. They just got in the way.

  24. #49
    SitePoint Addict Jasper Bekkers's Avatar
    Join Date
    May 2007
    Location
    The Netherlands
    Posts
    282
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff View Post
    1. How many times - not just this week, this month, or this year but in your entire programming career - have readers of this topic mistakenly tried to access a property/method which either was or should have been private/protected ?
    2. How many times have you seen someone else do it?
    3. How many times have you heard people praise php v5's "better" object model?

    The ratio of option 3 to option 2 + option 1 combined is roughly equal to the ratio of stars in the universe to the number of planets harbouring some form of intelligent life. If that level of risk troubles you, by all means use protected and private. My view is that we've got plenty real problems to deal with without inventing imaginary ones. Reflection was nice to get, and this does require some extra information in the code, but I've yet to find a use for ppp.
    It's not the fact that it might, one day happen. It's the fact that it will, one day, inevitably happen because some moron actually did call your private method and is now using the next version of your project and his code breaks because you removed the private method. The thing is, if you make your private methods publicly accessible you know for sure that someone will err.

    I know this should have been solved by the 'moron' by using and Adapter + factory or some other fancy way to abstract your library.

    I have never, ever, mistakenly called private methods. I have however did it on purpose (usually due to constraints in the libraries I work with and in places where inheritance is not possible without losing half a days worth).
    Design patterns: trying to do Smalltalk in Java.
    I blog too, you know.

  25. #50
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jasper Bekkers View Post
    It's the fact that it will, one day, inevitably happen because some moron actually did call your private method and is now using the next version of your project and his code breaks because you removed the private method.
    I'll dispute that, actually. It's not that someone will break it -- It's that you don't know for sure. What we're looking for with automated tests, is certainty. What we're looking for with access modifiers is the same thing. When we know for certain, that noone could possibly be using a given property, we do not need to think twice about renaming it. Not having to think, is a gift.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •