I use to look an aggregate as a container of events, and, inside it you can enforce a rule in a consistent manner only if all the data (events) needed to enforce it are present in the aggregate boundary. The aggregate boundaries aren't something predefined, you have to build them in the more comfortable way.
So you are free to change who is the responsible of an event* from an aggregate to another in order to enforce a rule (eg. placeOrder from Order to Customer aggregate), but sometimes that event also contains data needed to enforce another rule in your domain, that will unbecome consistent moving that event away from the original aggregate.
In your case having the placeOrder in an aggregate it's only a part of the data (event) needed to enforce at all your rule, as pointed out from freek, so the way to solve it is put all the operation to enforce the rule inside the aggregate, so you will need also the OrderFulfilled and OrderCancelled event in your aggregate therefore their command methods: fulfillOrder and cancelOrder. I think that removing them from the Order aggregate make the validation of the remains commands of the Order eventual consistent (what if you try to make some modify to a fulfilled order?), so you can think to put the entire order inside the customer aggregate.
Doing this cause other problems, because in this way if all the Orders are in the same aggregate they can't be modified concurrently, is this acceptable? If not you have to break the events and choose which are the less problematic rules and enforce them cross aggregate, using all the techniques to enforce a rule in an eventual consistency fashion (more expensive then a "normal" way inside the aggregate), so the question is "what's the real business impact if that rule gets violated"? :)
Hope it helps,
Cheers
* Who is the first that know that it happened, so that can be fully consistent with that state change